Replacing widget with custom template widget in Qt Creator Designer - c++

In Qt Creator UI Designer it is possible to replace a widget with its subclass. I have created a template subclass of QComboBox:
template <typename T>
class MappedComboBox : public QComboBox
{
// ...
};
And I have successfully managed to replace QComboBox with MappedComboBox<int>. However replacing QComboBox widget with, for instance, MappedComboBox<QSerialPort::BaudRate> fails due to dependency errors while building like
'QSerialPort' was not declared in this scope.
Of course one way to get rid of them is to include QSerialPort in mappedcombobox.h however that's not a very elegant way. Can I somehow tell Qt Designer to include additional files while generating UI?

In the UI designer there is no way to include an extra header. A better workaround is to include it in the cpp file of the designer class before including the generated header. That's better than including in the MappedComboBox which has no business with that header.
In mainwindow.cpp:
#include "mainwindow.h"
#include <QSerialPort>
#include "ui_mainwindow.h"

Related

How to add QwtPlot as a base class in Qt promote?

I am using Qt creator 4.2.1. I have installed Qwt lib successfully and been able to drag and drop QwtPlot widget to my form. I have an custom class Plot:public QwtPlot. I wish I can add QwtPlot to my form and then perform a widget promote to Plot.
However, when I try to do so, the promote dialog box does not show QwtPlot as a base class that I can choose. If I select QWidget as the base class and then specify "Plot" and "plot.h" as my promote class and header file, I got build errors complaining redefine of "class Plot". I do have the plot.h in my project already and it seems uic creates another "class Plot" for me. Hence, the compiler complains my plot.h has an redefined class.
How to resolve this problem? Thanks!
Place a widget from toolbox and use promote and make sure your class structure is like following sample.
#ifndef PLOT_H
#define PLOT_H
#include <QObject>
#include <qwt_plot.h>
class Plot : public QwtPlot
{
Q_OBJECT
public:
explicit Plot(QWidget *parent = nullptr);
signals:
public slots:
};
#endif // PLOT_H

How to break up Qt code into separate parts?

