QT 入门

目录

一、简介

二、基础模块

三、优秀的开发案例

四、窗口类

1、QWidget

(1)基础

(2)常用api

 (3)案例

2、QDialog

(1)基础

(2)例子

(3)子类

QMessageBox

QFileDialog

QFontDialog

 QFont 字体

 QColorDialog

QInputDialog

QProgressDialog

3、QMainWindow

菜单栏

 工具栏

 状态栏

QDockWidget 停靠窗口

​编辑 五、内存回收

1、QObject

2、QWidget

六、基础类型

1、#include

2、日志输出 QDebug

3、字符串 QByteArray QString

(1)QByteArray

(2)QString

(3)区别

4、QVariant

5、QPoint 坐标类

6、QLine

7、QSize 长宽

8、QRect 矩形

9、QDate 日期时间

(1)QDate

(2)QTime 时分秒 毫秒

(3)QDateTime 日期时间

七、信号槽

1、基础

 2、自定义信号槽

3、拓展

八、lamda表达式

九、QTimer 定时器

十、资源文件

 十一、布局


一、简介

跨平台的C++应用开发框架

广泛用于开发图形用户界面 GUI (graphical user interface)

拥有丰富的Api(250+类)

支持正则表达式

支持2/3D渲染,OpenGL

支持XML,Json

二、基础模块

core

GUI

Widgets

Multimedia 多媒体

Network 网络编程

QML 基于JavaScript

Quick 嵌入式

Sql 数据库

Test 测试

三、优秀的开发案例

virtualbox 甲骨文

咪咕音乐

WPS Office 金山

Skype 聊天软件

四、窗口类

1、QWidget

(1)基础

所有窗口类的基类,其父类是QObject

内嵌-无边框

独立窗口-有边框

(2)常用api

// 构造函数
QWidget::QWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());

// 公共成员函数
// 给当前窗口设置父对象
void QWidget::setParent(QWidget *parent);
void QWidget::setParent(QWidget *parent, Qt::WindowFlags f);
// 获取当前窗口的父对象, 没有父对象返回 nullptr
QWidget *QWidget::parentWidget() const;

 窗口位置

//------------- 窗口位置 -------------
// 得到相对于当前窗口父窗口的几何信息, 边框也被计算在内
QRect QWidget::frameGeometry() const;
// 得到相对于当前窗口父窗口的几何信息, 不包括边框
const QRect &geometry() const;
// 设置当前窗口的几何信息(位置和尺寸信息), 不包括边框
void setGeometry(int x, int y, int w, int h);
void setGeometry(const QRect &);
    
// 移动窗口, 重新设置窗口的位置
void move(int x, int y);
void move(const QPoint &);

获取位置

// 获取当前窗口的位置信息
void MainWindow::on_positionBtn_clicked()
{
    QRect rect = this->frameGeometry();
    qDebug() << "左上角: " << rect.topLeft()
             << "右上角: " << rect.topRight()
             << "左下角: " << rect.bottomLeft()
             << "右下角: " << rect.bottomRight()
             << "宽度: " << rect.width()
             << "高度: " << rect.height();
}

// 重新设置当前窗口的位置以及宽度, 高度
void MainWindow::on_geometryBtn_clicked()
{
    int x = 100 + rand() % 500;
    int y = 100 + rand() % 500;
    int width = this->width() + 10;
    int height = this->height() + 10;
    setGeometry(x, y, width, height);
}

// 通过 move() 方法移动窗口
void MainWindow::on_moveBtn_clicked()
{
    QRect rect = this->frameGeometry();
    move(rect.topLeft() + QPoint(10, 20));
}

 窗口尺寸

//------------- 窗口尺寸 -------------
// 获取当前窗口的尺寸信息
QSize size() const
// 重新设置窗口的尺寸信息
void resize(int w, int h);
void resize(const QSize &);
// 获取当前窗口的最大尺寸信息
QSize maximumSize() const;
// 获取当前窗口的最小尺寸信息
QSize minimumSize() const;
// 设置当前窗口固定的尺寸信息
void QWidget::setFixedSize(const QSize &s);
void QWidget::setFixedSize(int w, int h);
// 设置当前窗口的最大尺寸信息
void setMaximumSize(const QSize &);
void setMaximumSize(int maxw, int maxh);
// 设置当前窗口的最小尺寸信息
void setMinimumSize(const QSize &);
void setMinimumSize(int minw, int minh);


// 获取当前窗口的高度    
int height() const;
// 获取当前窗口的最小高度
int minimumHeight() const;
// 获取当前窗口的最大高度
int maximumHeight() const;
// 给窗口设置固定的高度
void QWidget::setFixedHeight(int h);
// 给窗口设置最大高度
void setMaximumHeight(int maxh);
// 给窗口设置最小高度
void setMinimumHeight(int minh);

// 获取当前窗口的宽度
int width() const;
// 获取当前窗口的最小宽度
int minimumWidth() const;
// 获取当前窗口的最大宽度
int maximumWidth() const;
// 给窗口设置固定宽度
void QWidget::setFixedWidth(int w);
// 给窗口设置最大宽度
void setMaximumWidth(int maxw);
// 给窗口设置最小宽度
void setMinimumWidth(int minw);

 窗口标题和图标

//------------- 窗口图标 -------------
// 得到当前窗口的图标
QIcon windowIcon() const;
// 构造图标对象, 参数为图片的路径
QIcon::QIcon(const QString &fileName);
// 设置当前窗口的图标
void setWindowIcon(const QIcon &icon);

//------------- 窗口标题 -------------
// 得到当前窗口的标题
QString windowTitle() const;
// 设置当前窗口的标题
void setWindowTitle(const QString &);

 窗口显示和窗口状态

//------------- 窗口显示 -------------
// 关闭当前窗口
[slot] bool QWidget::close();
// 隐藏当前窗口
[slot] void QWidget::hide();
// 显示当前创建以及其子窗口
[slot] void QWidget::show();
// 全屏显示当前窗口, 只对windows有效
[slot] void QWidget::showFullScreen();
// 窗口最大化显示, 只对windows有效
[slot] void QWidget::showMaximized();
// 窗口最小化显示, 只对windows有效
[slot] void QWidget::showMinimized();
// 将窗口回复为最大化/最小化之前的状态, 只对windows有效
[slot] void QWidget::showNormal();

//------------- 窗口状态 -------------
// 判断窗口是否可用
bool QWidget::isEnabled() const; // 非槽函数
// 设置窗口是否可用, 不可用窗口无法接收和处理窗口事件
// 参数true->可用, false->不可用
[slot] void QWidget::setEnabled(bool);
// 设置窗口是否可用, 不可用窗口无法接收和处理窗口事件
// 参数true->不可用, false->可用
[slot] void QWidget::setDisabled(bool disable);
// 设置窗口是否可见, 参数为true->可见, false->不可见
[slot] virtual void QWidget::setVisible(bool visible);

 信号

