学习 QT 时候做的一些笔记
目录
- 目录
- 按钮常用控件 API
- QT 窗口体系
- 信号和槽
- 点击按钮关闭窗口
- 自定义信号和槽
- 当自定义信号和槽出现重载
- 无参信号和有参信号与槽连接
- Lambda 表达式
- 利用 Lambda 表达式实现点击按钮关闭窗口
- QMainWindow
- 菜单栏
- 工具栏
- 状态栏
- 标签控件
- 浮动窗口
- 核心部件
- 资源文件
- 对话框
- 话框分类:
- 标准对话框
- 其他标准对话框
- 界面布局
- 控件
- 按钮组
- QListWidget 列表容器
按钮常用控件 API
代码语言:javascript复制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 窗口体系
坐标体系:
- 以左上角为原点
- 对于嵌套窗口,其坐标是相对于父窗口来说的
信号和槽
点击按钮关闭窗口
代码语言:javascript复制// 参数1 信号的发送方 参数2 发送的信号(函数地址) 参数3 信号的接收方 参数4 处理的槽函数
connect(btn2, &QPushButton::clicked, this, &QWidget::close);
自定义信号和槽
- 自定义信号
- 写到 signals 下
- 返回值为 void
- 只需要声明,不需要实现
- 可以有参数,可以重载
- 自定义槽
- 写到 public slot 下
- 返回值为 void
- 需要声明,也需要实现
- 可以有参数,可以重载
teacher.h & teacher.cpp
代码语言:javascript复制#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
代码语言:javascript复制#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
代码语言:javascript复制#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*
无参信号和有参信号与槽连接
代码语言:javascript复制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 断开信号
// 信号和槽函数的参数 类型必须一一对应
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;}
();
/*
= 值传递 推荐使用值传递
& 引用传递
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 表达式实现点击按钮关闭窗口
代码语言:javascript复制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
菜单栏
代码语言:javascript复制// 菜单栏 最多有一个
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("粘贴");
工具栏
代码语言:javascript复制// 工具栏 可以有多个
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);
状态栏
代码语言:javascript复制// 状态栏 最多有一个
QStatusBar* stBar = statusBar();
setStatusBar(stBar);
标签控件
代码语言:javascript复制// 放标签控件 可以多个
QLabel* label_1 = new QLabel("提示信息", this);
stBar->addWidget(label_1);
QLabel* label_2 = new QLabel("右侧提示信息", this);
stBar->addPermanentWidget(label_2);
浮动窗口
代码语言:javascript复制// 铆接部件 浮动窗口 可以多个
QDockWidget* dockWidget = new QDockWidget("浮动窗口", this);
addDockWidget(Qt::BottomDockWidgetArea, dockWidget);
// 设置只允许上下停靠
dockWidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
核心部件
代码语言:javascript复制// 设置核心部件 最多有一个
QTextEdit* edit = new QTextEdit();
setCentralWidget(edit);
资源文件
- 将文件拷贝到项目位置下
- 右键项目 添加新文件 -> Qt -> Qt recourse File -> 给资源文件起名
- res 生成 res.qrc
- open in editor
- 添加前缀
- 添加文件
- 使用 “: 前缀名 文件名”
对话框
话框分类:
- 模态对话框 (不可以对其他窗口进行操作)
- 非模态对话框 (可以对其他窗口进行操作)
// 点击新建按钮新建一个对话框
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 类型,利用返回值判断用户选择
代码语言:javascript复制// 错误对话框
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", "警告");
其他标准对话框
- 颜色对话框
- 文件对话框
- 字体对话框
// 颜色对话框
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 一次性添加多个内容