Qt

1. 概述

Qt 是一个功能极其强大的客户端开发软件,而且可以支持跨平台开发和多语言开发。

跨平台: 支持 Windows Linux Android iOS 操作系统,同时支持各种硬件平台,包括 ARM 体系架构。

多语言: 支持 C++ ,Java, Python

可以用于开发: 操作系统,应用程序(WPS, 极品飞车,高铁中控系统),塞班,Android,iOS中的应用程序,ARM 端可执行程序。

2. 第一个 Qt 案例

2.1 新建项目
02-项目类型选择 03-Qt项目路径和名称要求 04-默认qmake选择 05-Qt当前项目相关信息 06-语言默认选择 07-Kit Selection 08-项目最终确认
2.2 Qt 代码解释

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
// class MainWindow; 前置声明
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

/*
 在 Qt 中,所有 Qt 默认的类型都是 Q 开头。
 当前 QMainWindow 是 Qt 中标准界面组件基类 / Base Class

 自定义主界面/主组件 MainWindow
 */
class MainWindow : public QMainWindow
{
    // Qt 项目中的标记宏,如果类中声明当前宏存在,Qt 会自动识别
    // 当前类满足 Qt 需求,同时支持 Qt 相关操作。
    Q_OBJECT

public:
    /*
     * 当前 MainWindow 构造函数,所需参数为 QWidget 类型的指针 parent
     * 默认值参数为 null,当前组件默认没有父组件要求。
     *
     * 在 Qt 中存在组件树,存在父组件,子组件。
     */
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    /*
     * UI 界面成员变量,根据代码阅读
     * UI 是命名空间,在命名空间中有且只有一个类 MainWindow 当前文件
     * 对应的类
     *
     * UI 界面 Design 是 Qt 完成页面实现的一种方式,后续使用 UI 方式设置
     * 当前界面内容,所有的组件都在当前 ui 对象中。而 UI 对象实际上就是
     * 当前类 MainWindow 对象
     */
    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 构造函数实现
     *
     * ui->setupUi(this); 设置当前 UI 界面属于哪一个对象,当前操作
     * 是将 UI 界面归于 MainWindow 实例化对象。
     */
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    /*
     * delete ui;
     * ui ==> Ui::MainWindow *ui
     * 也就是当前实例化 MainWindow 对象。
     *
     * new 实现操作在 ui(new Ui::MainWindow) 构造函数
     * 对当前 MainWindow 进行内存空间申请和实例化操作。
     */
    delete ui;
}

main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    /*
     * QApplication Qt 整个项目对象,也可以认为是 Qt 上下文对象。
     * 主要包括整个项目的所有配置信息,相关资源文件。
     * 【项目大管家】
     */
    QApplication a(argc, argv);

    // 实例化 MainWindow 对象
    MainWindow w;
    // QMainWindow 包含的 show 函数,用于展示当前组件。
    w.show();

    /*
     * QApplication 项目大管家执行当前 Qt 项目
     */
    return a.exec();
}
2.3 Qt 组件树【重点】

Qt 中为了方便管理内存,利用组件树方式对整个项目中使用的动态内存和组件占用资源进行统一管理。

案例代码解释

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    /*
     * 当前 MainWindow 构造函数实现
     *
     * ui->setupUi(this); 设置当前 UI 界面属于哪一个对象,当前操作
     * 是将 UI 界面归于 MainWindow 实例化对象。
     */
    ui->setupUi(this);

    QPushButton *bt1 = new QPushButton;

    /*
     * 设置当前 QPushButton 文本信息
     * void setText(const QString &text);
     * 所需参数为 QString ,QString 可以直接认为是 C++ 字符串
     */
    bt1->setText("这里是一个按钮!");

    /*
     * void setParent(QWidget *parent);
     * 设置当前组件的父类,所需参数是 QWidget 指针,在 Qt 中
     * 任何一个组件都是 QWidget 的子类。
     *
     * 需要将当前 QPushButton 放到当前 mainwindow 对象中
     * 当前代码所在位置是 MainWindow 构造函数。 所以 this
     * 关键字就是当前构造函数实例化对象本身,可以将 this 作为
     * setParent 函数参数提供给当前 QPushButton
     *
     * mainwindow 组件中存在子组件 【QPushButton *bt1】
     * Qt 系统会在当前 mainwindow 释放销毁时对子组件同时进行
     * 释放操作,不需要再使用 delete 销毁子组件内存空间,如果
     * 调用会导致【二次释放】
     */
    bt1->setParent(this);
}