// QWidget::setContextMenuPolicy(Qt::ContextMenuPolicy policy);
// 窗口的右键菜单策略 contextMenuPolicy() 参数设置为 Qt::CustomContextMenu, 按下鼠标右键发射该信号
[signal] void QWidget::customContextMenuRequested(const QPoint &pos);
// 窗口图标发生变化, 发射此信号
[signal] void QWidget::windowIconChanged(const QIcon &icon);
// 窗口标题发生变化, 发射此信号
[signal] void QWidget::windowTitleChanged(const QString &title);

 (3)案例

QT 入门_第1张图片

代码

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //setMaximumSize(600, 600);
    //setMinimumSize(300, 300);
    //setFixedSize(500, 500);
    setWindowTitle("hello, qt  ");
    setWindowIcon(QIcon("e:\\1.jpg"));
}

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


void MainWindow::on_moveBtn_clicked()
{
    QRect rect = this->frameGeometry();
    move(rect.topLeft() + QPoint(10, 20));
}

void MainWindow::on_positionBtn_clicked()
{
    QRect rect = this->frameGeometry();
    qDebug() << "左上角:" << rect.topLeft();
    qDebug() << "右上角:" << rect.topRight();
    qDebug() << "左下角:" << rect.bottomLeft();
    qDebug() << "右下角:" << rect.bottomRight();
    qDebug() << "宽度:" << rect.width();
    qDebug() << "高度:" << rect.height();
}

void MainWindow::on_geometryBtn_clicked()
{
    int x = 100 + rand() % 500;
    int y = 100 + rand() % 500;
    int width = this->width() + 10;
    int height = this->height() + 10;
    setGeometry(x, y, width, height);
}

左上角: QPoint(389,321)

右上角: QPoint(1240,321)

左下角: QPoint(389,1002)

右下角: QPoint(1240,1002)

宽度: 852

高度: 682

修改标题和图标

connect(this, &MainWindow::windowTitleChanged, this, [=](const QString &title){
       qDebug() << "新的标题: " << title;
    });
    connect(this, &MainWindow::windowIconChanged, this, [=](const QIcon &icon){
       qDebug() << "当前图标被修改了... ";
    });

void MainWindow::on_modifyBtn_clicked()
{
    setWindowTitle("你好,世界");
    setWindowIcon(QIcon("e:\\2.jpg"));
}

 右键菜单

setContextMenuPolicy(Qt::CustomContextMenu);
    connect(this, &MainWindow::customContextMenuRequested, this, [=](const QPoint &pos){
       QMenu menu;
       menu.addAction("西红柿");
       menu.addAction("黄瓜");
       menu.addAction("茄子");
       menu.exec(QCursor::pos());
    });

QT 入门_第2张图片

2、QDialog

(1)基础

基类的派生类

对话框

不能内嵌

exec阻塞程序

(2)例子

void MainWindow::on_modalDlg_clicked()
{
    MyDialog dlg;
    connect(&dlg, &MyDialog::finished, this, [=](int res){
        qDebug() << "result: " << res;
    });
    connect(&dlg, &MyDialog::accepted, this, [=](){
        qDebug() << "accept信号被发射了...";
    });
    connect(&dlg, &MyDialog::rejected, this, [=](){
        qDebug() << "reject信号被发射了...";
    });
    int ret = dlg.exec();
    if (ret == QDialog::Accepted)
    {
        qDebug() << "accept button clicked...";
    }
    else if(ret == QDialog::Rejected)
    {
        qDebug() << "reject button clicked...";
    }
    else
    {
        qDebug() << "done button clicked...";
    }
}



void MyDialog::on_acceptBtn_clicked()
{
    this->accept();
}

void MyDialog::on_rejectBtn_clicked()
{
    this->reject();
}

void MyDialog::on_doneBtn_clicked()
{
    this->done(10);
}

accept信号被发射了...

result: 1

accept button clicked...

reject信号被发射了...

result: 0

reject button clicked...

result: 10

done button clicked...

(3)子类

QMessageBox
void MainWindow::on_msgbox_clicked()
{
    QMessageBox::about(this, "about",  "这是一个简单的消息提示框!!!");
        QMessageBox::critical(this, "critical", "这是一个错误对话框-critical...");
        int ret = QMessageBox::question(this, "question",
                 "你要保存修改的文件内容吗???",
                  QMessageBox::Save|QMessageBox::Cancel,
                  QMessageBox::Cancel);
        if(ret == QMessageBox::Save)
        {
            QMessageBox::information(this, "information", "恭喜你保存成功了, o(* ̄︶ ̄*)o!!!");
        }
        else if(ret == QMessageBox::Cancel)
        {
            QMessageBox::warning(this, "warning", "你放弃了保存, ┭┮﹏┭┮ !!!");
        }
}

QT 入门_第3张图片

 QT 入门_第4张图片

QT 入门_第5张图片

QT 入门_第6张图片

QT 入门_第7张图片

QFileDialog

打开文件、目录

/*
通用参数:
  - parent: 当前对话框窗口的父对象也就是父窗口
  - caption: 当前对话框窗口的标题
  - dir: 当前对话框窗口打开的默认目录
  - options: 当前对话框窗口的一些可选项,枚举类型, 一般不需要进行设置, 使用默认值即可
  - filter: 过滤器, 在对话框中只显示满足条件的文件, 可以指定多个过滤器, 使用 ;; 分隔
    - 样式举例: 
	- Images (*.png *.jpg)
	- Images (*.png *.jpg);;Text files (*.txt)
  - selectedFilter: 如果指定了多个过滤器, 通过该参数指定默认使用哪一个, 不指定默认使用第一个过滤器
*/
// 打开一个目录, 得到这个目录的绝对路径
[static] QString QFileDialog::getExistingDirectory(
                  QWidget *parent = nullptr, 
                  const QString &caption = QString(), 
                  const QString &dir = QString(), 
                  QFileDialog::Options options = ShowDirsOnly);

// 打开一个文件, 得到这个文件的绝对路径
[static] QString QFileDialog::getOpenFileName(
    	          QWidget *parent = nullptr, 
    		  const QString &caption = QString(), 
                  const QString &dir = QString(), 
                  const QString &filter = QString(), 
                  QString *selectedFilter = nullptr, 
                  QFileDialog::Options options = Options());

// 打开多个文件, 得到这多个文件的绝对路径
[static] QStringList QFileDialog::getOpenFileNames(
    	          QWidget *parent = nullptr, 
                  const QString &caption = QString(), 
                  const QString &dir = QString(), 
                  const QString &filter = QString(), 
                  QString *selectedFilter = nullptr, 
                  QFileDialog::Options options = Options());

// 打开一个目录, 使用这个目录来保存指定的文件
[static] QString QFileDialog::getSaveFileName(
    		  QWidget *parent = nullptr, 
                  const QString &caption = QString(), 
                  const QString &dir = QString(), 
                  const QString &filter = QString(), 
                  QString *selectedFilter = nullptr, 
                  QFileDialog::Options options = Options());

