Qt creator 生成的GUI程序运作机理探秘

来源:互联网 发布:分享淘宝头条能挣钱吗 编辑:程序博客网 时间:2024/05/21 22:41

        首先用Qt Creator生成一个空白的基于QMainwindow的GUI程序,得到5个文件,一个.pro文件,一个.ui文件,一个.h文件,两个.cpp文件,其中一个是main.cpp。
        

         .pro文件描述了工程包含的文件结构,没什么可以说的,下面分析一下其他几个文件。
        main.cpp文件如下:
#include <QtGui/QApplication>#include "mainwindow.h"int main(int argc, char *argv[]){    QApplication a(argc, argv);    MainWindow w;    w.show();    return a.exec();}
        一个标准的main文件,引入了一个自定义的类MainWindow,并生成了一个实例w。下面进入mianwindow.h文件,看一下MainWindow的定义过程:
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>namespace Ui {    class MainWindow;}class MainWindow : public QMainWindow{    Q_OBJECTpublic:    explicit MainWindow(QWidget *parent = 0);    ~MainWindow();private:    Ui::MainWindow *ui;};#endif // MAINWINDOW_H
        从这里可以看到自定义类MainWindow公有派生自QMainWindow类,且定义了一个使用了explicit修饰的构造函数和一个析构函数,关键字explicit可以保证构造函数不会被隐式调用,除此以外还定义了一个私有的Ui::MainWindow型指针变量ui。注意,这里的UI::MainWindow类型和类定义的MainWindow并不相同,而是使用的前面声明的Ui空间中的MainWindow类,而这个类就是真正通过Qt Designer生成的.ui文件经过代码转换重新生成的类,作用是生成实际窗口。
       下面我们再来看一下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;}

        cpp文件中包含了构造函数和析构函数的实现,这里包含了新的头文件"ui_mainwindow.h",而这个头文件由ui_ 开头,其实是由Qt Designer自动生成的,在Qt Designer中打开.ui文件,Form->View Code命令,就可以看到.ui文件自动转换生成的c++代码,当然如果编译工程后,在编译目录中也可以找到这些代码:

#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_NAMESPACEclass 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(400, 300);        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));    } // retranslateUi};namespace Ui {    class MainWindow: public Ui_MainWindow {};} // namespace UiQT_END_NAMESPACE#endif // UI_MAINWINDOW_H
        可以看到,这里定义了一个Ui_MainWindow的类和有这个类公有派生出来的新类MainWindow,并且为这个新生的MainWindow类定义了命名空间Ui,至此,我们得到了一个比较完整的派生关系表:

 
        这样看来,4个类的关系就很清楚了,Qt语言编写者显得有些恶趣味,制作了几个名字差不多的类,让初学者很容易一头雾水。明了了类的层次关系,我们就有了很多结论——
        1.用户类可以改名,事实上很多从不用界面编辑器创建代码的Qt牛人主窗口类大多选用个性化的名字。
        2.界面编辑器生成界面可见代码量很小,原因是将一众QAction,QMenu,QtoolBar等杂鱼全都用一个私有指针ui封装了起来,要付出的代价就是使用这些被封装的对象时,在前面必须加上ui->的指向标志,貌似并不麻烦。
        3.定义ui指针,可以直接使用Ui_MainWindow,不过在头文件开始处Ui空间的声明要换成#include"ui_mainwindow.h"的形式,
        4.自动生成的mainwindow.h并没有包含ui_mainwindow.h文件,这个文件实际在mainwindow.cpp中被包含,这样设计的目的是为了降低头文件的代码量,可能在大型工程中能够加快编译速度。


原创粉丝点击