欢迎光临~湖南智能应用科技有限公司-hniat.com
语言选择: 中文版 ∷  英文版

基础知识

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
关闭
用手机扫描二维码关闭
二维码