学习QT时候做的一些笔记

目录

按钮常用控件API

1
2
3
4
5
6
7
8
9
10
11
12
QPushButton * btn = new QPushButton;
btn->setParent(this); // 设置父亲
btn->setText("Hello World"); // 设置文本

QPushButton* btn2 = new QPushButton("Hello World", this);
btn2->move(100, 100); // 设置位置

resize(800, 300); // 重置窗口大小

setFixedSize(800, 300); // 固定窗口大小

setWindowTitle("TEST"); // 设置窗口标题

QT窗口体系

坐标体系:

  • 以左上角为原点

  • 对于嵌套窗口,其坐标是相对于父窗口来说的

信号和槽

点击按钮关闭窗口

1
2
// 参数1 信号的发送方 参数2 发送的信号(函数地址) 参数3 信号的接收方 参数4 处理的槽函数
connect(btn2, &QPushButton::clicked, this, &QWidget::close);

自定义信号和槽

  • 自定义信号

    • 写到signals下
    • 返回值为void
    • 只需要声明, 不需要实现
    • 可以有参数, 可以重载
  • 自定义槽

    • 写到public slot下
    • 返回值为void
    • 需要声明, 也需要实现
    • 可以有参数, 可以重载

teacher.h & teacher.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
28
29
30
#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

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

signals:
// 自定义信号
// 返回值为void, 只需要声明, 不需要实现
// 可以有参数, 可以重载

void hungry();

public slots:
};

#endif // TEACHER_H

/*--------------------------------------------------------------*/
#include "teacher.h"

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

}

student.h & studemt.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
28
29
30
31
32
33
34
35
36
#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

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

signals:

public slots:
// 槽函数
// 返回值为void, 需要声明, 也需要实现
// 可以有参数, 可以发生重载

void treat();
};

#endif // STUDENT_H

/*--------------------------------------------------------------*/
#include "student.h"
#include <QDebug>

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

}

void Student::treat()
{
qDebug() << "请老师吃饭";
}

widget.h & widget.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "teacher.h"
#include "student.h"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
Q_OBJECT

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

private:
Ui::Widget *ui;

Teacher* t;
Student* s;

void classOver();
};
#endif // WIDGET_H

/*--------------------------------------------------------------*/
#include "widget.h"
#include "ui_widget.h"

// Teracher类
// Student类
// 下课后, 老师会触发一个信号, 饿了, 学生响应信号, 请吃饭

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

this->t = new Teacher(this);
this->s = new Student(this);

connect(t, &Teacher::hungry, s, &Student::treat);

classOver();
}

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

void Widget::classOver()
{
// 下课函数, 触发老师饿了的信号
emit t->hungry();
}

当自定义信号和槽出现重载

  • 利用函数指针 明确指向函数地址
    • void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;
    • void(Student:: *studentSlot)(QString) = &Student::treat;
  • QString转成char*
    • .toutf8() 转为QByteArray
    • .Data()转为Char*

无参信号和有参信号与槽连接

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->resize(600, 400);

this->t = new Teacher(this);
this->s = new Student(this);

QPushButton *btn_1 = new QPushButton("有参信号和槽连接", this);
QPushButton *btn_2 = new QPushButton("无参信号和槽连接", this);
btn_2->move(200,0);

// 有参信号和槽连接
void(Teacher:: *teacherSignal_1)(QString) = &Teacher::hungry;
void(Student:: *studentSlot_1)(QString) = &Student::treat;

connect(t, teacherSignal_1, s, studentSlot_1);
connect(btn_1, &QPushButton::clicked, this, &Widget::classOver);


// 无参信号和槽连接
void(Teacher:: *teacherSignal_2)(void) = &Teacher::hungry;
void(Student:: *studentSlot_2)(void) = &Student::treat;

connect(t, teacherSignal_2, s, studentSlot_2);
connect(btn_2, &QPushButton::clicked, t, teacherSignal_2);

// disconnect断开信号
// disconnect(btn_2, &QPushButton::clicked, t, teacherSignal_2);
}

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

void Widget::classOver()
{
// 下课函数, 触发老师饿了的信号
emit t->hungry("shit");
}

