Welcome: Hunan Intelligent Applications Tecgnology CO.,ltd.-HNIAT.com
Language: Chinese ∷  English

Basic knowledge

Principle and implementation of Ui namespace and setupUi function in Qt

Selecting GUI applications with the latest QtCreator produces a project with the following files

 

The following is a brief analysis of the functions of each part.

 

The .pro file is a file used by qmake, not the focus of this article [but it's actually very simple], so I won't go into details here.

So, let's start with main,

 

#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
 

 

very simple

QApplication a(argc, argv) and a.exec() can be understood as the architecture loaded with Qt, and programs running Qt must have this part, so I won't say more.

It calls a MainWindow and shows it, and analyzes it in detail.

Below is the content in mainwindow.h

 

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui/QMainWindow>
namespace UI
{
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
 

 

The namespace Ui at the beginning may be a bit confusing, because Qt separates the UI-related classes, but the class names are the same, and the namespace distinction is disabled [but for the current use, I feel that this is not very good, I will explain why later.]

 

The namespace Ui is declared because the MainWindow in Ui is to be called. This MainWindow is not another MainWindow, and the *ui pointer involved later will call it!

 

I will not say about Q_OBJECT. The classes related to signal and slot in Qt must be declared like this.

 

Carefully see the structure, the destructor is nothing, there is only such a *ui! But now if you run it, it will only generate a form.

 

Let's look at the constructor and destructor, which is actually mainwindow.c

 

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
 

 

During construction, a new MainWindow in the Ui domain is created on the heap, and setupUi is called. The destructor is just to delete it, which is still very simple!

 

As mentioned earlier, Qt separates the ui very well. The .ui file in the previous figure is the layout file used by QtDesigner!

 

Now run, it will generate ui_mainwindow.h, which will involve the real layout function, that is, the MainWindow in the Ui domain. Let's take a look at it in detail,

 

#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QHeaderView>
#include <QtGui/QMainWindow>
#include <QtGui/QMenuBar>
#include <QtGui/QStatusBar>
#include <QtGui/QToolBar>
#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QMenuBar *menuBar;
QToolBar *mainToolBar;
QWidget *centralWidget;
QStatusBar *statusBar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(600, 400);
menuBar = new QMenuBar(MainWindow);
menuBar->setObjectName(QString::fromUtf8("menuBar"));
MainWindow->setMenuBar(menuBar);
mainToolBar = new QToolBar(MainWindow);
mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
MainWindow->addToolBar(mainToolBar);
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
MainWindow->setCentralWidget(centralWidget);
statusBar = new QStatusBar(MainWindow);
statusBar->setObjectName(QString::fromUtf8("statusBar"));
MainWindow->setStatusBar(statusBar);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0, QApplication::UnicodeUTF8));
Q_UNUSED(MainWindow);
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
 

Whoosh, it's a lot more at once, but it's actually quite easy. Ui_MainWindow declares several components, I won't say it specifically, because there is nothing to say, it implements the setupUi function, which is the setupUi called in the previous MainWindow.

But it should be noted that the QMetaObject::connectSlotsByName function will automatically connect the signal and slot of the corresponding name, but it should be noted that it is connected to the incoming MainWindow and its subcomponents [not subclasses], pay attention to the front ui->setupUi(this ), which is the MainWindow in the non-ui domain, so if you want to declare the signal and slot, you still need to declare it in the MainWindow of the non-ui domain, and then interact with the GUI in the form of ui->xxx! This is easily demonstrated if we drag and drop a button in QtDesiner and click go to slot.

retranslateUi will name the components in the ui, and I will not say more here.

Finally, look at this code

namespace Ui {
  
class MainWindow: public Ui_MainWindow {};
  
} // namespace Ui
 

The *ui of MainWindow in the previous non-Ui domain points to the MainWindow in the Ui domain, and the MainWindow in the Ui domain inherits Ui_MainWindow, and the interior is impoverished! 【A little convoluted】

Come to a picture, and then review it



 

Finally, there are two points to explain. Personally, I feel that it is a bug of QtCreator.

One is that if you customize the control yourself and want to load it in the built-in designer, it is not feasible to use mingw under win, because the designer in the sdk suite is compiled with Microsoft's compiler, and of course there is a more convenient solution. The solution is to download the source code of qtcreator, compile it again with the existing creator, and then overwrite it.

The second is also mentioned above. The two MainWindow with the same name are only distinguished by the Ui domain. Although it feels beautiful in design, there will be some problems when debugging. In short, debugging in the creator cannot be recognized correctly. domain, see the figure below for details


 

Like the picture above, this should actually point to the MainWindow in the non-Ui domain [this actually points to the MainWindow, it doesn't know which domain's MainWindow, and if it expands further down, it points to the Ui domain incorrectly], but the debugging The data area points to the MainWindow in the Ui domain. Of course, there is no solution. You can manually change the name of the MainWindow in the Ui domain to get the correct debugging information, but it is a little troublesome to do so, and run qmake again. It may be revised later.

 

The bug you mentioned later seems to be fixed in QT5

http://blog.csdn.net/songjinshi/article/details/7333119

Category: Qt-Layout

CONTACT US

Contact: Manager Xu

Phone: 13907330718

Tel: 0731-22222718

Email: hniatcom@163.com

Add: Room 603, 6th Floor, Shifting Room, No. 2, Orbit Zhigu, No. 79 Liancheng Road, Shifeng District, Zhuzhou City, Hunan Province

Scan the qr codeClose
the qr code