Featured image of post 【Qt 入门】1 入门

【Qt 入门】1 入门

Qt 基础介绍

|
1529 字
|

Qt 入门

这一系列Qt知识的笔记是根据爱编程的大丙所写,写的很详细,也有对应的视频讲解。

我也根据视频写了对应的练习代码,仓库地址:QtLearn

第一个Qt项目

这里我为了与视频文件名对应,重新创了一个项目,项目名字是 mainwindow

main.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include "mainwindow.h"

#include <QApplication>
#pragma comment(lib, "user32.lib")

int main(int argc, char *argv[])
{
    // 创建应用程序对象, 在一个Qt项目中实例对象有且仅有一个
    // 类的作用: 检测触发的事件, 进行事件循环并处理
    QApplication a(argc, argv);
    // 创建窗口对象
    mainwindow w;
    // 显示窗口
    w.show();
    // 阻塞函数,应用程序对象开始事件循环,保证应用程序不退出
    return a.exec();
}

mainwindow.ui

在Qt中每一个窗口都对应一个可编辑的可视化界面(*.ui), 这个界面对应的是一个xml格式的文件, 一般情况下不需要在xml格式下对这个文件进行编辑, 关于这个文件结构了解即可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>mainwindow</string>
  </property>
  <widget class="QWidget" name="centralwidget"/>
  <widget class="QMenuBar" name="menubar"/>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

mainwindow.h

这个文件是窗口界面对应的类的头文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#pragma once
#include "ui_mainwindow.h"
#include <QMainWindow> // Qt 标准窗口类头文件

class mainwindow : public QMainWindow
{
    Q_OBJECT; // 这个宏是为了能够使用Qt中的信号槽机制

  public:
    mainwindow(QWidget *parent = nullptr);
    ~mainwindow();

  private:
    Ui_mainwindow *ui; // 定义指针指向窗口的 UI 对象
};

mainwindow.cpp

这个文件是窗口界面对应的类的源文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include "mainwindow.h"

mainwindow::mainwindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui_mainwindow) // 基于 mainwindow.ui 创建一个实例对象
{
    // 将 mainwindow.ui 的示例对象和当前类的对象进行关联
    ui->setupUi(this);
}

mainwindow::~mainwindow()
{ 
    delete ui; 
}

Qt 窗口类

基础窗口类

  • 常用的窗口类有3个

    • 在创建Qt窗口的时候, 需要让自己的窗口类继承上述三个窗口类的其中一个
  • QWidget

    • 所有窗口类的基类
    • Qt中的控件(按钮, 输入框, 单选框…)也属于窗口, 基类都是 QWidget
    • 可以内嵌到其他窗口中: 没有边框
    • 可以不内嵌单独显示: 独立的窗口, 有边框
  • QDialog

    • 对话框类, 后边的章节会具体介绍这个窗口
    • 不能内嵌到其他窗口中
  • QMainWindow

    • 有工具栏, 状态栏, 菜单栏, 后边的章节会具体介绍这个窗口不能内嵌到其他窗口中

QWidget

所有窗口的基类

  • 内嵌窗口

    • 依附于某一个大的窗口, 作为了大窗口的一部分
    • 大窗口就是这个内嵌窗口的父窗口
    • 父窗口显示的时候, 内嵌的窗口也就被显示出来了
  • 不内嵌窗口

    • 这类窗口有边框, 有标题栏
    • 需要调用函数才可以显示

代码

由于我们使用的是 cmake 构建项目,即使使用的是Qtcreator,也没法跟视频一样直接添加一个新文件,所以我们只能手动添加。

不过依然可以在 VScode使用Qtconfigure快速构建一个新的项目,命名为widget好了,但是需要做一些修改:

widget.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#pragma once
#include "ui_widget.h"
#include <QWidget>

class widget : public QWidget // 继承 QWidget 而不是 QMainWindow
{ 
    Q_OBJECT

  public:
    widget(QWidget *parent = nullptr);
    ~widget();

  private:
    Ui_widget *ui;
};

widget.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include "widget.h"

widget::widget(QWidget *parent)
    : QWidget(parent), // 初始化列表也要记得修改类型
      ui(new Ui_widget)
{
    ui->setupUi(this);
}

widget::~widget()
{
    delete ui;
}

widget.ui

1
<widget class="QWidget" name="newwindow">

要修改成 QWidget

mainwindow.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "mainwindow.h"
#include "src/newwindow.h"

mainwindow::mainwindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui_mainwindow) // 基于 mainwindow.ui 创建一个实例对象
{
    // 将 mainwindow.ui 的示例对象和当前类的对象进行关联
    ui->setupUi(this);

    // 一般在 qt 的构造函数中进行初始化操作(窗口,数据,...)
    // 显示当前窗口的时候,显示另外一个窗口 NewWindow
#if 0
    // 创建窗口对象,没有给 w 对象指定父对象
    newwindow *w = new newwindow;
    w->show();
#else
    // 创建窗口对象,没有给 w 对象指定父对象
    // newwindow(QWidget* parent = nullptr);
    newwindow *w = new newwindow(this);

#endif
}

mainwindow::~mainwindow()
{
    delete ui;
}

QDialog

对话框窗口类
有模态和非模态两种
不能内嵌

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#if 0
    // 创建对话框窗口
    dialog *dlg = new dialog(this);
    // 非模态
    dlg->show();
#else
    // 创建对话框窗口
    dialog *dlg = new dialog(this);
    // 模态,exec()
    // 阻塞程序运行
    dlg->exec();
#endif

使用模态时,启动程序发现只有两个子窗口,主窗口没显示,这是因为 exec() 函数阻塞程序运行,导致主窗口的构造函数没有运行完。
且这时候我们无法关闭 widget 窗口,只有当我们把dialog窗口关闭时,widget窗口才能被聚焦,且主窗口也会显示。

QMainWindow

具有菜单栏,工具栏,状态栏

工程结构调整

太多窗口类堆在src文件夹下可能难以维护,所以可以看这篇文章调整一下工程结构: 【Qt配置】工程结构调整

使用 Hugo 构建
主题 StackJimmy 设计