扩展

  • 信号是可以连接信号的
  • 一个信号可以连接多个槽函数
  • 多个信号 可以连接 同一个槽函数
  • 信号和槽函数的参数 类型必须一一对应
  • 信号的参数个数 可以多于槽函数的参数个数
  • disconnect断开信号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 信号和槽函数的参数 类型必须一一对应
void(Teacher:: *teacherSignal_1)(int) = &Teacher::hungry;
void(Student:: *studentSlot_1)(int) = &Student::treat;

// 一个信号可以连接多个槽函数
QPushButton *btn_3 = new QPushButton("同时与槽连接", this);
btn_3->move(0, 50);
connect(btn_3, &QPushButton::clicked, this, &Widget::classOver);
connect(btn_3, &QPushButton::clicked, t, teacherSignal_2);

// 信号的参数个数 可以多于槽函数的参数个数
void(Teacher:: *teacherSignal_1)(QString, int) = &Teacher::hungry;
void(Student:: *studentSlot_1)(QString) = &Student::treat;

// disconnect断开信号
disconnect(btn_2, &QPushButton::clicked, t, teacherSignal_2);

Lambda表达式

[](){}

  • 函数对象参数 [ ]
    • = 值传递 推荐使用值传递
    • & 引用传递
    • this
    • a 按a值传递, 即只能看到a
    • a, &b 将a按值传递, b按引用传递
    • =, &a, &b 除a和b按引用进行传递外, 其他参数都按值传递
    • &, a, b 除a和b按值进行传递外, 其他参数都按引用传递
  • 操作符重载函数参数 ( )
    • 参数可以通过按值(如: (a, b))和按引用(如: (&a, &b))两种方式传递
  • 可修改标示符
    • mutable声明,加上mutable修饰符后,可以修改按值传递进来的拷贝(修改的是拷贝,不是本体)
  • 函数返回值
    • int ret = []()->int{return 100;}();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
= 值传递 推荐使用值传递
& 引用传递
this
a 按a值传递, 即只能看到a
a, &b 将a按值传递, b按引用传递
=, &a, &b 除a和b按引用进行传递外, 其他参数都按值传递
&, a, b 除a和b按值进行传递外, 其他参数都按引用传递
*/

[=](){
bin->setText("aaaa");
}(); // 值传递和引用传递都可以修改成功, ();是函数调用, 前面是函数声明

QPushButton *btn_1 = new QPushButton(this);
QPushButton *btn_2 = new QPushButton(this);
btn_2->move(100, 0);
int m = 10;

// 输出110, 不加mutable会报错, 但是修改的是m的拷贝, 不是本体
connect(btn_1, &QPushButton::clicked, this, [m]()mutable{m = 100 + 10; qDebug() << m;});
connect(btn_2, &QPushButton::clicked, this, [=](){qDebug() << m;}}); // 输出10

利用Lambda表达式实现点击按钮关闭窗口

1
2
3
4
5
6
7
8
9
QPushButton *btn_1 = new QPushButton("关闭", this);
connect(btn_1, &QPushButton::clicked, this, [](){
this->close();
});

QPushButton *btn_2 = new QPushButton("关闭", this);
connect(btn_2, &QPushButton::clicked, this, [=](){
emit t->treat("屎");
});

QMainWindow

菜单栏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 菜单栏 最多有一个
QMenuBar* bar = menuBar();
setMenuBar(bar);

// 创建菜单栏
QMenu* fileMenu = bar->addMenu("文件");
QMenu* editMenu = bar->addMenu("编辑");

// 创建菜单项
QAction* newAction = fileMenu->addAction("新建");
// 添加分隔线
fileMenu->addSeparator();
QAction* openAction = fileMenu->addAction("打开");
QAction* pasteAction = editMenu->addAction("粘贴");

工具栏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 工具栏 可以有多个
QToolBar* toolBar = new QToolBar(this);
addToolBar(Qt::BottomToolBarArea, toolBar); // 默认左右停靠

// 设置只允许左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);

// 设置浮动
toolBar->setFloatable(false);

// 设置移动 总开关
toolBar->setMovable(false);

// 工具栏中设置内容
toolBar->addAction(newAction);
toolBar->addSeparator();
toolBar->addAction(openAction);

状态栏

1
2
3
// 状态栏 最多有一个
QStatusBar* stBar = statusBar();
setStatusBar(stBar);

