美文网首页
Qt程序的基本结构

Qt程序的基本结构

作者: downdemo | 来源:发表于2018-09-14 16:37 被阅读303次
  • 以VS的空项目为例,新建一个Qt界面程序
空项目自带的文件
  • 为了更深入地认识,这里不使用默认的空窗口,而是自己写一个窗口
添加一个窗口
  • 添加窗口后将生成一个Widget.ui文件,双击就会打开Designer界面,可在界面中拖动控件编辑程序。这里使用Designer添加一个按钮
添加一个按钮
  • 编译Widget.ui文件,生成ui_Widget.h文件,将其导入到项目中
  • ui_Widget.h文件内容如下
/********************************************************************************
** Form generated from reading UI file 'Widget.ui'
**
** Created by: Qt User Interface Compiler version 5.10.1
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Form
{
public:
    QPushButton *pushButton;

    void setupUi(QWidget *Form)
    {
        if (Form->objectName().isEmpty())
            Form->setObjectName(QStringLiteral("Form"));
        Form->resize(400, 300);
        pushButton = new QPushButton(Form);
        pushButton->setObjectName(QStringLiteral("pushButton"));
        pushButton->setGeometry(QRect(100, 80, 75, 23));

        retranslateUi(Form);

        QMetaObject::connectSlotsByName(Form);
    } // setupUi

    void retranslateUi(QWidget *Form)
    {
        Form->setWindowTitle(QApplication::translate("Form", "Form", nullptr));
        pushButton->setText(QApplication::translate("Form", "PushButton", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Form: public Ui_Form {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H
  • 可以发现在Designer界面添加的按钮,实际上会在setupUi函数中生成对应的代码,所以setupUi可以简单理解为构造函数,它的作用就是把Designer界面内容显示出来。如果把按钮从Designer中删掉,重新编译后,ui_Widget.h内容如下(QPushButton相关代码被删除)
/********************************************************************************
** Form generated from reading UI file 'Widget.ui'
**
** Created by: Qt User Interface Compiler version 5.10.1
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Form
{
public:

    void setupUi(QWidget *Form)
    {
        if (Form->objectName().isEmpty())
            Form->setObjectName(QStringLiteral("Form"));
        Form->resize(400, 300);

        retranslateUi(Form);

        QMetaObject::connectSlotsByName(Form);
    } // setupUi

    void retranslateUi(QWidget *Form)
    {
        Form->setWindowTitle(QApplication::translate("Form", "Form", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Form: public Ui_Form {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H
  • 这里还需要解释的是namespace Ui,其中的class Form其实就是一个继承了Ui_Form的空类。之后将在Widget.h中声明一个指向Ui::Form的指针,用于操控界面。虽然Form是空类,但它继承了Ui_Form,因此Ui_Form中的所有非私有的内容都能用
  • 随后添加一个头文件Widget.h和源文件Widget.cpp(也可以取其他文件名)
添加头文件和源文件之后的项目结构
  • Widget.h内容如下,先做一个namespace的前置声明,private作用域中添加了一个指向Ui::Form类型的指针ui,可以将其理解为指向界面的指针。在源文件中用它可以直接访问界面中的控件,如访问之前添加过的按钮,只需要ui->pushButton。这样做的好处就是不需要包含ui_Widget.h,降低了耦合性(每次Designer界面改变都会重新编译ui_Widget.h),这种分离接口和实现的手法类似于PImpl
#ifndef WIDGET_H
#define WIDGET_H

#include <QMainWindow> // 窗口派生自QMainWindow

namespace Ui { // 前置声明命名空间
    class Form;
}

class widget : public QMainWindow // 继承
{
    Q_OBJECT // 必须添加的宏

public:
    explicit widget(QWidget *parent = 0); // 必须指定显式构造
    ~widget();

private:
    Ui::Form *ui; // 指向Designer界面的指针
};

#endif // WIDGET_H
  • 这里要解释的是Q_OBJECT,它的本质是一个宏
#define Q_OBJECT \
public: \
    Q_OBJECT_CHECK \
    QT_WARNING_PUSH \
    Q_OBJECT_NO_OVERRIDE_WARNING \
    static const QMetaObject staticMetaObject; \
    virtual const QMetaObject *metaObject() const; \
    virtual void *qt_metacast(const char *); \
    virtual int qt_metacall(QMetaObject::Call, int, void **); \
    QT_TR_FUNCTIONS \
private: \
    Q_OBJECT_NO_ATTRIBUTES_WARNING \
    Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
    QT_WARNING_POP \
    struct QPrivateSignal {}; \
    QT_ANNOTATE_CLASS(qt_qobject, "")
  • QObject类是Qt所有类的基类,只要是QObject的子类就要在第一行代码写上Q_OBJECT,它提供信号槽机制、国际化机制以及 Qt 提供的不基于 C++ RTTI 的反射能力,但即使不使用这些操作最好也添加Q_OBJECT以防出错。这个宏由moc(可以将其理解为一种预处理器) 做特殊处理,moc会处理标记了Q_OBJECT的头文件(不处理cpp文件),生成moc_前缀的文件
  • Widget.cpp内容如下,这里调用setupUi相当于ui_Widget.h中的构造函数,用于显示Widget.ui界面的内容
#include "Widget.h"
#include "ui_Widget.h"

widget::widget(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Form)
{
    ui->setupUi(this);
}

widget::~widget()
{
    delete ui;
}
  • 利用ui指针也可以访问控件来修改内容,比如在Designer界面中的按钮控件pushButton文本默认是PushButton,在Widget.cpp中使用ui->pushButton->setText即可修改按钮文本,类似也可以自己添加其他控件
#include "Widget.h"
#include "ui_Widget.h"

widget::widget(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Form)
{
    ui->setupUi(this);
    ui->pushButton->setText("new");
}

widget::~widget()
{
    delete ui;
}
  • 也可以不通过ui指针,也就是不利用Desiner界面,直接用代码生成,比如直接在Widget.cpp的构造函数中添加控件
widget::widget(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Form)
{
    ui->setupUi(this);

    QVBoxLayout* layout = new QVBoxLayout(this);
    QPushButton* btn = new QPushButton(this);
    btn->setText("test");
    layout->addWidget(btn);

    QWidget *centralWidget = new QWidget();
    centralWidget->setLayout(layout);
    setCentralWidget(centralWidget);
}
  • 随后在main.cpp中包含Widget.h头文件,直接声明一个对象再调用show()就显示了我们自己写的窗口
#include "QtGuiApplication1.h"
#include "Widget.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    // QtGuiApplication1 w;
    widget w;
    w.show();
    return a.exec();
}

相关文章

  • Qt程序的基本结构

    以VS的空项目为例,新建一个Qt界面程序 为了更深入地认识,这里不使用默认的空窗口,而是自己写一个窗口 添加窗口后...

  • 第四章:程序的控制结构

    程序的流程图 a程序的基本结构 程序由三种基本结构组成: 顺序结构 分支结构 循环结构 这些基本结构都有一个入口和...

  • Python学习笔记(四)

    第四章 程序的控制结构 程序的基本结构 程序由三种基本结构组成: 顺序结构 分支结构 循环结构这些基本结构都有一个...

  • 4. Python 分支、循环与异常处理

    程序的基本结构 程序有3种基本结构组成:顺序结构、分支结构和循环结构 顺序结构:程序按照线性顺序依次执行 分支结构...

  • 信号和槽(signal and slot)

    快速创建qt工程 当我们熟悉基本的从空项目创建qt应用程序后,以后我们可以直接从模板中创建一个qt工程 注意,本节...

  • <> 复习整理 第四章

    第4章 程序的控制结构 4.1 程序的基本结构 /程序由三种结构组成:顺序结构,分支结构和循环结构. 4.1.1 ...

  • JinLou-C++day03

    程序流程结构 C/C++⽀持最基本的三种程序运⾏结构:顺序结构、选择结构、循环结构 顺序结构:程序按顺序执⾏,不发...

  • Linux下打包发布Qt应用程序

    Linux下打包发布Qt应用程序 Linux下打包发布Qt应用程序 Linux下使用Qt进行开发的程序,如果想要在...

  • 小程序主体理解

    小程序的4种文件类型 小程序的基本结构 小程序良好的组件式结构

  • Qt开发系列2——使用Qt开发一个简单程序

    这里介绍开发Qt程序的一些方法和步骤。主要内容:一、手工编写QT程序二、使用Qt Designer进行程序界面设计...

网友评论

      本文标题:Qt程序的基本结构

      本文链接:https://www.haomeiwen.com/subject/bzwogftx.html