Ui名字空间及setupUi()原理解读
1.前言
用最新的QtCreator选择GUI的应用会产生含有如下文件的工程:
1.1 *.pro文件
QT += core gui //使用Qt的Core和Gui模块。QT将自己的库函数分为多个模块,最常用的是QtCore, QtGui。如果使用 //其他的模块的话可以添加其他模块。常用的有QtNetwork,QtOpenGl, QtSql, QtXml. QtWebkit等等 //如果应用程序使用到该模块,需要添加相应的模块。
TARGET = test0831 //生成的应用程序或者链接库的名字
TEMPLATE = app //工程的类型,一般有app和lib,app就是直接的应用程序,lib就是动态链接库,一般用于插件开发
SOURCES += main.cpp\ //就是*.cpp文件列表,多行显示的时候用\
mainwindow.cpp
HEADERS += mainwindow.h //*.h文件列表
FORMS += mainwindow.ui //UI文件的列表,UI文件是Qt特有的界面设计文件
1.2 mainwindow.h文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_
该文件是类的声明文件。符合主流的OOP的面向接口编程的思想。一般将类的定义都在此文件中。一般不再该文件中定义操作。注意继承自Qt的内部文件,一定在类中加上Q_OBJECT的宏定义,Qt会使用MOC将改文件重新编译成moc_mainwindow.cpp文件,这个才是原始的C++类的文件。所以Qt内置的类文件都不是原生态的C++类,需要Qt编译器再处理,所以继承子Qt的类一定要添加该宏定义,否则编译一定不通过。
Ui::MainWindow* ui 变量声明是mainwindow.ui生成的布局类Ui::MainWindow.
1.3 mainwindow.cpp文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
是类的定义文件。注意#include “ui_mainwindow.h". 工程中的mainwindow.ui文件会被UIC编译生成ui_mainwindow.h。文件中的类就是Ui::MainWindow。MainWindow中的ui就是用布局类初始化。之后在构造函数需要使用ui->setupUI(this);就可以将Ui::MainWindow中的布局应用到本地的MainWindow。
1.4 mainwindow.ui布局文件
其中的内容是xml格式的标记文件,这点和主流的UI设计相符,现在主流的UI设计如Andriod和WP都是使用XML文件做UI设计,可以使用Qt SDK自带的Qt Designer进行可视化设计,设计好的*.ui文件可以直接在工程文件中使用。主要.pro中FORMS中添加对应的文件名,*.cpp文件中加入#include "ui_*.h"文件名。初始化之后就可以将布局建立在自己的类中。
2.一定要理解ui_mainwindow.h
这个UI的头文件是原始项目编译后生成的,这个里面会涉及到真正布局用的函数,也就是那个Ui域中的MainWindow。看下面代码:
#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
吼吼,一下子多了不少,但其实还是很容易的。Ui_MainWindow声明了几个构件,具体我就不说了,因为也没啥可说的,它实现了setupUi函数,也就是前面那个MainWindow中调用的setupUi。
但是要说明的是QMetaObject::connectSlotsByName()函数会自动连接相应名称的信号与槽,但要注意它连接的是传入的MainWindow及其子构件【不是子类】,注意前边ui->setupUi(this)中传入的this,也就是非ui域中的MainWindow,所以如果要声明signal和slot时还是要在非ui域的MainWindow中来声明,然后通过ui->xxx的形式来与GUI产生交互!如果我们在QtDesiner中拖放一个按钮然后点击go to slot就很容易印证这一点。
retranslateUi则会为ui中的构件命名,具体也不在此多说。
我们需要着重讨论的是,下面代码。并思考,编译完Designer后,产生一个布局可以理解,怎么还多了一个命名空间?
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
前面非Ui域中的MainWindow的*ui( UI::MainWindow *ui)指向的是Ui域中的MainWindow,而Ui域中的MainWindow( 上边那行代码)继承Ui_MainWindow
3.到底什么是UI?
ui通常是用Qt 设计师设计出来的界面文件的后缀。通常情况下ui是一个指向这个界面类的指针。“ui->”一般就是用来访问这个界面类里面的控件。
例如我们的ui文件里有一个叫OkButton的QPushButton。我们可以这样来访问这个按钮ui->OkButton。setupUi(this)是由.ui文件生成的类的构造函数,这个函数的作用是对界面进行初始化,
它按照我们在Qt设计器里设计的样子把窗体画出来,把我们在Qt设计器里面定义的信号和槽建立起来。也可以说,setupUi 是我们画界面和写程序之间的桥梁。
————————————————
版权声明:本文为CSDN博主「沈子恒」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/shenziheng1/article/details/60765502