新建一个QMainWindow工程
有三个文件 h cpp ui
其中对于ui文件,QT有解释工具uic 将ui文件转为h文件,在编译时会执行uic
我点击编译,然后打开uic生成的文件
"ui_mainwindow.h"
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QWidget *centralwidget;
QMenuBar *menubar;
QStatusBar *statusbar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(800, 600);
centralwidget = new QWidget(MainWindow);
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
MainWindow->setCentralWidget(centralwidget);
menubar = new QMenuBar(MainWindow);
menubar->setObjectName(QString::fromUtf8("menubar"));
MainWindow->setMenuBar(menubar);
statusbar = new QStatusBar(MainWindow);
statusbar->setObjectName(QString::fromUtf8("statusbar"));
MainWindow->setStatusBar(statusbar);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MainWindow", nullptr));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
1 public 声明了一些UI控件
2 setup函数是将控件传递给参数
3 最下面一个命名空间是最令人迷惑和不解的,在UI命名空间内定义了 和我们自己定义的类的 同名的类,它继承自上面自动生成的UI类
-------------------------------------------------------------------------------------------------
问了问chatgtp:
为什么继承:
- 封装UI元素:
Ui_MainWindow
类通常包含了与界面相关的UI元素的声明和初始化。这些元素包括窗口、按钮、文本框等。将MainWindow
类继承自Ui_MainWindow
允许MainWindow
类访问和操作这些UI元素,因为它继承了Ui_MainWindow
类中的成员。 - 符合Qt的设计模式: Qt框架中采用了一种基于组合的设计模式,其中
Ui_MainWindow
类表示了MainWindow的界面部分(View),而MainWindow
类通常用于包含应用程序的逻辑和控制器部分。通过继承关系,MainWindow
类可以轻松地访问界面元素,并且符合了这种设计模式。 - 更易于操作和维护: 继承关系使得在
MainWindow
类中可以添加自定义的方法和事件处理程序,以响应用户交互或执行其他与界面相关的任务。这使得界面操作更加方便,代码更具可维护性。
为什么使用命名空间:
- 封装UI元素: Qt中的UI元素(如窗口、按钮、文本框等)通常是使用Qt Designer或Qt Creator等工具生成的。将这些UI元素放置在
namespace Ui
中可以将它们封装在一个命名空间内,从而避免与应用程序的其他部分发生命名冲突。这是一种良好的软件工程实践,有助于维护代码的清晰性。 - 避免全局变量: 通过将UI元素封装在
namespace Ui
中,可以避免将UI元素暴露为全局变量,从而减少了可能导致的全局命名冲突和不必要的全局变量。 - 清晰的UI访问方式: 使用
namespace Ui
使得访问UI元素的方式更加清晰。例如,要访问MainWindow的某个UI元素,您可以使用Ui::MainWindow
来限定命名空间,然后访问具体的元素。 - 符合Qt的设计模式: Qt框架鼓励使用一种基于组合的设计模式,其中UI元素(视图)和应用程序逻辑(控制器)分开。使用
namespace Ui
有助于符合这种设计模式,将UI元素的声明和初始化与应用程序逻辑分离开。
-------------------------------------------------------------------------------------------------------------------------
我们打开h文件
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
1. namespace Ui { class MainWindow; }这句话是为了 下面的定义 Ui::MainWindow *ui 而写的,因为没有include "ui_mainwindow.h" 所以把ui_mainwindow.h中的最下面的命名空间那几行代码重新抄了一遍
2 . 我们自行定义的类MainWindow继承自QWidget
我们再看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;
}
1 ui =new Ui::MainWindow; UI::MainWindow 就是自动生成的ui_mainwindow.h中的这个类,虽然多了一层继承关系 namespace Ui { class MainWindow: public Ui_MainWindow {}; }
2 通过执行 ui->setupUi(this); 将自动生成的UI控件类传递给我们自行定义的类MainWindow中,因此MainWindow继承自QWidget,所以自动生成的控件类就和我们自行定义的MainWindow类耦合起来了