MainWindow::~MainWindow()
{
    /*
     * delete ui;
     * ui ==> Ui::MainWindow *ui
     * 也就是当前实例化 MainWindow 对象。
     *
     * new 实现操作在 ui(new Ui::MainWindow) 构造函数
     * 对当前 MainWindow 进行内存空间申请和实例化操作。
     */
    delete ui;
}

3. 信号和槽【重点】

3.1 案例

项羽鸿门宴 宴请刘邦。分析当前有【三个对象】

  • 项羽
  • 刘邦
  • 准备干掉刘邦的人!【刀斧手】
3.2 系统中提供的信号和槽案例

完成一个操作,按键按下之后,关闭当前窗口

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /*
     * 当前代码实现于 MainWindow 构造函数,this 表示当前构造函数
     * 实例化对象的 MainWindow 本身
     *
     * new QPushButton(this); 当前操作是实例化 QPushButton 对象
     * 同时设置当前 QPushButton 父组件为 MainWindow
     * 相当于:
     *      QPushButton * closeBt = new QPushButton;
     *      closeBt->setParent(this);
     */
    QPushButton * closeBt = new QPushButton(this);

    closeBt->setText("关闭当前页面!");
    /*
     * inline void QWidget::resize(int w, int h)
     */
    closeBt->resize(150, 50);

    /*
     * 任务:
     *      点击当前 QPushButton 之后,当前 mainwindow 关闭
     * 利用信号槽机制完成
     *      1. 信号的发送者/发送对象 : QPushButton 对象
     *      2. 发送的信号是: QPushButton 点击操作 clicked
     *      3. 信号的接受者: 当前 mainwindow 对象,需要关闭的界面是
     *          当前 mainwindow 界面
     *      4. 执行的内容是: 当前 mainwindow 关闭页面操作。
     *
     * 利用 Qt connect 函数完成信号和槽之间的绑定关系。
     * connect(信号发送对象,
     *          信号函数,
     *          信号接收对象,
     *          执行任务函数/槽函数)
     */
     connect(closeBt, // 信号的发送对象
             &QPushButton::clicked, // 信号函数
             this, // 当前接受信号的对象,this 表示当前 mainwindow 构造函数实例化对象
             &QMainWindow::close // 当前执行任务函数/槽函数
             );
}

MainWindow::~MainWindow()
{
    delete ui;
}
3.3 connect 函数总结

connect();

Connection connect(const QObject *sender, 
                   const char *signal, 
                   const QObject *receiver, 
                   const char *method, 
                   Qt::ConnectionType type = Qt::AutoConnection)
  • sender:信号的发送对象
  • signal:信号函数地址
  • receiver:信号的接受对象,也可以认为是槽函数的执行对象
  • method:槽函数/任务函数地址。

当前函数是链接两个对象,将发送信号对象和接受信号对象进行链接,同时绑定其中的信号函数和槽函数/任务函数。

3.4 信号和槽总结【存疑】

信号的执行者/发送者是一个对象,同时信号函数是一个有且只有函数声明,没有函数体的函数。信号的接受者是一个对象,执行的槽函数必须有对应函数体。

在 Qt 中如果需要声明一个信号函数,必须在类中函数声明位置明确的告知使用关键字 signals

class XXX
{
public:
signals:
	// 信号函数,只有声明,没有实现
};

Qt 中只要是带有函数体的成员函数,都可以认为是槽函数,如果明确告知为槽函数,必须在函数声明位置明确告知使用关键字 slots

class XXX
{
public:
slots
	// 槽函数,声明之后,需要在对应 .cpp 文件中实现。
};
3.5 自定义信号和槽

案例代码中需要使用一个关键字 emit

场景: 老师饿了,学生请老师吃饭!

分析:

  • 信号的发送对象 :老师
  • 信号函数 : 饿了 ==> hungry
  • 信号的接受对象:学生
  • 槽函数/任务函数 : 请老师吃饭 Invite the teacher to dinner

自定义类流程

12-类名定义和继承关系 13-确认添加新的class和h文件

老师类定义

#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

class Teacher : public QObject
{
    Q_OBJECT
public:
    explicit Teacher(QObject *parent = nullptr);

signals:
    /*
     * 老师在 signals 关键字之后有且只声明一个函数,并且函数
     * 没有函数体
     * 【信号函数】
     */
     void hungry();
};

#endif // TEACHER_H

老师类实现

#include "teacher.h"