例子,找路径

#define OPENFILE
void MainWindow::on_QFileDlgBtn_clicked()
{
#ifdef OPENDIR
    QString dirName = QFileDialog::getExistingDirectory(this, "打开目录", "e:\\Project5");
        QMessageBox::information(this, "打开目录", "您选择的目录是: " + dirName);
#endif
#ifdef OPENFILE
        QString arg("Text files (*.txt)");
            QString fileName = QFileDialog::getOpenFileName(
                      this, "Open File", "e:\\Project5",
                      "Images (*.png *.jpg);;Text files (*.txt)", &arg);
            QMessageBox::information(this, "打开文件", "您选择的文件是: " + fileName);
#endif

#ifdef OPENFILES
            QStringList fileNames = QFileDialog::getOpenFileNames(
                          this, "Open File", "e:\\Project5",
                          "Images (*.png *.jpg);;Text files (*.txt)");
                QString names;
                for(int i=0; i
QFontDialog

字体设置对话框

 QFont 字体
QFont::QFont(const QString &family, int pointSize = -1, int weight = -1, bool italic = false);

例子

void MainWindow::on_fontdlg_clicked()
{
#if 1
    // 方式1
    bool ok;
    QFont ft = QFontDialog::getFont(
                &ok, QFont("微软雅黑", 12, QFont::Bold), this, "选择字体");
    qDebug() << "ok value is: " << ok;
#else
    // 方式2
    QFont ft = QFontDialog::getFont(NULL);
#endif
    // 将选择的字体设置给当前窗口对象
    ui->fontlabel->setFont(ft);
}

 QT 入门_第8张图片

 

 QColorDialog

fv

QInputDialog
// 得到一个可以输入浮点数的对话框窗口, 返回对话框窗口中输入的浮点数
/*
参数:
  - parent: 对话框窗口的父窗口
  - title: 对话框窗口显示的标题信息
  - label: 对话框窗口中显示的文本信息(用于描述对话框的功能)
  - value: 对话框窗口中显示的浮点值, 默认为 0
  - min: 对话框窗口支持显示的最小数值
  - max: 对话框窗口支持显示的最大数值
  - decimals: 浮点数的精度, 默认保留小数点以后1位
  - ok: 传出参数, 用于判断是否得到了有效数据, 一般不会使用该参数
  - flags: 对话框窗口的窗口属性, 使用默认值即可
*/
[static] double QInputDialog::getDouble(
    		QWidget *parent, const QString &title, 
    		const QString &label, double value = 0, 
    		double min = -2147483647, double max = 2147483647, 
    		int decimals = 1, bool *ok = nullptr, 
    		Qt::WindowFlags flags = Qt::WindowFlags());

// 得到一个可以输入整形数的对话框窗口, 返回对话框窗口中输入的整形数
/*
参数:
  - parent: 对话框窗口的父窗口
  - title: 对话框窗口显示的标题信息
  - label: 对话框窗口中显示的文本信息(用于描述对话框的功能)
  - value: 对话框窗口中显示的整形值, 默认为 0
  - min: 对话框窗口支持显示的最小数值
  - max: 对话框窗口支持显示的最大数值
  - step: 步长, 通过对话框提供的按钮调节数值每次增长/递减的量
  - ok: 传出参数, 用于判断是否得到了有效数据, 一般不会使用该参数
  - flags: 对话框窗口的窗口属性, 使用默认值即可
*/
[static] int QInputDialog::getInt(
    		QWidget *parent, const QString &title, 
    		const QString &label, int value = 0, 
    		int min = -2147483647, int max = 2147483647, 
    		int step = 1, bool *ok = nullptr, 
    		Qt::WindowFlags flags = Qt::WindowFlags());

// 得到一个带下来菜单的对话框窗口, 返回选择的菜单项上边的文本信息
/*
参数:
  - parent: 对话框窗口的父窗口
  - title: 对话框窗口显示的标题信息
  - label: 对话框窗口中显示的文本信息(用于描述对话框的功能)
  - items: 字符串列表, 用于初始化窗口中的下拉菜单, 每个字符串对应一个菜单项
  - current: 通过菜单项的索引指定显示下拉菜单中的哪个菜单项, 默认显示第一个(编号为0)
  - editable: 设置菜单项上的文本信息是否可以进行编辑, 默认为true, 即可以编辑
  - ok: 传出参数, 用于判断是否得到了有效数据, 一般不会使用该参数
  - flags: 对话框窗口的窗口属性, 使用默认值即可
  - inputMethodHints: 设置显示模式, 默认没有指定任何特殊显示格式, 显示普通文本字符串
    - 如果有特殊需求, 可以参数帮助文档进行相关设置
*/
[static] QString QInputDialog::getItem(
    		QWidget *parent, const QString &title, 
    		const QString &label, const QStringList &items, 
    		int current = 0, bool editable = true, bool *ok = nullptr, 
    		Qt::WindowFlags flags = Qt::WindowFlags(), 
    		Qt::InputMethodHints inputMethodHints = Qt::ImhNone);

// 得到一个可以输入多行数据的对话框窗口, 返回用户在窗口中输入的文本信息
/*
参数:
  - parent: 对话框窗口的父窗口
  - title: 对话框窗口显示的标题信息
  - label: 对话框窗口中显示的文本信息(用于描述对话框的功能)
  - text: 指定显示到多行输入框中的文本信息, 默认是空字符串
  - ok: 传出参数, 用于判断是否得到了有效数据, 一般不会使用该参数
  - flags: 对话框窗口的窗口属性, 使用默认值即可
  - inputMethodHints: 设置显示模式, 默认没有指定任何特殊显示格式, 显示普通文本字符串
    - 如果有特殊需求, 可以参数帮助文档进行相关设置
*/
[static] QString QInputDialog::getMultiLineText(
    		QWidget *parent, const QString &title, const QString &label, 
    		const QString &text = QString(), bool *ok = nullptr, 
    		Qt::WindowFlags flags = Qt::WindowFlags(), 
    		Qt::InputMethodHints inputMethodHints = Qt::ImhNone);

// 得到一个可以输入单行信息的对话框窗口, 返回用户在窗口中输入的文本信息
/*
参数:
  - parent: 对话框窗口的父窗口 
  - title: 对话框窗口显示的标题信息
  - label: 对话框窗口中显示的文本信息(用于描述对话框的功能)
  - mode: 指定单行编辑框中数据的反馈模式, 是一个 QLineEdit::EchoMode 类型的枚举值
    - QLineEdit::Normal: 显示输入的字符。这是默认值
    - QLineEdit::NoEcho: 不要展示任何东西。这可能适用于连密码长度都应该保密的密码。
    - QLineEdit::Password: 显示与平台相关的密码掩码字符,而不是实际输入的字符。
    - QLineEdit::PasswordEchoOnEdit: 在编辑时按输入显示字符,否则按密码显示字符。
  - text: 指定显示到单行输入框中的文本信息, 默认是空字符串
  - ok: 传出参数, 用于判断是否得到了有效数据, 一般不会使用该参数
  - flags: 对话框窗口的窗口属性, 使用默认值即可
  - inputMethodHints: 设置显示模式, 默认没有指定任何特殊显示格式, 显示普通文本字符串
     - 如果有特殊需求, 可以参数帮助文档进行相关设置
*/
[static] QString QInputDialog::getText(
    		QWidget *parent, const QString &title, const QString &label,
    		QLineEdit::EchoMode mode = QLineEdit::Normal, 
    		const QString &text = QString(), bool *ok = nullptr, 
    		Qt::WindowFlags flags = Qt::WindowFlags(), 
    		Qt::InputMethodHints inputMethodHints = Qt::ImhNone);

 整形输入框

void MainWindow::on_inputdlg_clicked()
{
    int ret = QInputDialog::getInt(this, "年龄", "您的当前年龄: ", 10, 1, 100, 2);
    QMessageBox::information(this, "年龄", "您的当前年龄: " + QString::number(ret));
}

QT 入门_第9张图片

浮点型输入框

void MainWindow::on_inputdlg_clicked()
{
    double ret = QInputDialog::getDouble(this, "工资", "您的工资: ", 2000, 1000, 6000, 2);
    QMessageBox::information(this, "工资", "您的当前工资: " + QString::number(ret));
}

 带下拉窗口

void MainWindow::on_inputdlg_clicked()
{
    QStringList items;
    items << "苹果" << "橙子" << "橘子" << "葡萄" << "香蕉" << "哈密瓜";
    QString item = QInputDialog::getItem(this, "请选择你喜欢的水果", "你最喜欢的水果:", items, 1, false);
    QMessageBox::information(this, "水果", "您最喜欢的水果是: " + item);
}

多行字符串输入框

void MainWindow::on_inputdlg_clicked()
{
    QString info = QInputDialog::getMultiLineText(this, "表白", "您最想对漂亮小姐姐说什么呢?", "呦吼吼...");
    QMessageBox::information(this, "知心姐姐", "您最想对小姐姐说: " + info);
}

 单行字符串输入框

void MainWindow::on_inputdlg_clicked()
{
    QString text = QInputDialog::getText(this, "密码", "请输入新的密码", QLineEdit::Password, "helloworld");
    QMessageBox::information(this, "密码", "您设置的密码是: " + text);
}
QProgressDialog

进度对话

// 构造函数
/*
参数:
  - labelText: 对话框中显示的提示信息
  - cancelButtonText: 取消按钮上显示的文本信息
  - minimum: 进度条最小值
  - maximum: 进度条最大值
  - parent: 当前窗口的父对象
  - f: 当前进度窗口的flag属性, 使用默认属性即可, 无需设置
*/
QProgressDialog::QProgressDialog(
	QWidget *parent = nullptr, 
	Qt::WindowFlags f = Qt::WindowFlags());

QProgressDialog::QProgressDialog(
	const QString &labelText, const QString &cancelButtonText, 
	int minimum, int maximum, QWidget *parent = nullptr,
	Qt::WindowFlags f = Qt::WindowFlags());


// 设置取消按钮显示的文本信息
[slot] void QProgressDialog::setCancelButtonText(const QString &cancelButtonText);

// 公共成员函数和槽函数
QString QProgressDialog::labelText() const;
void QProgressDialog::setLabelText(const QString &text);

// 得到进度条最小值
int QProgressDialog::minimum() const;
// 设置进度条最小值
void QProgressDialog::setMinimum(int minimum);

// 得到进度条最大值
int QProgressDialog::maximum() const;
// 设置进度条最大值
void QProgressDialog::setMaximum(int maximum);

// 设置进度条范围(最大和最小值)
[slot] void QProgressDialog::setRange(int minimum, int maximum);

// 得到进度条当前的值
int QProgressDialog::value() const;
// 设置进度条当前的值
void QProgressDialog::setValue(int progress);


bool QProgressDialog::autoReset() const;
// 当value() = maximum()时,进程对话框是否调用reset(),此属性默认为true。
void QProgressDialog::setAutoReset(bool reset);


bool QProgressDialog::autoClose() const;
// 当value() = maximum()时,进程对话框是否调用reset()并且隐藏,此属性默认为true。
void QProgressDialog::setAutoClose(bool close);

// 判断用户是否按下了取消键, 按下了返回true, 否则返回false
bool wasCanceled() const;


// 重置进度条
// 重置进度对话框。wascancelled()变为true,直到进程对话框被重置。进度对话框被隐藏。
[slot] void QProgressDialog::cancel();
// 重置进度对话框。如果autoClose()为真,进程对话框将隐藏。
[slot] void QProgressDialog::reset();   

// 信号
// 当单击cancel按钮时,将发出此信号。默认情况下,它连接到cancel()槽。
[signal] void QProgressDialog::canceled();

// 设置窗口的显示状态(模态, 非模态)
/*
参数:
	Qt::NonModal  -> 非模态
	Qt::WindowModal	-> 模态, 阻塞父窗口
	Qt::ApplicationModal -> 模态, 阻塞应用程序中的所有窗口
*/
void QWidget::setWindowModality(Qt::WindowModality windowModality);

 例子

void MainWindow::on_progressdlg_clicked()
{
    // 1. 创建进度条对话框窗口对象
    QProgressDialog *progress = new QProgressDialog(
                "正在拷贝数据...", "取消拷贝", 0, 100, this);
    // 2. 初始化并显示进度条窗口
    progress->setWindowTitle("请稍后");
    progress->setWindowModality(Qt::WindowModal);
    progress->show();

    // 3. 更新进度条
    static int value = 0;
    QTimer *timer = new QTimer;
    connect(timer, &QTimer::timeout, this, [=]()
    {
         progress->setValue(value);
         value++;
         // 当value > 最大值的时候
         if(value > progress->maximum())
         {
             timer->stop();
             value = 0;
             delete progress;
             delete timer;
         }
    });

    connect(progress, &QProgressDialog::canceled, this, [=]()
    {
        timer->stop();
        value = 0;
        delete progress;
        delete timer;
    });

    timer->start(50);
}

QT 入门_第10张图片

3、QMainWindow

基类的派生类

不能内嵌

包含菜单栏、工具栏、状态栏

菜单栏

QT 入门_第11张图片

显示到窗口中 

QT 入门_第12张图片

 QT 入门_第13张图片

// save_action 是某个菜单项对象名, 点击这个菜单项会弹出一个对话框
connect(ui->save_action, &QAction::triggered, this, [=]()
{
      QMessageBox::information(this, "Triggered", "我是菜单项, 你不要调戏我...");
});

点击 保存

QT 入门_第14张图片

 工具栏

先显示工具栏

QT 入门_第15张图片

可以直接拖动

QT 入门_第16张图片

 增加搜索框

    ui->toolBar->addWidget(new QPushButton("搜索"));
    ui->toolBar->addWidget(new QLineEdit);

QT 入门_第17张图片

 增加第二个工具栏

// 添加第二个工具栏
    QToolBar* toolbar = new QToolBar("toolbar");
    this->addToolBar(Qt::LeftToolBarArea, toolbar);

QT 入门_第18张图片

 状态栏
// 状态栏添加子控件
// 按钮
QPushButton* button = new QPushButton("按钮");
ui->statusbar->addWidget(button);
// 标签
QLabel* label = new QLabel("hello,world");
ui->statusbar->addWidget(label);

QT 入门_第19张图片

显示字,但是会覆盖掉其他附件

//放到开头
ui->statusbar->showMessage("我是状态栏...");

 修改成2秒后,消失

 ui->statusbar->showMessage("我是状态栏...", 2000);

            QPushButton* button = new QPushButton("按钮");
            ui->statusbar->addWidget(button);
            // 标签
            QLabel* label = new QLabel("hello,world");
            ui->statusbar->addWidget(label);

            QTimer::singleShot(5000, this, [=](){
               button->show();
               label->show();
            });
QDockWidget 停靠窗口

QT 入门_第20张图片 五、内存回收

1、QObject

无父类

2、QWidget

继承自QObject

六、基础类型

1、#include

熟知qint之类

实际应用int之类

2、日志输出 QDebug

调用qDebug

qDebug() << "hello" << "*" << 10000;

想在外边显示终端 :在pro的config后加上 console 并重新构建项目

3、字符串 QByteArray QString

(1)QByteArray

构造函数

//空对象
QByteArray::QByteArray();

//构造size长度的data,-1为自动计算长度
QByteArray::QByteArray(const char *data, int size=-1);

//构造size个ch字符
QByteArray::QByteArray(int size, char ch);

数据操作

//尾加数据
QByteArray @QByteArray::append(const QByteArray &ba);
void QByteArray::push_back(const QByteArray &other);

//头加数据
QByteArray @QByteArray::prepend(const QByteArray &ba);
void QByteArray::push_front(const QByteArray &other);

//插入任意位置,i之前
QByteArray @QByteArray::insert(int i, const QByteArray &ba);

//删除数据,从pos开始len个
QByteArray @QByteArray::remove(int pos, int len);
//删除尾部n个
void QByteArray::chop(int n);
//从pos开始,到尾截断
void QByteArray::truncate(int pos);
//清空
void QByteArray::clear();

//替换字符串n before->after
QByteArray @QByteArray::replace(const QByteArray &before, const QByteArray &after);

查找判断

//包含ba/ch则返回true

bool QByteArray::contains(const ByteArray &ba) const;

bool QByteArray::contains(const char *ba) const;

bool QByteArray::contains(char ch) const;



//是否以ba/ch开始

bool QByteArray::startsWith(const ByteArray &ba) const;

bool QByteArray::startsWith(const char *ba) const;

bool QByteArray::startsWith( char ch) const;

//是否以ba/ch结尾

bool QByteArray::endsWith(const ByteArray &ba) const;

bool QByteArray::endsWith(const char *ba) const;

bool QByteArray::endsWith( char ch) const;

遍历

//迭代器
iterator QByteArray::begin();
iterator QByteArray::end();

//数组遍历
char QByteArray::at(int i) const;
char QByteArray::operator[](int i) const;

查字节数

int QByteArray::length() const;
int QByteArray::size() const;
int QByteArray::count() const;

//查ba次数
int QByteArray::count(const QByteArray &ba) const;
int QByteArray::count(const char *ba) const;
int QByteArray::count(char  ch) const;

类型转换

//QByteArray转换成char*
char *QByteArray::data();
const char *QByteArray::data() const;

//其他类型转换成QByteArray
QByteArray &QByteArray::setNum(int n, int base = 10);
QByteArray &QByteArray::setNum(short n, int base = 10);
QByteArray &QByteArray::setNum(qlonglong n, int base = 10);
QByteArray &QByteArray::setNum(float n, char f = 'g', int prec = 6);
QByteArray &QByteArray::setNum(double n, char f = 'g', int prec = 6);

//静态
[static] QByteArray &QByteArray::number(int n, int base = 10);
[static] QByteArray &QByteArray::number(qlonglong n, int base = 10);
[static] QByteArray &QByteArray::number(double n, char f = 'g', int prec = 6)

(2)QString

构造

//空c串
QString::QString();

//char*转换成QString
QString::QString(const char *str);

//QByteArray转换成QString
QString::QString(const QByteArray &ba);

运用

QString str = QString("(%1)有(%2)个徒弟").arg("唐僧").arg("3");
qDebug()<<"字符串的值:"<

显示

唐僧有3个徒弟

(3)区别

QString 一个汉字一个字符,内部utf-8编码

QByteArray 一个汉字3个字符,仍是char*

4、QVariant

标准类型包装

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    int value = dataPlus(10, 20).toInt();
    QString str = dataPlus("Hello", "World").toString();
    qDebug() << "int value: " << value;
    qDebug() << "string value: " << str;

}

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

QVariant MainWindow::dataPlus(QVariant a, QVariant b)
{
    QVariant ret;
    if (a.type() == QVariant::Int && b.type() == QVariant::Int)
    {
        ret = QVariant(a.toInt() + b.toInt());
    }
    else if (a.type() == QVariant::String && b.type() == QVariant::String)
    {
        ret.setValue(a.toString() + b.toString());
    }
    return ret;
}

int value: 30

string value: "HelloWorld"

自定义数据类型

struct Person{
    int id;
    QString name;
};    


Person p;
        p.id = 250;
        p.name = "张三丰";
#if 0
        QVariant v;
        v.setValue(p);
#else
        QVariant v = QVariant::fromValue(p);
#endif
        if(v.canConvert())
        {
            Person tmp = v.value();
            qDebug() << "id: " << tmp.id << ", name: " << tmp.name;
        }

}

