user3025332
user3025332

Reputation: 83

C++ How does Qt work?

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

Answers (1)

RobbieE
RobbieE

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

Related Questions