Teacher::Teacher(QObject *parent) : QObject(parent)
{

}

学生类定义

#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>
#include <QDebug>

class Student : public QObject
{
    Q_OBJECT
public:
    explicit Student(QObject *parent = nullptr);

    void Invite_dinner();

};

#endif // STUDENT_H

学生类实现

#include "student.h"

Student::Student(QObject *parent) : QObject(parent)
{

}

void Student::Invite_dinner()
{
    qDebug() << "学生请老师吃满汉全席";
}

mainwindow.h 头文件声明内容

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>

#include "teacher.h"
#include "student.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    void emit_teacher_signal();

private:
    Ui::MainWindow *ui;
    /*
     * 【修改】
     * 将 Teacher 和 Student 作为成员变量,同时选择数据类型方式
     * 为指针方式。另外声明位置为 private 修饰内容
     */
    Teacher *tea;
    Student *stu;

    QPushButton * bt1;

};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 实例化 Teacher 和 Student 对象,同时将当前对象最终的
    // 父组件设置为当前 mainwindow,最终内存销毁交给 mainwindow 完成
    tea = new Teacher(this);
    stu = new Student(this);

    bt1 = new QPushButton(this);
    bt1->setText("老师饿了!");
    bt1->resize(100, 50);

    /*
     * 利用 connect 函数链接
     *
     * 信号发送对象: tea
     * 信号: hungry 函数
     * 信号接收对象: stu
     * 槽函数: Invite_dinner
     */
    connect(tea,
            &Teacher::hungry,
            stu,
            &Student::Invite_dinner
            );

    /*
     * emit 关键字用于发送指定信号
     * 当前操作是 emit 发送 tea 的 hungry 信号
     */
//    emit_teacher_signal();

    /*
     * 【重点】
     *  将 QPushButton bt1 对象,和当前 mainwindow 成员函数
     *  emit_teacher_signal 进行 connect 链接
     *  利用 QPushButton clicked 信号,触发当前 mainwindow
     *  的 emit_teacher_signal。
     */
     connect(bt1,
             &QPushButton::clicked,
             this,
             &MainWindow::emit_teacher_signal
             );
}

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

void MainWindow::emit_teacher_signal()
{
    emit tea->hungry();
}
3.6 带有参数的信号和槽案例

Teacher 类补充有参数信号函数

void hungry(QString &food);

Student 类补充无参数槽函数

void inviteDinner(QString & food);

在 mainwindow 中定义 QLineEdit 组件内容 和 获取 QLineEdit 信息相关函数


class MainWindow : public QMainWindow
{
public:
    ****** 
	void get_edit_text();
    void emit_signal_with_msg();
private:
    Ui::MainWindow *ui;
    Student * stu;
    Teacher * tea;

    QPushButton * bt1;
    QPushButton * bt2;
    QLineEdit * edit;
};
edit = new QLineEdit(this);
edit->move(200, 200);

mainwindow 代码实现

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    stu = new Student(this);
    tea = new Teacher(this);

    bt1 = new QPushButton(this);

    bt1->resize(100, 50);
    bt1->setText("无参数信号");
    bt1->move(100, 100);

    bt2 = new QPushButton(this);

    bt2->resize(100, 50);
    bt2->setText("有参数信号");
    bt2->move(100, 200);

    edit = new QLineEdit(this);
    edit->move(200, 200);

    /*
     * 【重点】利用函数指针区分 hungry 有参和无参信号
     * 函数指针:
     *    返回值数据类型 (*函数指针)(参数数据类型);
     *    函数指针需要声明位置告知归属权
     */
    void (Teacher::*noArguHungry)(void) = &Teacher::hungry;
    void (Teacher::*arguHungry)(QString &) = &Teacher::hungry;

    /*
     * 【重点】 利用函数指针区分 Student 的 有参和无参 inviteDinner
     */
    void (Student::*noArguInviteDinner)(void) = &Student::inviteDinner;
    void (Student::*arguInviteDinner)(QString &) = &Student::inviteDinner;

    // 【完成无参数 Hungry 和 无参数 inviteDinner 链接】
    connect(tea,
            noArguHungry,
            stu,
            noArguInviteDinner);

    connect(bt1,
            &QPushButton::clicked,
            tea,
            noArguHungry);