结果

id: 250 , name: "张三丰"

5、QPoint 坐标类

构造、赋值、运算

QPoint::QPoint();
QPoint::QPoint(int x, int y);

//x
void QPoint::setX(int x);
//y
void QPoint::setY(int y);

//取x
int QPoint::x() const;
//取y
int QPoint::y() const;

//取x引用
int &QPoint::rx();
//取y引用
int &QPoint::rx();

//坐标运算
QPoint &QPoint::operator*=(float factor);
//*= += -= /=

6、QLine

直线类,封装xy

//构造
QLine::QLine();
//两点一直线
QLine::QLine(const QPoint &p1, const QPoint &p2);
QLine::QLine(int x1, int y1, int x2, int y2);

//设置坐标
void QLine::setPoints(const QPoint &p1, const QPoint &p2);
void QLine::setLine(int x1, int y1, int x2, int y2);
//起点、终点
void QLine::setP1(const QPoint &p1);
void QLine::setP2(const QPoint &p2);

//返回起点、终点
QPoint QLine::p1() const;
QPoint QLine::p2() const;

//平移
void QLine::translate(const QPoint &offset);
void QLine::translate(int dx, int dy);

//直线比较位置
bool QLine::operator!=(const QLine &line) const;
bool QLine::operator==(const QLine &line) const;