标签控件

1
2
3
4
5
6
// 放标签控件 可以多个
QLabel* label_1 = new QLabel("提示信息", this);
stBar->addWidget(label_1);

QLabel* label_2 = new QLabel("右侧提示信息", this);
stBar->addPermanentWidget(label_2);

浮动窗口

1
2
3
4
5
// 铆接部件 浮动窗口 可以多个
QDockWidget* dockWidget = new QDockWidget("浮动窗口", this);
addDockWidget(Qt::BottomDockWidgetArea, dockWidget);
// 设置只允许上下停靠
dockWidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);

核心部件

1
2
3
// 设置核心部件 最多有一个
QTextEdit* edit = new QTextEdit();
setCentralWidget(edit);

资源文件

  • 将文件拷贝到项目位置下
  • 右键项目 添加新文件 -> Qt -> Qt recourse File -> 给资源文件起名
  • res生成res.qrc
  • open in editor
  • 添加前缀
  • 添加文件
  • 使用 “:+ 前缀名 + 文件名”

对话框

话框分类:

  • 模态对话框(不可以对其他窗口进行操作)
  • 非模态对话框(可以对其他窗口进行操作)
1
2
3
4
5
6
7
8
9
10
11
12
13
// 点击新建按钮新建一个对话框
connect(ui->actionnew, &QAction::triggered, [=](){
// 模态对话框创建
QDialog dlg_1(this);
dlg_1.resize(200,100);
dlg_1.exec();

// 非模态对话框创建
QDialog *dlg_2 = new QDialog(this);
dlg_2->resize(500,200);
dlg_2->show();
dlg_2->setAttribute(Qt::WA_DeleteOnClose); // 关闭的时候就释放
});

标准对话框

  • 错误对话框
  • 信息对话框
  • 提问对话框
  • 警告对话框
参数1参数2参数3参数4参数5
父类标题显示内容按键类型默认关联回车按键

返回值:也是StandardButton类型,利用返回值判断用户选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 错误对话框
QMessageBox::critical(this, "critical", "错误");

// 信息对话框
QMessageBox::information(this, "info", "信息");

// 提问对话框
// 参数1 父类 参数2 标题 参数3 提示内容 参数4 按键类型 参数5 默认关联回车按键
if(QMessageBox::Save == QMessageBox::question\
(this, "ques", "提问", QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel))
{
qDebug() << "选择的是保存";
}
else
{
qDebug() << "选择的是取消";
}

// 警告对话框
QMessageBox::warning(this, "warning", "警告");

其他标准对话框

  • 颜色对话框
  • 文件对话框
  • 字体对话框
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 颜色对话框
QColor color = QColorDialog::getColor(QColor(255,0,0));
qDebug() << color.red() << color.green() << color.blue();

// 文件对话框
// 参数1 父类 参数2 标题 参数3 默认打开路径 参数4 过滤文件格式
// 返回值为打开文件的路径
QString str = QFileDialog::getOpenFileName(this, "打开文件", "C:\\Users\\17740\\Desktop\\", "(*.txt)");
qDebug() << str;

// 字体对话框
bool flag;
QFont font = QFontDialog::getFont(&flag, QFont("微软雅黑", 20));
qDebug() << font.family().toUtf8().data() << font.pointSize() << font.bold() << font.italic();

界面布局

  • 实现登录窗口
  • 利用布局方式 给窗口进行美化
  • 选取widget 进行布局 水平布局、垂直布局、栅格布局
  • 给用户名、密码、登录、退出按钮进行布局
  • 默认窗口和控件之间有间隙,可以调整 layout
  • 利用弹簧进行布局

控件

按钮组

  • QPushBotton 常用按钮
  • QToolButton 工具按钮 用于显示图片,如果想显示文字,修改风格:toolButtonStyle,透明风格autoRaise
  • radioButton 单选按钮,设置默认 ui->rBtnMan->setChecked(true);
  • checkbox多选按钮,监听状态,0未选中,1半选中,2选中

QListWidget列表容器

  • QListWidget* item = new QListWidgetItem(“hello”);
  • ui->listWidget->addItem(item);
  • 设置居中方式 item->setTextAlignment(Qt::AlignHCenter);
  • 可以利用addItems一次性添加多个内容