QT学习教程与实战三:控件与QT Designer

|----------------------------------------------|
| 如有懒人想要开发,直接看上传的文件,改名即可。记得看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++语法。

今天真实收获满满的一天,希望大家都吸收了这些知识,我们下次再见!!

相关推荐
WangWei_CM2 小时前
Active Setup:按用户首次登录执行的组件初始化
windows
code_pgf2 小时前
C/C++ 中 `typedef` 关键字详解
c语言·c++
会周易的程序员2 小时前
js-shm: 高性能 Node.js 共享内存模块
开发语言·javascript·c++·node.js·共享内存·shm
2023自学中3 小时前
imx6ull 开发板 贪吃蛇, C++11 SDL2 无硬件GPU优化版
linux·c++
anscos3 小时前
为CUDA 代码引入静态分析
c++·工业软件·功能检测
众少成多积小致巨3 小时前
C++ 规范参考(中)
c++
小保CPP3 小时前
OpenCV C++基于AI模型的场景文本识别(OCR)
c++·人工智能·opencv·计算机视觉·ocr
shylyly_3 小时前
C++中的类型转换
开发语言·c++·匿名对象·隐式类型转换·拷贝优化
jinyishu_3 小时前
哈希表原理与开放定址法C++实现
c++·哈希算法·散列表
小龙报4 小时前
【优选算法】1. 水果成蓝 2.找到字符串中所有字母的异位词
java·c语言·数据结构·数据库·c++·redis·算法