|----------------------------------------------|
| 如有懒人想要开发,直接看上传的文件,改名即可。记得看ReadMC.md,不然...... |
今天将由我继续带领大家研究控件。控件有多种排布方式,只不过有不同特点与优缺点。
一、QT Designer
QT Designer是全QT最简单的控件设计方式。首先打开开始菜单,找到Q。选择QT文件夹里的这个Designer 6.11.1 (MSVC 2022 64-bit) 快捷方式,千万不能选成其他的例如 (MINGW 64-bit) 。只有他才能生成Visual Studio QT能打开的ui文件。

打开后,你应该可以看到以下界面(我的电脑是深色系的,可能看不清)

这个界面可以 设计不同的界面,我们目前能用的就只有Main Window。选择后在右侧自定义大小或者其他内容后就可以创建了。如下图,我们就进入了QT Designer的主界面。其中的功能分布我会稍后讲解。

1.控件区
在这里,你可以拖拽不同的控件到屏幕上,支持所有原生控件,其他的插件里的控件无法在这里编辑,QT7Beta版解决了这个问题,但是QT7极不稳定,且仅支持Visual Studio 2025 Preview版,不支持已发布的2022版,所以对于插件控件,建议使用另外两种方式放置。设置完属性后,就不需要在程序里设置了。详见运行时控件。
2.功能区
在这里,你可以选择复制粘贴,还有QT独有的名称非属性粘贴。
3.主操作区
在这里,我们会对拖入的空间进行摆放,也可以预览成型的窗口。设置完属性后,就不需要在程序里设置了。详见运行时控件。
4.对象显示器
这里会将所有已经放置的对象显示出来,并且还会显示嵌套关系。对于复杂的大项目或者刚刚接触QT的新手,这都非常有用。
5.属性编辑器
毫不夸张的说,这是QT Designer最大的优势。他不仅可以显示控件的位置,还会把所有控件的属性显示的明明白白,不需要在程序界面一个一个摸索。还可以预览设置后的效果。在设置->首选项->语言里还可以显示中文,对新手非常友好。不过出于专业考虑,我们就用中文吧(可爱元宝会帮我翻译的^v^)
我们先选择Push Button(QPushButton),将其拖入中间的主操作区(提示:我以后说控件和消息框以及布局等等都会用"QT显示名(C++类名)"的方式表达控件),接着看向属性编辑器。接下来,我将告诉你们QT Designer的最大缺点。
看向Geometry项,你会发现他共有4项,分别为。(其中Px指的是X坐标,Py是Y坐标,Sx是长度,那么Sy还用想吗?)其中Px和Py就是绝对坐标。这意味着假如窗口大小可以调整,那么最大化的窗口就是设计窗口大小下的右下角拖拉版,缩小窗口的话有的控件就无法显示。(说实话这点没有AppInventer好用,起码他作为Android图形窗口编辑器,还是支持百分比的,这个设置起来超级麻烦,而且我也没研究到哪,所以现在这就是最大的缺陷)
接着保存为.ui文件,保证和你的项目在一个文件夹下。
编译时加载(推荐)
先修改CMake.txt,注意注释行。
objectivec
cmake_minimum_required(VERSION 3.16)
list(APPEND CMAKE_PREFIX_PATH "D:/Qt/6.11.1/msvc2022_64/lib/cmake")
project(HelloQt CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
add_executable(MyQtApp WIN32
main.cpp
mainwindow.ui # 把 .ui 文件加到源文件列表里
)
target_link_libraries(HelloQt Qt6::Core Qt6::Gui Qt6::Widgets)
if(WIN32)
set(WINDEPLOYQT_EXE "D:/Qt/6.11.1/msvc2022_64/bin/windeployqt.exe")
add_custom_command(TARGET HelloQt POST_BUILD
COMMAND "${WINDEPLOYQT_EXE}" "$<TARGET_FILE:HelloQt>"
COMMENT "Deploying Qt dependencies..."
VERBATIM
)
endif()
你可以拷贝,也可以直接复制这行代码,修改刚刚的注释行:
objectivec
add_executable(MyQtApp WIN32 main.cpp mainwindow.ui)
接下来在主程序中引用头文件后面(或者在项目名.h里)添加:
cpp
#include "ui_mainwindow.h" // uic 自动生成的头文件
class MainWindow : public QWidget{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
private:
Ui::MainWindow *ui; // 指向 uic 生成的界面类的指针
};
// 以下内容必须放在CPP文件中
MainWindow::MainWindow(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this); // 加载 .ui 中定义的所有控件
setWindowTitle("<窗口标题>");
resize(400, 300);
// 通过 ui->objectName 访问 Designer 中拖的控件,暂时超纲了
connect(ui->confirmButton, &QPushButton::clicked, [this]() {
QString text = ui->inputField->text();
if (text.isEmpty()) {
QMessageBox::information(this, "提示", "请输入内容");
} else {
ui->resultLabel->setText("你输入的是:" + text);
}
});
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
运行时加载(方便)
直接修改main函数:
cpp
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// 加载 .ui 文件
QFile uiFile("mainwindow.ui");
if (!uiFile.open(QFile::ReadOnly)) {
return -1;
}
QUiLoader loader;
QWidget *window = loader.load(&uiFile);
uiFile.close();
if (!window) {
return -1;
}
window->setWindowTitle("运行时加载 UI");
window->resize(400, 300);
// 通过 findChild 获取控件(参数是 Designer 中设置的 objectName)
QPushButton *button = window->findChild<QPushButton*>("confirmButton");
QLabel *label = window->findChild<QLabel*>("resultLabel");
QLineEdit *input = window->findChild<QLineEdit*>("inputField");
// ui事件处理,依旧超纲
if (button && label && input) {
QObject::connect(button, &QPushButton::clicked, [label, input]() {
QString text = input->text();
if (text.isEmpty()) {
label->setText("请输入内容");
} else {
label->setText("你输入的是:" + text);
}
});
}
window->show();
return app.exec();
}
上述的事件处理器均为超纲内容,后面才讲。
二、XML模式
XML实际上就是手动编辑.ui文件,更麻烦,但更自由,我不推荐,希望有哪位肝帝能全程用XML而不用QT Designer。
先看刚刚弄好的.ui文件的内容:
XML
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>762</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>330</x>
<y>330</y>
<width>83</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>33</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
可以看到有QMainWindow、QWidget、QMenuBar和QStatusBar。
QMainWindow
其实就是窗口的属性
QWidget
多数控件都是他的子类,包括我们刚刚放的QPushButton也在里面作为子项,也写了事件处理器的回调。
QMenuBar
就是我们打开Windows自带的画图上面显示的文件、编辑、窗口等内容。可以使用热键。我们以后会学习。
QStatusBar
就是最上方显示的窗口图标、窗口名、最小化、最大化和关闭。提示:Linux和Mac OS的位置可能不一样。
三、运行时控件(代码里设置)
由于字数原因,今天我们不讲解控件,只讲解原理。他就是创建了一个控件,但是这个空间不能显示,需要win变量关联他(或者是布局),由于学会这个不仅需要C++基本基础,还需要高级指针等内容。所以下篇我会讲解相关的C++语法。
今天真实收获满满的一天,希望大家都吸收了这些知识,我们下次再见!!