例子

   QLine line(QPoint(100, 200), QPoint(150, 210));
   QLine newLine = line.translated(20, 20);
   qDebug() << "平移之前的坐标点:" << line;
   qDebug() << "平移之后的坐标点:" << newLine;

平移之前的坐标点: QLine(QPoint(100,200),QPoint(150,210))

平移之后的坐标点: QLine(QPoint(120,220),QPoint(170,230))

7、QSize 长宽

QSize::QSize();
QSize::QSize(int width, int height);

void QSize::setWidth(int width);
void QSize::setheight(int height);

int QSize::width() const;
int &QSize::rwidth();
int QSize::height() const;
int &QSize::rheight();

//交换长宽
void QSize::transpose();
//并返回
QSize QSize::transposed() const;

//运算
QSize &QSize::operator*=(qreal factor);
//+= /= -=

8、QRect 矩形

QRect::QRect();
// 左上角,右下角
QRect::QRect(const QPoint &topLeft, const QPoint &bottomRight);
// 左上角,宽度, 高度
QRect::QRect(const QPoint &topLeft, const QSize &size);
// 通过 左上角坐标(x, y), 和 矩形尺寸(width, height) 
QRect::QRect(int x, int y, int width, int height);

// 尺寸信息, 左上角坐标不变
void QRect::setSize(const QSize &size);
// 左上角坐标为(x,y), 大小为(width, height)
void QRect::setRect(int x, int y, int width, int height);
// 矩宽
void QRect::setWidth(int width);
// 矩高
void QRect::setHeight(int height);