/*
#if 0
    // 在 Student 和 Teacher 类内
    // 信号为 void hungry() 函数
    // 槽函数为 void inviteDinner() 函数
    connect(tea,
            &Teacher::hungry,
            stu,
            &Student::inviteDinner);


    // 利用 connect 函数,将 QPushButton clicked 和 Teacher 的 hungry 信号
    // 进行绑定,当前 clicked 触发,实际上触发的信号内容是 Teacher 的 hungry 信号

    connect(bt1,
            &QPushButton::clicked, // QPushButton clicked 信号
            tea,
            &Teacher::hungry // Teacher Hungry 信号
            );
#endif
*/
    /*
     * 将 Teacher void hungry(QString &food); 信号
     * 和 Student void inviteDinner(QString & food); 槽函数进行绑定
     * 绑定之后 Teacher 带有参数的信号会提供给 inviteDinner 使用,同时将
     * 参数赋值给 inviteDinner
     */
    connect(tea,
            arguHungry,
            stu,
            arguInviteDinner);

    connect(bt2,
           &QPushButton::clicked,
           this,
           &MainWindow::emit_signal_with_msg);
}

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

void MainWindow::get_edit_text()
{
    QString str = edit->text();
    qDebug() << str;
}

void MainWindow::emit_signal_with_msg()
{
    // 当前操作是从 QLineEdit 获取文本框中的字符串内容。
    QString msg = edit->text();
    // 利用 emit 关键字,发送 teacher 的hungry 信号,同时
    // 将 msg 作为信号的参数,提供一个【有参数信号】
    emit tea->hungry(msg);
}

4. MainWindow 组件

4.1 MainWindow 组件组成内容

MainWindow 组件主要包括

  • Window Title 整个界面的名称,也可以使用图片进行展示。
  • Menu Bar 菜单栏,包括菜单组件,选项组件
  • Tool Bar Area 工具栏
  • Dock Widget Area 可拖拽,可移动,可停靠组件区域,可以创建可移动的工具栏
  • Central Widget 中间组件,可以放置其他组件内容,例如 Text 文本,图片
  • Status Bar 状态栏
4.2 Window Title 和 Menu Bar

头文件声明

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
// QMenuBar 菜单栏组件
#include <QMenuBar>
// QMenu 菜单组件
#include <QMenu>
// QAction 选项组件
#include <QAction>
#include <QKeySequence>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    void ctrl_n();
    void ctrl_o();

private:
    Ui::MainWindow *ui;

    /*
     * 菜单栏组件,父组件是当前 MainWindow
     */
    QMenuBar *menuBar;
};
#endif // MAINWINDOW_H

主要功能实现

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /*
     * this 表示当前 mainwindow 对象。
     *
     * setWindowTitle(const QString & titleName);
     *      设置当前界面的标题
     */
    this->setWindowTitle("Qt 标题和菜单案例");
    /*
     * setWindowIcon(const QIcon & icon);
     *      设置当前页面的图标,后续需导入当前 Qt 项目所需的
     *      资源图片文件进行操作。
     */
    // this->setWindowIcon()
    /*
     * 设置当前页面的固定尺寸,尺寸仅是页面中空白区域的内容
     * 不包括页面的边框,和必要的 Title 区域
     *      setFixedSize(int w, int h);
     */
    this->setFixedSize(500, 500);

    /*
     * 实例化菜单栏,同时完成菜单栏添加到当前 mainwindow 中
     * new QMenuBar(this)
     *      告知当前 Qt 在组件树中,将 QMenuBar 的父组件设置
     *      为当前 MainWindow,方便后续 Qt 对当前内存的相关管理
     */
    menuBar = new QMenuBar(this);
    /*
     * this 是当前实例化 mainwindow 对象,也就是当前页面对象
     * setMenuBar(QMenuBar * menubar);
     *      设置当前 MainWindow 对应的菜单栏组件
     */
    this->setMenuBar(menuBar);

    /*
     * 实例化 QMenu 菜单组件
     */
    QMenu * file = new QMenu("文件(F)", menuBar);

    // file->setShortcut(QKeySequence(Qt::ALT + Qt::Key_F));

    QMenu * edit = new QMenu("编辑(E)", menuBar);

    // 将菜单组件添加到当前 QMenuBar 菜单栏中
    menuBar->addMenu(file);
    menuBar->addMenu(edit);

    // 实例化 QAction 选项组件,同时设置选项组件的快捷键
    QAction * newFileOrObject = new QAction("新建文件或项目(N)", file);
    newFileOrObject->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N));

    QAction * openFileOrObject = new QAction("打开文件或项目(O)", file);
    openFileOrObject->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_O));

    // 将 QAction 选项组件添加到 QMenu 菜单组件中
    file->addAction(newFileOrObject);
    file->addAction(openFileOrObject);

    // 利用 connect 链接 QAction 触发操作和对应函数
    connect(newFileOrObject,
            &QAction::triggered,
            this,
            &MainWindow::ctrl_n);

    connect(openFileOrObject,
            &QAction::triggered,
            this,
            &MainWindow::ctrl_o);
}

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