So I am currently writing a Qt app, but am fairly new to it and am unsure of how certain things should be designed. As I add more and more code, my MainWindow.cpp is getting large and unruly. I am curious of what is the proper way to separate my code up in to smaller files. Each of the components that I wish to move to a separate file is making changes to the UI. What I am currently doing is literally just creating a new .cpp file, and then including my MainWindow and also the MainWindow ui. Here is an example of a function that I placed in its own file.
#include <QDebug>
#include <QString>
#include <QPalette>
#include "master_main_window.h"
#include "ui_master_main_window.h"
#include "cmd_net.h"
#include "cmd.h"
/*
* Send a command/data packet to the host
*/
void MasterMainWindow::sendCommand() {
// Disable some GUI components
ui->con_btn_cmd_disc->setEnabled(false);
ui->con_btn_cmd_rec->setEnabled(false);
ui->cmd_edit->setEnabled(false);
ui->cmd_btn_send->setEnabled(false);
// Send the packet through the open socket
sendCmdPacket(ui->cmd_edit->text().toLocal8Bit().data(), cmdSocket);
// Enable the socket notifier
cmdSockNotifier->setEnabled(true);
qDebug() << "Command sent:"
<< (ui->cmd_edit->text().toLocal8Bit().data())
<< "\nSent Packet";
}
As you can see, I have simply included the "master_main_window.h" and "ui_master_main_window.h" which gives me access to all of the different functions/variables/ui available in the MainWindow class. I am curious if I am doing this the proper way, or if there is a better method to achieve my goal of separating the functions into separate files.
If I'm getting what you're asking correctly, since you're working with pointers here you can simply write other classes in different files and pass your variables in ui to them.
For example, let's say you're ui has these variables in it:
QWidget * leftWidget;
QWidget * centerWidget;
QWidget * rightWidget;
You can write classes who inherit QWidget and give these variables to them, like this:
class leftWidgetClass : public QWidget
{
//your code here
}
and so on...
And then in the constructor of your MainWindow you can do this:
leftWidget = new leftWidgetClass();
rightWidget = new rightWidgetClass();
centerWidget = new centerWidgetClass();
The proper way would be to not using ui namespace and mainwindow methods outside of mainwindow class. You should sublass QWidget or any other classes, which functionality you want to extend, create all the functionality you need (like doImportantStuff()) and include this new class header ( let's call it myWidget) in mainwindow.h. Then you can create those myWidget's in mainwindow, add them to ui (ether through disigner, add QWidget, click promote to , select your class, or by adding to layout manually) and use all of their signals and functionality, that you've created, like:
connect(ui->doWorkButtot(),SIGNAL(clicked()), myWidget, SLOT(doImportantStuff()));`
again, changes to ui you can do via signals and slots mechanism; In myWidget when you feel, you have to change ui somehow, emit a signal and catch it in mainwindow with connect. Example:
myWidget.h:
...
signals:
void needUiChange();
....
public slots:
myWidget::doImportantStuff(){
....
emit needUiChange();
// you can emit signals with params also:
// emit setToolTipText(QString("from signal));
...
and in mainwindow catch signal with connect:
connect(myWidget, SIGNAL(needUiChange(),this,SLOT(updateUI());
// actually you can connect directly to let's say `pushButton`'s slot `hide()`

Settings errors in Qt project with OpenGL

In the project that use OpenGL in Qt I use in protected method initializeGL() the statement
qglClearColor(qtPurple.dark());
Follows errors occurs in the building project:
‘qtPurple’ was not declared in this scope
‘qglClearColor’ was not declared in this scope
The files that is included is:
#include <QtGui>
#include <QtOpenGL>
#include <QtGui/QColor>
In the .pro file is present
QT += core gui, opengl
Where are the mistakes that cause these errors?
QGLClearColor is a non-static member of QGLWidget. So first you must include <QGLWidget> to your widget header file and inherit your widget from QGLWidget. Then you will be able to call it in methods of your widget. You get was not declared in this scope error because qglClearColor is in QGLWidget scope.
Alternatively, you can call it as regular method of your widget object.
And what is qtPurple? It seems that it's not a part of Qt.
Add #include <QtOpenGL/QGLWidget> in your head file.And Your class should inherit QGLWidget.
It seems that you have not declared the variable qtPurple,so check
your head file,if not exist,just declare it[like this:QColor qtPurple;].

Qt doesn't display child widget

How can i access ui files of children of a class. Lets say MainWindow class has twoa child dialog. I want to access LINEEDIT of dialog so that i can take text from there. Similarly how can i access ui files of parent inside child class in QT. Note: I havn't inherited any thing from Parent class.
I have writen the following code, in order to display a dialog but it won't show!
void MainWindow::displaydialog()
{
ItemDialog dialog= new ItemDialog(this);
dialog->show(); // it is not displaying the dialog
}
and how can i access the ui widgets like check whether ListWidget item has been selected or not.
Here is the code of itemdialog,
#include "itemdialog.h"
#include "ui_itemdialog.h"
#include "mainwindow.h"
ItemDialog::ItemDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::ItemDialog)
{
ui->setupUi(this);
setWindowTitle("Status Dialog");
setFixedSize(QWidget::sizeHint());
}
ItemDialog::~ItemDialog()
{
delete ui;
}
void ItemDialog::on_pushButton_clicked()
{
MainWindow obj;
obj.okbuttonclicked(ui->lineEdit->text());
}
Please review an example such as this: http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
It explains how to use the ui files that you generate from Qt Designer. You shouldn't really think of them as "ui files" in the sense of accessing them on the widgets in your class. The idea is that you include them, and then use their setupUi() function to apply them to your given class. At that point, everything you created in qt designer, and that is in that ui file, is now a member of your class. They can be accessed via the naming you used in qt designer.
As for why your dialog isn't showing...I don't know because you only included 3 lines of code as an example. Theoretically it should show if Mydialog was properly set up. You could just try changing it to a QDialog to make sure you didn't do anything wrong with your custom class.
It depends what you want that dialog for. Either it's a modal dialog - some kind of a information display or retrival that blocks the function of your program until user reacts, or it's somekind of toolbox or similar, in which case you probably should not use QDialog.
If a modal dialog with a line edits and/or additional features is what you want, you should read up on QDialog in the doc. See the exec() function. Basic usage would go like this:
void MainWindow::displaydialog()
{
ItemDialog *dialog = new ItemDialog();
if (dialog->exec() == someApropriateReturnStatus)
{
QString somevalue = dialog->someValue();
int dialog->someOtherValue();
//do something with the value
}
delete dialog;
}
The point is that the ItemDialog class handles the UI internally and implements the getter functions accordingly, you should not (in most typical cases) access it's UI from outside.
If a simple line edit is all you want, you'd be better off using one of the standard dialogs already implemented in Qt, have a look at the Standard Dialogs Example

How to call created .ui design form in Qt with button.clicked() event?

I'm very new in Qt and I would like to ask how to call the created .ui designer form to be connected with the PushButton in MainWindow.
What I've done:
1. Created a new .ui design form (Forms.right click -> Add New -> Qt Designer Form) to the current project.
2. Designed an about dialog in the .ui form created.
3. Make a slot PushButton.clicked() in the MainWindow.
For all who have done programming in Qt, please help me solve this problem to connect the PushButton with the .ui form, so the PushButton can call/show the form created in the .ui.
Thanks for your attention.
Using .ui files is explained in Qt's documentation:
http://doc.qt.io/archives/qt-4.7/designer-using-a-ui-file.html
Summary:
The easiest way to handle an .ui file is to run it through uic (the User Interface Compiler) at compile time. This is done automatically if the .ui file is included in your project (.pro) file. ("Add New" probably has done this automatically in your case.) Then you only need to include the generated C++ header file in your source file. Its name should be something like "ui_nameoftheoriginaluifile.hpp". Of course, after that you need to instantiate the form defined in the .hpp file.
Edited to add:
There are several issues with your code, starting from its readability. I don't know if you have used an object-oriented language before, but a very basic rule in C++ is to begin class names with capital letters to make them easier to distinguish from objects and other variables. So the class names should be "About", "Parent", etc.
The compilation error is caused by using "about" instead of the name of the class actually used in the "ui_about.hpp" file - "MainWindow". (Which is determined by the name of the form you have used in the .ui file.)
If you are using Qt Creator: hold down the Ctrl key and click on the name of the file "ui_about.h" in the include directive. This will open it for inspection. Try to figure out how it works.
You also haven't defined the opDialog() function as a member of the "parent" class in "parent.cpp", which causes another compile-time error.
You also shouldn't be using a QMainWindow for an about dialog. QMainWindow is supposed to be the main window of your application - there shouldn't be any more instances of it.
So, about.h:
namespace Ui {
class MainWindow;
}
class about : public QMainWindow {
Q_OBJECT
public:
about(QWidget *parent = 0);
~about();
protected:
void changeEvent(QEvent *e);
private:
Ui::MainWindow *ui;
};
And the beginning of about.cpp:
#include "about.h"
#include "ui_about.h"
about::about(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}