// 返回左上角坐标
QPoint QRect::topLeft() const;
// 返回右上角坐标
// 该坐标点值为: QPoint(left() + width() -1, top())
QPoint QRect::topRight() const;
// 返回左下角坐标
// 该坐标点值为: QPoint(left(), top() + height() - 1)
QPoint QRect::bottomLeft() const;
// 返回右下角坐标
// 该坐标点值为: QPoint(left() + width() -1, top() + height() - 1)
QPoint QRect::bottomRight() const;
// 返回中心点坐标
QPoint QRect::center() const;

// 返回上边缘y轴坐标
int QRect::top() const;
int QRect::y() const;
// 返回值下边缘y轴坐标
int QRect::bottom() const;
// 返回左边缘 x轴坐标
int QRect::x() const;
int QRect::left() const;
// 返回右边缘x轴坐标
int QRect::right() const;

// 返回高度
int QRect::width() const;
// 返回宽度
int QRect::height() const;
// 返回尺寸信息
QSize QRect::size() const;

9、QDate 日期时间

(1)QDate

QDate::QDate();
QDate::QDate(int y, int m, int d);

// 公共成员函数
// 重新设置日期对象中的日期
bool QDate::setDate(int year, int month, int day);
// 给日期对象添加 ndays 天
QDate QDate::addDays(qint64 ndays) const;
// 给日期对象添加 nmonths 月
QDate QDate::addMonths(int nmonths) const;
// 给日期对象添加 nyears 月
QDate QDate::addYears(int nyears) const;

// 得到日期对象中的年/月/日
int QDate::year() const;
int QDate::month() const;
int QDate::day() const;
void QDate::getDate(int *year, int *month, int *day) const;

// 日期对象格式化
/*
    d    - The day as a number without a leading zero (1 to 31)
    dd   - The day as a number with a leading zero (01 to 31)
    ddd	 - The abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses the system locale to localize the name, i.e. QLocale::system().
    dddd - The long localized day name (e.g. 'Monday' to 'Sunday'). Uses the system locale to localize the name, i.e. QLocale::system().
    M    - The month as a number without a leading zero (1 to 12)
    MM   - The month as a number with a leading zero (01 to 12)
    MMM	 - The abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses the system locale to localize the name, i.e. QLocale::system().
    MMMM - The long localized month name (e.g. 'January' to 'December'). Uses the system locale to localize the name, i.e. QLocale::system().
    yy   - The year as a two digit number (00 to 99)
    yyyy - The year as a four digit number. If the year is negative, a minus sign is prepended, making five characters.
*/
QString QDate::toString(const QString &format) const;

// 操作符重载 ==> 日期比较
bool QDate::operator!=(const QDate &d) const;
bool QDate::operator<(const QDate &d) const;
bool QDate::operator<=(const QDate &d) const;
bool QDate::operator==(const QDate &d) const;
bool QDate::operator>(const QDate &d) const;
bool QDate::operator>=(const QDate &d) const;

// 静态函数 -> 得到本地的当前日期
[static] QDate QDate::currentDate();

例子

QDate d = QDate::currentDate();
    qDebug() << "year: " << d.year() << ", moth: " << d.month() << ", day: " << d.day();
    QString str = d.toString("yyyy-MM-dd");
    qDebug() << "date str: " << str;

year: 2023 , moth: 8 , day: 7

date str: "2023-08-07"

(2)QTime 时分秒 毫秒

QTime::QTime();
/*
    h 		==> 取值范围: 0 ~ 23
    m and s 	==> 取值范围: 0 ~ 59
    ms 		==> 取值范围: 0 ~ 999
*/ 
QTime::QTime(int h, int m, int s = 0, int ms = 0);

// 公共成员函数
// Returns true if the set time is valid; otherwise returns false.
bool QTime::setHMS(int h, int m, int s, int ms = 0);
QTime QTime::addSecs(int s) const;
QTime QTime::addMSecs(int ms) const;

// 示例代码
  QTime n(14, 0, 0);                // n == 14:00:00
  QTime t;
  t = n.addSecs(70);                // t == 14:01:10
  t = n.addSecs(-70);               // t == 13:58:50
  t = n.addSecs(10 * 60 * 60 + 5);  // t == 00:00:05
  t = n.addSecs(-15 * 60 * 60);     // t == 23:00:00

// 从时间对象中取出 时/分/秒/毫秒
// Returns the hour part (0 to 23) of the time. Returns -1 if the time is invalid.
int QTime::hour() const;
// Returns the minute part (0 to 59) of the time. Returns -1 if the time is invalid.
int QTime::minute() const;
// Returns the second part (0 to 59) of the time. Returns -1 if the time is invalid.
int QTime::second() const;
// Returns the millisecond part (0 to 999) of the time. Returns -1 if the time is invalid.
int QTime::msec() const;


