单独添加UI文件
- 问题描述
- 解决方案
- 1. 添加UI文件
- 2. 与对应的界面类进行关联
- 3. 修改UI文件
- 4. 设置界面类读取UI文件
- 总结
问题描述
不知什么原因,Qt Creator并不是很完美很智能。当先写好界面类的头文件和源代码文件后,我们再添加用于可视化界面设计的UI文件时,会出现一些问题。
解决方案
1. 添加UI文件
当使用CMake管理项目时,CMake会读取CMakeLists.txt
文件来确定各种项目设置。需要把MainWindow.ui
包含进项目时,在CMakeLists.txt
中添加入上图的第21行时,才能真正实现。
2. 与对应的界面类进行关联
UI文件MainWindow.ui
对应的类文件为MainWindow.h
和MainWindow.cpp
文件。
// MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_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; // ***
}; //**********
#endif // MAINWINDOW_H
// MainWindow.cpp
#include "MainWindow.h"
#include "./ui_MainWindow.h" //**********
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow) //**********
{
}
MainWindow::~MainWindow()
{
}
用注释标注过的地方即为需要更改的地方。
虽然默认的UI文件是个空的界面,但道理,这个时候应该已经使用UI文件,并可以构建项目了。但若此时真的构建项目,那么会出现下面的编译时错误。
通过错误信息,我们不难看出是我们新包含的./ui_MainWindow.h
头文件不合适。此头文件是由Qt Creator自动创建的,而且也没有自动包含进项目中。在笔者的磁盘上项目的路径是E:\Project\Qt\Demo018
,而这个头文件的位置为E:\Project\Qt\build-Demo018-Desktop_Qt_6_4_0_MinGW_64_bit-Debug\Demo018_autogen\include\ui_MainWindow.h
。如果我们打开这个头文件则如下所示:
/********************************************************************************
** Form generated from reading UI file 'MainWindow.ui'
**
** Created by: Qt User Interface Compiler version 6.4.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_Form
{
public:
void setupUi(QWidget *Form)
{
if (Form->objectName().isEmpty())
Form->setObjectName("Form");
Form->resize(400, 300);
retranslateUi(Form);
QMetaObject::connectSlotsByName(Form);
} // setupUi
void retranslateUi(QWidget *Form)
{
Form->setWindowTitle(QCoreApplication::translate("Form", "Form", nullptr));
} // retranslateUi
};
namespace Ui {
class Form: public Ui_Form {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
不难看出其中的问题:ui_MainWindow.h
头文件中提到的都是Form
,而不是我们在源代码文件MainWindow.cpp
中提到的MainWindow
。在看这个头文件的注释中的这一句Form generated from reading UI file 'MainWindow.ui'
,我们可以推断出错误的根源是在UI文件MainWindow.ui
中。
我们以普通文本编辑器模式打开MainWidnow.ui
文件,如下图所示:
<ui version="4.0" >
<author></author>
<comment></comment>
<exportmacro></exportmacro>
<class>Form</class>
<widget class="QWidget" name="Form" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
</widget>
<pixmapfunction></pixmapfunction>
<connections/>
</ui>
在文件的第4行为<class>Form</class>
,而在第5为<widget class="QWidget" name="Form" >
,这才是我们无法编译的真正原因!!!
3. 修改UI文件
将MainWidnow.ui
文件第4行中的Form
改为我们使用的MainWindow
。如下所示:
<ui version="4.0" >
<author></author>
<comment></comment>
<exportmacro></exportmacro>
<class>MainWindow</class>
<widget class="QWidget" name="MainWindow" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
</widget>
<pixmapfunction></pixmapfunction>
<connections/>
</ui>
此时,就可以成功构建项目了。运行项目后,如下图所示:
细心的同学可以发现,我们设置的窗口的标题是Form
,而不是Demo018
。而在MainWidnow.ui
中我们确实看到了相关的代码:
<property name="windowTitle" >
<string>Form</string>
</property>
以界面编辑器方式打开这个文件后,在属性栏中我们也找到了相关设置:
这说明,界面类并没有从UI文件中读取界面设计。
4. 设置界面类读取UI文件
#include "MainWindow.h"
#include "./ui_MainWindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this); //**********
}
MainWindow::~MainWindow()
{
}
在类MainWindow
的构造函数中添加一行ui->setupUi(this);
。
此时构建项目并运行,如下图所示:
此图说明,至此,我们才真正地将UI文件添加进项目中。
总结
- 添加UI文件;
- 将UI文件与界面类进行关联;
- 修改UI文件中还未自动更正过来地信息;
- 设置界面类读取UI文件。