Reputation: 83
I'm trying to figure out how to access components from Qt Designer form which I have inside my c++ project, there is no compile errors but runtime errors occur.
How does "main" function work and a.exec? Should I execute my code before a.exec() or create a new thread to do so?
QWidget *pWindow;
QPushButton *lpPushButton;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtProject w;
w.show();
pWindow = QApplication::activeWindow();
lpPushButton = pWindow->findChild<QPushButton*>("pushButton_2");;
lpPushButton->setText("test");
return a.exec();
}
Both pWindow and lpPushButton are NULL
The above code doesn't work since I have no idea where I can call setText from. A little ELI5 explanation on how Qt works would be great, thank you.
Upvotes: 1
Views: 2087
Reputation: 4350
When you create a form using QtDesigner, it stores the details in a xxx.ui
file which must be added to your project. This is compiled in a precompile step into a ui_xxx.h
file which you must include in your source files.
This header file contains a generated class with all the widget and layout code inside and puts it in a namespace called Ui
.
You have two options to use this generated class: you can derive from it, or you can have it as a member. You then need to call the class' setupUi()
function to execute the creation/layout code.
The advantage of deriving from the generated class is that all child widgets are publicly available.
For example, if you create a simple widget form in QtDesigner and call it MyWidget
, with a single QPushButton
called pushbutton_2
, you can create the form using the following code:
#include "ui_mywidget.h"
#include <qwidget.h>
#include <qapplication.h>
class Widget : public QWidget, public Ui::MyWidget{
public:
Widget(QWidget *parent = 0):QWidget(parent){
setupUi(this);
}
};
int main(int argc, char **argv){
QApplication app(argc, argv);
Widget w;
w.show();
w.pushbutton_2->setText("test");
return app.exec();
}
The reason you can access pushbutton_2
directly is because it's a public member of Ui::MyWidget
from which you derived Widget
. It is also created when you call setupUi()
from the constructor of Widget
.
EDIT:
Another way of creating a form is to have your generated class a member class in your display widget. You will still need to call setupUi()
though, in order to create all the form's child widgets and perform layout tasks.
class Widget : public QWidget{
public:
Widget(QWidget *parent = 0):QWidget(parent){
ui.setupUi(this);
}
private:
Ui::MyWidget ui;
};
In this case, you will not be able to access the child widgets directly. The reason is that, although structurely, they might be children of Widget
, the pointer variables that hold the memory addresses to them, and were used to create them, belong to ui
, which is a private member of Widget
.
You can still access them, however, using the findChild<>()
function, if you know their object names.
Upvotes: 1