// 时间格式化
/*
    -- 时 --
    h	==>	The hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
    hh	==>	The hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
    H	==>	The hour without a leading zero (0 to 23, even with AM/PM display)
    HH	==>	The hour with a leading zero (00 to 23, even with AM/PM display)
    -- 分 --
    m	==>	The minute without a leading zero (0 to 59)
    mm	==>	The minute with a leading zero (00 to 59)
    -- 秒 --
    s	==>	The whole second, without any leading zero (0 to 59)
    ss	==>	The whole second, with a leading zero where applicable (00 to 59)
    -- 毫秒 --
    zzz	==>	The fractional part of the second, to millisecond precision, 
			including trailing zeroes where applicable (000 to 999).
    -- 上午或者下午
    AP or A	==>	使用AM/PM(大写) 描述上下午, 中文系统显示汉字
    ap or a	==>	使用am/pm(小写) 描述上下午, 中文系统显示汉字
*/
QString QTime::toString(const QString &format) const;

// 阶段性计时
// 过时的API函数
// 开始计时
void QTime::start();
// 计时结束
int QTime::elapsed() const;
// 重新计时
int QTime::restart();

// 推荐使用的API函数
// QElapsedTimer 类
void QElapsedTimer::start();
qint64 QElapsedTimer::restart();
qint64 QElapsedTimer::elapsed() const;


// 操作符重载 ==> 时间比较
bool QTime::operator!=(const QTime &t) const;
bool QTime::operator<(const QTime &t) const;
bool QTime::operator<=(const QTime &t) const;
bool QTime::operator==(const QTime &t) const;
bool QTime::operator>(const QTime &t) const;
bool QTime::operator>=(const QTime &t) const;

// 静态函数 -> 得到当前时间
[static] QTime QTime::currentTime();

例子 

 QDate d = QDate::currentDate();
    qDebug() << "year: " << d.year() << ", moth: " << d.month() << ", day: " << d.day();
    QString str = d.toString("yyyy-MM-dd");
    qDebug() << "date str: " << str;

   QTime curtime = QTime::currentTime();
   qDebug() << "hour: " << curtime.hour() << ", minute: " << curtime.minute() <<
               ", sec: " << curtime.second() << ", minsec: " << curtime.msec();

   QString strtm = curtime.toString("hh:mm:ss:zzz");
   qDebug() << "格式化的日期:" << strtm;

year: 2023 , moth: 8 , day: 7

date str: "2023-08-07"

hour: 21 , minute: 29 , sec: 12 , minsec: 844

格式化的日期: "21:29:12:844"

另外:生成随机数

QTime tt;
tt.start();
randNumbers(100);
int ms = tt.elapsed();
qDebug() << "函数执行所用的时间:" << ms << "毫秒";

void MainWindow::randNumbers(int count)
{
    srand(time(NULL));
    for(int i = 0; i < count; ++i)
    {
    int num = rand () % 10000;
    qDebug() << num;
    }
}

显示100个数

...

1814

4292

636

函数执行所用的时间: 7 毫秒

(3)QDateTime 日期时间

QDateTime::QDateTime();
QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec = Qt::LocalTime);

// 公共成员函数
// 设置日期
void QDateTime::setDate(const QDate &date);
// 设置时间
void QDateTime::setTime(const QTime &time);
// 给当前日期对象追加 年/月/日/秒/毫秒, 参数可以是负数
QDateTime QDateTime::addYears(int nyears) const;
QDateTime QDateTime::addMonths(int nmonths) const;
QDateTime QDateTime::addDays(qint64 ndays) const;
QDateTime QDateTime::addSecs(qint64 s) const;
QDateTime QDateTime::addMSecs(qint64 msecs) const;

// 得到对象中的日期
QDate QDateTime::date() const;
// 得到对象中的时间
QTime QDateTime::time() const;

// 日期和时间格式, 格式字符参考QDate 和 QTime 类的 toString() 函数
QString QDateTime::toString(const QString &format) const;


// 操作符重载 ==> 日期时间对象的比较
bool QDateTime::operator!=(const QDateTime &other) const;
bool QDateTime::operator<(const QDateTime &other) const;
bool QDateTime::operator<=(const QDateTime &other) const;
bool QDateTime::operator==(const QDateTime &other) const;
bool QDateTime::operator>(const QDateTime &other) const;
bool QDateTime::operator>=(const QDateTime &other) const;

// 静态函数
// 得到当前时区的日期和时间(本地设置的时区对应的日期和时间)
[static] QDateTime QDateTime::currentDateTime();

例子

QDateTime dt = QDateTime::currentDateTime();
    QString strdt = dt.toString("yy/MM/dd hh:mm:ss ap");
    qDebug() << "时间是:" << strdt;

时间是: "23/08/07 10:42:01 下午"

取时间

    QDate d = dt.date();
    qDebug() << "year: " << d.year() << ", moth: " << d.month() << ", day: " << d.day();

    QTime curtime = dt.time();
    qDebug() << "hour: " << curtime.hour() << ", minute: " << curtime.minute() <<
                ", sec: " << curtime.second() << ", minsec: " << curtime.msec();

year: 2023 , moth: 8 , day: 7

hour: 22 , minute: 46 , sec: 26 , minsec: 557

七、信号槽

1、基础

信号本质是 事件

信号是 类的成员函数

connect 关联

QMetaObject::Connection QObject::connect(
    	const QObject *sender, PointerToMemberFunction signal, 
        const QObject *receiver, PointerToMemberFunction method, 
		Qt::ConnectionType type = Qt::AutoConnection);

connect(const QObject *sender, &QObject::signal, 
        const QObject *receiver, &QObject::method);

查信号槽

Public Slots

Signals

关闭窗口

   connect( ui->clostBtn, &QPushButton::clicked, this, &MainWindow::close);
                //信号         信号发出者         接收者     执行的动作

QT 入门_第21张图片

 2、自定义信号槽

从QObject及其子类派生

加入Q_OBJECT  宏

返回值 void,支持重载

例子

女朋友饿了,我请她吃麻辣烫

写按钮,hungry(), Me(), 并connect

//girlfriend.h
#ifndef GIRLFRIEND_H
#define GIRLFRIEND_H

#include 

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

signals:
    void hungry();

};

#endif // GIRLFRIEND_H


//me.h
#ifndef ME_H
#define ME_H

#include 

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

public slots:
    void eat();

};

#endif // ME_H

//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include "me.h"
#include "girlfriend.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    void hungrySlot();
private:
    Ui::MainWindow *ui;

    Me* m_me;
    GirlFriend* m_girl;
};
#endif // MAINWINDOW_H


//girlfriend.cpp
#include "girlfriend.h"

GirlFriend::GirlFriend(QObject *parent) : QObject(parent)
{

}


//me.cpp
#include "me.h"
#include 
Me::Me(QObject *parent) : QObject(parent)
{

}