void MainWindow::ctrl_n()
{
    qDebug() << "Ctrl + N 触发!";
}
void MainWindow::ctrl_o()
{
    qDebug() << "Ctrl + O 触发!";
}
4.3 ToolBar 和 StatusBar

头文件内容

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
// QToolBar 工具栏
#include <QToolBar>
#include <QAction>
// QStatusBar 状态栏
#include <QStatusBar>
#include <QPushButton>
// QLabel 文本标签
#include <QLabel>

#include <QList>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    void show_msg();

private:
    Ui::MainWindow *ui;

    QToolBar * toolBar;
    QStatusBar * statusBar;
    QList<QAction *> * actionList;
};
#endif // MAINWINDOW_H

函数实现

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /* 工具栏 */
    toolBar = new QToolBar(this);

    toolBar->addAction("截图");
    toolBar->addSeparator();

    QAction * action1 = new QAction("取色笔", toolBar);
    toolBar->addAction(action1);

    actionList = new QList<QAction *>();

    actionList->push_back(new QAction("点赞", toolBar));
    actionList->push_back(new QAction("收藏", toolBar));
    actionList->push_back(new QAction("推荐", toolBar));
    actionList->push_back(new QAction("分享", toolBar));

    toolBar->addActions(*actionList);

    /*
    enum ToolBarArea {
        LeftToolBarArea = 0x1,     // 左侧 ToolBar 区域支持
        RightToolBarArea = 0x2,    // 右侧 ToolBar 区域支持
        TopToolBarArea = 0x4,      // 顶部 ToolBar 区域支持
        BottomToolBarArea = 0x8,   // 底部 ToolBar 区域支持

        ToolBarArea_Mask = 0xf,   // 所有区域支持宏常量
        AllToolBarAreas = ToolBarArea_Mask, // 支持所有区域 【默认值】
        NoToolBarArea = 0 // 不能靠边
    };
     */
    // 设置当前 QToolBar 允许靠边的区域范围
    // Qt::ToolBarArea::LeftToolBarArea 有且只允许左侧停靠
    // Qt::ToolBarArea::LeftToolBarArea | Qt::ToolBarArea::RightToolBarArea 有且只允许左侧和右侧停靠
    toolBar->setAllowedAreas(Qt::ToolBarArea::AllToolBarAreas);

    // 当前 mainwindow 添加 toolbar 组件默认靠边方式。
    this->addToolBar(Qt::ToolBarArea::LeftToolBarArea, toolBar);

    /* 状态栏 */
    statusBar = new QStatusBar(this);

    QLabel * label1 = new QLabel("状态信息", this);
    // 添加 QWidget 组件到状态类左侧
    statusBar->addWidget(label1);

    QLabel * label2 = new QLabel("少吃冰淇淋", this);
    // 添加 QWidget 组件到状态类右侧
    statusBar->addPermanentWidget(label2);

    QPushButton * bt = new QPushButton("惊喜", this);
    statusBar->addWidget(bt);

    connect(bt, &QPushButton::clicked, this, &MainWindow::show_msg);

    connect(bt, &QPushButton::clicked, [=]() {qDebug() << "233333";});

    this->setStatusBar(statusBar);

}

MainWindow::~MainWindow()
{
    delete actionList;
    delete ui;

}

void MainWindow::show_msg()
{
    qDebug() << "什么叫惊喜!";
}
4.4 DockWidget 和 CentralWidget

头文件内容

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
// QDockWidget 铆接部件
#include <QDockWidget>
// QTextEdit 文本框
#include <QTextEdit>
#include <QAction>
#include <QMenuBar>
#include <QMenu>
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    void initMenuBar();
    void initCentralWidget();
    void initStatusBar();
    void initToolBar();

private:
    Ui::MainWindow *ui;

    QDockWidget * dockWidget;
    QTextEdit * textEdit;
};
#endif // MAINWINDOW_H

实现内容代码

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    textEdit = new QTextEdit(this);
    this->setCentralWidget(textEdit);

    dockWidget = new QDockWidget(this);

    dockWidget->setWidget(new QPushButton("按一下" ,this));