void Me::eat()
{
    qDebug() << "我带你去吃麻辣烫...";
}


//main.cpp
#include "mainwindow.h"

#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}


//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_me = new Me;
    m_girl = new GirlFriend;
    connect(m_girl, &GirlFriend::hungry, m_me, &Me::eat);
   connect(ui->hungry, &QPushButton::clicked, this, &MainWindow::hungrySlot);
   connect( ui->clostBtn, &QPushButton::clicked, this, &MainWindow::close);
}

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

void MainWindow::hungrySlot()
{
    emit m_girl->hungry();
}

mianwindow.ui

QT 入门_第22张图片

结果:不断点击hungry

我带你去吃麻辣烫...

我带你去吃麻辣烫...

我带你去吃麻辣烫...

我带你去吃麻辣烫...

3、拓展

一个信号可以连接多个槽函数

发一个信号有多个处理动作

例子

connect(m_girl, &GirlFriend::hungry, m_me, &Me::eat);
connect(m_girl, &GirlFriend::hungry, this, &MainWindow::eatSlot);
connect(ui->hungry, &QPushButton::clicked, m_girl, &GirlFriend::hungry);

void MainWindow::hungrySlot()
{
    emit m_girl->hungry();
}

void MainWindow::eatSlot()
{
    qDebug() << "我带你去吃海鲜...";
}

我带你去吃麻辣烫...

我带你去吃海鲜...

信号槽可以断开

disconnect(const QObject *sender, &QObject::signal, 
        const QObject *receiver, &QObject::method);

信号槽的连接方式

QT5

connect(m_girl, &GirlFriend::hungry, m_me, &Me::eat);
connect(m_girl, &GirlFriend::hungry, this, &MainWindow::eatSlot);
connect(ui->hungry, &QPushButton::clicked, m_girl, &GirlFriend::hungry);

QT4

connect(m_girl, SIGNAL(hungry()), m_me, SLOT(eat()));

八、lamda表达式

[capture](params) opt -> ret {body;};
    - capture: 捕获列表
    - params: 参数列表
    - opt: 函数选项
    - ret: 返回值类型
    - body: 函数体

例子

//匿名函数定义
[](){
       qDebug() << "hello, I am a lambda...";
   };
//匿名函数调用
[](){
       qDebug() << "hello, I am a lambda...";
   }();

[] - 不捕捉任何变量
[&] - 捕获外部作用域中所有变量, 并作为引用在函数体内使用 (按引用捕获)
[=] - 捕获外部作用域中所有变量, 并作为副本在函数体内使用 (按值捕获)
拷贝的副本在匿名函数体内部是只读的
[=, &foo] - 按值捕获外部作用域中所有变量, 并按照引用捕获外部变量 foo
[bar] - 按值捕获 bar 变量, 同时不捕获其他变量
[&bar] - 按引用捕获 bar 变量, 同时不捕获其他变量
[this] - 捕获当前类中的this指针
让lambda表达式拥有和当前类成员函数同样的访问权限
如果已经使用了 & 或者 =, 默认添加此选项

值引用

  qDebug() << "引用方式传递...";
  qDebug() << "a+1:" << a+1 << "b+a: " << b+a << "c+b: " << c+b;

引用方式传递...

a+1: 2 b+a: 3 c+b: 5

值拷贝,只读,不能写 需要加mutable

[=]()mutable{

值拷贝用外部数据

[=](int n, int m)mutable{
       qDebug() << "m+1: " << ++m << "n: " << n;
   }(1, 2);

m+1: 3 n: 1

实际在信号槽中使用

connect(ui->hungry, &QPushButton::clicked, this, [=](){
        m_girl->hungry();
    });

九、QTimer 定时器

// 如果指定了父对象, 创建的堆内存可以自动析构
QTimer::QTimer(QObject *parent = nullptr);

// 设置定时器时间间隔为 msec 毫秒
// 默认值是0,一旦窗口系统事件队列中的所有事件都已经被处理完,一个时间间隔为0的QTimer就会触发
void QTimer::setInterval(int msec);
// 获取定时器的时间间隔, 返回值单位: 毫秒
int QTimer::interval() const;

// 根据指定的时间间隔启动或者重启定时器, 需要调用 setInterval() 设置时间间隔
[slot] void QTimer::start();
// 启动或重新启动定时器,超时间隔为msec毫秒。
[slot] void QTimer::start(int msec);
// 停止定时器。
[slot] void QTimer::stop();

// 设置定时器精度
/*
参数: 
    - Qt::PreciseTimer -> 精确的精度, 毫秒级
    - Qt::CoarseTimer  -> 粗糙的精度, 和1毫秒的误差在5%的范围内, 默认精度
    - Qt::VeryCoarseTimer -> 非常粗糙的精度, 精度在1秒左右
*/
void QTimer::setTimerType(Qt::TimerType atype);
Qt::TimerType QTimer::timerType() const;	// 获取当前定时器的精度

// 如果定时器正在运行,返回true; 否则返回false。
bool QTimer::isActive() const;

// 判断定时器是否只触发一次
bool QTimer::isSingleShot() const;
// 设置定时器是否只触发一次, 参数为true定时器只触发一次, 为false定时器重复触发, 默认为false
void QTimer::setSingleShot(bool singleShot);

获取时间,一开一关

connect(ui->loopBin, &QPushButton::clicked, this, [=](){
        if (timer->isActive())
        {
            timer->stop();
            ui->loopBin->setText("开始");
        }
        else
        {
            ui->loopBin->setText("关闭");
         timer->start(1000);
        }

    });
    connect(timer, &QTimer::timeout, this, [=](){
        QTime tm = QTime::currentTime();
        QString tmstr = tm.toString("hh:mm:ss.zzz");
        ui->curTime->setText(tmstr);
    });

获取两秒后的时间

connect(ui->onceBtn, &QPushButton::clicked, this, [=](){
        QTimer::singleShot(2000,this,[=] (){
            QTime tm = QTime::currentTime();
            QString tmstr = tm.toString("hh:mm:ss.zzz");
            ui->onceTime->setText(tmstr);
        });
    });

十、资源文件

在pro有的路径下创建存放图片的文件夹,并且图片命名为非中文

QT 入门_第23张图片

并将需要加入的图片加入此文件夹

 创建资源夹

QT 入门_第24张图片

 输入路径前缀 /(或者其他)

并添加图片 add files

可以改别名

在左侧可以复制路径

QT 入门_第25张图片

 十一、布局

垂直、水平、网格

拖入左侧的layouts 选择想要的布局

QT 入门_第26张图片

 可以直接将插件拖入布局中

或者 拖入Widget 再将插件拖入 再选中右击 改变布局

QT 入门_第27张图片

 也可以选中后 点击以下来改变布局

QT 入门_第28张图片


参考

QT借鉴

你可能感兴趣的:(QT,c++,qt)