//    dockWidget->setWidget(new QTextEdit(this));

    dockWidget->addAction(new QAction("2333", this));

    /*
    enum DockWidgetArea {
        LeftDockWidgetArea = 0x1,
        RightDockWidgetArea = 0x2,
        TopDockWidgetArea = 0x4,
        BottomDockWidgetArea = 0x8,

        DockWidgetArea_Mask = 0xf,
        AllDockWidgetAreas = DockWidgetArea_Mask,
        NoDockWidgetArea = 0
    };
    */
    this->addDockWidget(Qt::DockWidgetArea::AllDockWidgetAreas, dockWidget);


}

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

5. 资源文件添加

5.1 添加资源文件流程

17-资源文件配置.png

18-资源文件配置前缀修改.png

5.2 案例代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QPixmap *pix1 = new QPixmap;
    // : 真坑!!!
    bool ret = pix1->load(":/img/1.png");

    if (ret)
    {
        qDebug() <<"加载成功";
    }
    else
    {
        qDebug() << "加载失败!";
    }

    QIcon * icon = new QIcon(*pix1);
    this->setWindowIcon(*icon);
    this->setWindowTitle("志祺牌快乐水!");


    QPixmap * pix2 = new QPixmap;
    pix2->load(":/img/2.png");
    QLabel * label = new QLabel(this);
    label->resize(416, 416);
    label->setPixmap(*pix2);

    label->show();
}

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

6. 对话框 Dialog

6.1 Qt 对话框分类
  • 阻塞对话框。模态对话框
  • 非阻塞对话框。非模态对话框

对话框分为系统提供的常用对话框和自定义对话框内容。

6.2 系统提供的对话框

QColorDialog 和 QFontDialog

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    colorDialogBt = new QPushButton("颜色选择", this);
    fontDialogBt = new QPushButton("字体选择", this);

    colorDialogBt->resize(100, 50);
    colorDialogBt->move(100, 100);

    fontDialogBt->resize(100, 50);
    fontDialogBt->move(200, 100);

    label = new QLabel(this);
    label->setText("测试使用字符串内容");
    label->resize(300, 50);
    label->move(100, 200);

    connect(colorDialogBt, &QPushButton::clicked, this, &MainWindow::changeColor);
    connect(fontDialogBt, &QPushButton::clicked, this, &MainWindow::changeFont);
}

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

void MainWindow::changeColor()
{
    /*
    static QColor getColor(const QColor &initial = Qt::white,
                           QWidget *parent = nullptr,
                           const QString &title = QString(),
                           ColorDialogOptions options = ColorDialogOptions());
    当前函数是一个 static 修饰静态成员函数,可以直接利用类名 + 作用域运算符进行调用,执行
    效率极高。
    需要修改的参数有三个:
        QColor &initial 存在默认值参数,默认对应颜色为 Qt::white
        QWidget *parent 选择当前所在的父组件是哪一个,因为当前颜色对话框是一个阻塞对话框,
            明确告知限制的上一级组件是哪一个
        const QString &title = QString(), 当前对话框的名称
        ColorDialogOptions options = ColorDialogOptions() 直接使用默认值即可,当前
        颜色对话框默认选项
    */

    QColor color = QColorDialog::getColor(Qt::white,
                                          this,
                                          "颜色选择");
    qDebug() << "Red : " << color.red()
             << "Green : " << color.green()
             << "Blue : " << color.blue();

    /*
     * 获取当前 Label 对应的 QPalette 调色板对象
     */
    QPalette palette = label->palette();
    // 设置当前调色板对象目标修改的内容 WindowText 界面文本,和使用的 QColor 对象
    palette.setColor(QPalette::WindowText, color);
    // 将 Label 使用的 QPalette 进行修改
    label->setPalette(palette);
}
void MainWindow::changeFont()
{
    /*
     static QFont getFont(bool *ok, QWidget *parent = nullptr);
     QFontDialog 获取 QFont 字体对象方式,要求参数是一个 bool 类型指针对应
     变量存储数据为 true ,和当前指定组件的父组件情况
     */
    bool ret = true;
    QFont font = QFontDialog::getFont(&ret,
                                      QFont("宋体"),
                                      this,
                                      "字体选择");

    qDebug() << "Family : " << font.family()
             << "Size : " << font.pointSize();

    label->setFont(font);
}
6.3 自定义对话框
6.4 消息对话框

使用的是 QMessageBox 组件,涉及到提示,选择,警告...