QT学习记录
Ifo:对于网络或者图书中收集的QT开发的学习笔记汇总整理
前言
提示:主要是收集和汇总:
平台:QtCreator;语言Qt5;系统:Ubuntu。
一、QT基础
说明:QT语法与部件的基本说明。
1. QT平台基础
1.1 新项目框架说明
1.1.1 .pro文件
.pro文件说明,摘自新建
#模块,当用到一个类的时候,有时候不单单需要包含它的头文件
#也有可能需要添加相应的模块,这个时候就需要去相应的帮助文档中去查看
QT += core gui #添加了 Qt的支持的模块, core与 gui库是 Qt的默认设置
#高于QT4版本,添加QT += widgets是为了兼容Qt4;
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
#,比较 Qt5版本,如果是 Qt5版本, 在 main.cpp中 application是在 QtWidgets中的,因此要包含这个库
CONFIG += c++11 #分别配置的是使用c++11
DEFINES += QT_DEPRECATED_WARNINGS #添加 QT_DEPRECATED_WARNINGS定义。
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
qnx: target.path = /tmp/$${TARGET}/bin #判断操作系统
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target #判断target.path为空目录,
RESOURCES += \
res.qrc
1.1.2 .h头文件
.h文件说明,摘自新建项目
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTextBrowser>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; } //这里的MainWindow,和下面的不是一个对象、对应19行的*ui
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT //是一个宏,由QT进行处理,所有信号的类都需要添加这个宏
public:
MainWindow(QWidget *parent = nullptr); //构造函数
~MainWindow();
private slots:
void on_pushButton_clicked(); //在头文件中声明类 槽函数;自动生成的
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
private:
Ui::MainWindow *ui; //Ui::MainWindow的指针,为了使用.ui文件设计界面
//_____27___________
QTextBrowser *textBrowser;
QAction *openAction;
private slots:
void openActionTriggered();
};
#endif // MAINWINDOW_H
1.1.3 .cpp源文件
文件说明,摘自新建项目
#include "mainwindow.h"
#include "ui_mainwindow.h" //Qt根据.ui文件自动生成
//_____27___________
#include <QFileDialog>
#include <QTextStream>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow) //构造函数中逗号隔开,一种初始化成员的方法
{
ui->setupUi(this); //进行界面初始化
/*将this(MainWindow类本身)作为setupUi参数,里, ui界面文件的对象会以 this为父对象,所有子对象都将显示在
MainWindow里 。 我们要想使用 ui里的对象,必须将代码写在 ui-->setupUi(this)这句话之后,因
为 ui-->setupUi(this)会先初始化里面的对象,只有初始化里面的对象我们才能使用这个对象。*/
//_____27___________
this->setWindowTitle("文本浏览器");
textBrowser = new QTextBrowser(this);
//居中
this->setCentralWidget(textBrowser);
openAction = new QAction("打开",this);
/*ui自带菜单、工具、状态,menuBar生成ui就有,可在ui设计删除*/
//将动作添加的菜单
ui->menubar->addAction(openAction);
connect(openAction,SIGNAL(triggered(bool)),
this,SLOT(openActionTriggered()));
}
MainWindow::~MainWindow()
{
//析构函数
delete ui; //在析构函数里,delete的对象一般是new创建的,并且没有父对象的对象
//this在成员函数的开始执行前构造,在成员的执行结束后消除
}
void MainWindow::on_pushButton_clicked()
{
//根据头文件槽函数的声明,编辑函数内容
this->close();
}
1.1.4 main .cpp 主函数文件
文件说明,摘自新建项目
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
//Main函数把控制交给Qt库之前,执行初始化,Qt库通过事件来向程序告知用户行为
{
QApplication a(argc, argv); //argv是命令行变量的数组
MainWindow w;
w.show(); //显示程序界面
return a.exec(); //main把控制交给qt,,并且当应用程序退出的时候 exec()就会返回。
//在exec()中, Qt接受并处理用户和系统的事件并且把它们传递给适当的窗口部件。
}
1.2 样式编辑
1.2.1 字体
Front设置
QFont font;
font.setFamily("华文行楷");
font.setPointSize(20);
font.setBold(true);
font.setItalic(true);
2. QT部件基础
2.1 基本元件
2.1.1 QLabel
可以用来显示文本、图片、Gif动画
显示文本
labelText->setText("123");
//设置字体
m_label->setFont(font);
文本过长,显示省略
QFontMetrics fontWidth(m_label->font());
QString elideNote = fontWidth.elidedText(info, Qt::ElideRight, 150);
m_label->setText(elideNote);
m_label->setToolTip(info);
显示图片
//设置图片
labelImage->setPixmap(QPixmap("://Image/1.jpg"));
//让图片自适应Label大小
labelImage->setScaledContents(true);
>示例
QPixmap *pixmap = new QPixmap(":/images/welcome_tlauto.png");
pixmap->scaled(ui->label->size(), Qt::KeepAspectRatio);
ui->label->setScaledContents(true);
ui->label->setPixmap(*pixmap);
>显示动画
```cpp
//创建动画
QMovie* myMovie = new QMovie("://Image/6.gif");
//设置动画
labelGif->setMovie(myMovie);
//动画自适应
labelGif->setScaledContents(true);
//启动动画
myMovie->start();
2.1.2 按钮
改变按钮位置
pBtn1->move(100,100); //更改按钮在窗口上的位置
3. 信号与槽
3.1 基本说明
信号与槽之间的关联:是用 QObject::connect() 函数实现的,其基本格式是:
QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
//信号发出者,处理的信号, 信号接收者,处理动作方法(槽函数)
槽函数需要和信号一致(参数列表,返回值)如果信号没有返回值,槽函数一定没有返回值。
3.1.1 信号
- 信号没有返回值,但可以有参数
- 信号就是函数的声明,只需要声明,无需定义
- 使用 emit mySignal
- 信号可以重载
void mySignal(); //无参数的信号
void mySignal(int, QString); //有参数的信号
//信号重载,发送不同内容
emit mySignal();
emit mySignal(100, "我是子窗口");
3.1.2 槽函数
槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;
自定义槽函数:
1.QT5:任意的成员函数,普通的全局函数,静态函数
2.信号函数是没有返回值的,所以槽函数一定也没有返回值
3.一般在QT5中都是使用成员函数作为槽函数
3.1.3 emit
emit 是Qt关键字,像其他关Qt扩展一样,它也会被C++预处理器转换成标准的C++代码。
含义是发出信号。接收者关注这个信号,可能还需要知道是哪份报纸发出的信号?所以,我们将实际的报纸名字m_name当做参数传给这个信号。当接收者连接这个信号时,就可以通过槽函数获得实际值。这样就完成了数据从发出者到接收者的一个转移。
public:
Newspaper(const QString & name) :
m_name(name)
{
}
void send()
{
emit newPaper(m_name);
}
signals:
void newPaper(const QString &name);
private:
QString m_name;
使用 emit 在恰当的位置发送信号;
3.2 具体使用
3.2.1 基本使用
使用Qt本身的信号和槽
//标准信号与槽函数的使用
connect(pBtn1, &QPushButton::pressed, this, &MyWidget::close);
/*pBtn1:信号发出者,为指针类型
*&QPushButton::pressed 信号函数; &发送者的类名:信号名字
*this:信号的接收者
*&Widget::close 槽函数,信号处理函数; &接受的类名::槽函数名称
*/
3.2.2 多个信号绑定一个槽
包含多个按钮,每个按钮都创建一个槽函数,这样会这代码看起来比较冗杂,我们可以让多个按钮共用一个槽函数,然后去执行不同的功能。
通过setObjectName(),定义button处先设置ObjectName,在槽函数中判断按钮的名称。然后根据按钮的名称从而实现不同的功能模块
多个按钮绑定一个槽函数
4. 布局
4.1 窗体布局
4.1.1 QFormLayout
用来管理表单的输入部件以及与它们相关的标签,窗体布局管理器将它的子部件分为两列,左边是一些标签,右边是一些输入部件。
登陆界面
QLineEdit *pUserEdit = new QLineEdit(this);
QLineEdit *pPasswordEdit = new QLineEdit(this);
QLineEdit *pVerifyLineEdit = new QLineEdit(this);
QFormLayout *pLayout = new QFormLayout(this);
pLayout->addRow("用户名:", pUserEdit);
pLayout->addRow("密码:", pPasswordEdit);
pLayout->addRow("验证码:", pVerifyLineEdit);
//间隔
pLayout->setSpacing(10);
//边距
pLayout->setMargin(10);
4.1.2 格栅布局(QGridLayout)
将子部件按照网格方式排列
网格布局 | 每个子部件占据一个单元格 | |
---|---|---|
添加子部件 | addWidget() | 指定子部件行和列,可跨多个行或列 |
对齐方式 | setAlignment() | 指定左对齐、右对齐、居中等 |
弹性空间 | setRowStretch()、setColumnStretch() | 分配额外的空间或者平均分配剩余空间 |
跨越多个单元格 | setSpan() | 占据多个单元格的大型部件或自定义布局非常有用 |
嵌套布局 | 以将QGridLayout嵌套其他布局中,或将其他布局嵌套在QGridLayout中 |
应用举例
/* 图片在第0行,从第0行开始,占3行1列 */
pLayout->addWidget(m_pImageLabel, 0, 0, 3, 1);
/* 用户输入框第0行,从第1列开始,占1行2列 */
pLayout->addWidget(m_pUserEdit, 0, 1, 1, 2);
pLayout->addWidget(m_pRegisterButton, 0, 4);
/* 密码输入框第1行,从第1行开始,占1行2列 */
pLayout->addWidget(m_pPasswordEdit, 1, 1, 1, 2);
pLayout->addWidget(m_pForgotButton, 1, 4);
/* 记住密码 第2行,第1列开始,占1行1列 水平居左,垂直居中 */
pLayout->addWidget(m_pRemberCheck, 2, 1, 1, 1, Qt::AlignLeft | Qt::AlignVCenter);
/* 自动等罗 第2行,从第2列开始,占1行1列,水平居左,垂直居中 */
pLayout->addWidget(m_pAutoLoginCheck, 2, 2, 1, 1, Qt::AlignLeft | Qt::AlignVCenter);
/* 登陆按钮 第3行,第1列开始,占1行2列 */
pLayout->addWidget(m_pLoginButton, 3, 1, 1, 2);
/* 设置水平间距 */
pLayout->setHorizontalSpacing(10);
/* 设置垂直间距 */
pLayout->setVerticalSpacing(10);
/* 设置外间距 */
pLayout->setContentsMargins(10, 10, 10, 10);
效果图
4.1.3 水平布局(QHBoxLayout)
水平布局 | 水平从左到右布局,自动调整位置和大小 | |
---|---|---|
添加子部件 | addWidget()函数 | |
弹性空间 | addStretch() | 分配额外的空间或者平均分配剩余空间 |
对齐方式 | setAlignment() | 左对齐、右对齐、居中等 |
嵌套布局 | 可以与其他布局管理器一起使用 |
常用函数
控件之间的间距 | void QBoxLayout::setSpacing(int spacing) |
---|---|
左、上、右、下的外边距 | void QLayout::setContentsMargins(int left, int top, int right, int bottom) |
伸缩空间 | void QBoxLayout::addStretch(int stretch = 0) |
对齐Qt::Alignment alignment = Qt::Alignment()) | Qt::AlignLeft 、Qt::AlignTop、Qt::AlignBottom |
布局方向 | void QBoxLayout::setDirection(QBoxLayout::Direction direction) |
QBoxLayout::RightToLeft | QBoxLayout::TopToBottom |
4.1.4 堆栈布局(QStackedLayout)
用于管理多个子窗口或页面的堆叠显示,与 QStackedWidget 类似,但 QStackedLayout 是一个布局管理器,可以与其他布局管理器一起使用。
添加到堆叠布局 | addWidget(page1) |
---|---|
指定索引位置插入 | insertWidget(1, page3) |
设置当前显示的子窗口的索引 | currentIndex() |
获取堆叠布局中子窗口的数量 | count |
设置当前显示的子窗口 | setCurrentWidget(page2) |
获取当前显示的子窗口的指针 | currentWidget() |
切换到下一个或上一个子窗口,带有滑动效果 | slideInNext()、slideInPrev() |
4.2 窗口
4.2.1 窗口常用属性
一、**setAttribute()**函数,设置窗体的一些属性
二、**setWindowFlag()**函数,设置窗体标记
三、setWindowState()函数,使窗口处于最小化、最大化
四、setWindowModality()函数,设置窗口的模态
五、setWindowOpacity()函数,设置窗口的透明度
参数level是1.0(完全不透明)至(完全透明)之间的数
4.2.2 堆栈窗口(QStackedWidget)
通过连接 currentChanged 信号,你还可以监测子窗口的切换事件,通过切换页面的方式,如设置当前页或使用动画效果
添加 | addWidget(page1) |
---|---|
移除 | removeWidget(page1) |
设置当前显示 | setCurrentIndex(1) |
获取当前显示索引 | currentIndex() |
子窗口的数量 | count() |
切换时触发的信号 | currentChanged |
获取当前显示的子窗口的指针 | QWidget *currentPage = stackedWidget->currentWidget() |
下一个或上一个 | slideInNext()、slideInPrev() |
void MainWindow::onPrevButtonClicked()
{
int nextPage = (m_pStackedWidget->currentIndex() + 1) % m_pStackedWidget->count();
m_pStackedWidget->setCurrentIndex(nextPage);
}
void MainWindow::onNextButtonClicked()
{
int prevPage = (m_pStackedWidget->currentIndex() - 1 + m_pStackedWidget->count()) % m_pStackedWidget->count();
m_pStackedWidget->setCurrentIndex(prevPage);
}
4.2.3 停靠窗口(QDockWidget)
停靠功能、浮动窗口、可关闭、自定义部件
4.2.4 分裂器(QSplitter)
- 可拖动分隔器:用户可以通过拖动分隔器来动态调整子控件的大小
- 嵌套使用:你可以嵌套多个 QSplitter 以创建复杂的布局
4.3 容器
- 用于存储指定类型的数据项
- 作为只读容器时可被多个线程访问
- 分为顺序容器和关联容器
- 提供了foreach宏用于遍历容器内的所有数据项
4.3.1 顺序类容器
顺序容器类有QList、QLinkedList、QVector、QStack和QQueue
- QList容器
用于存储和管理元素的动态数组,高效的动态大小调整功能,支持插入、删除、查找和遍历元素。
创建,添加
QList<QString> myList;
myList.append("Apple");
myList.append("Banana");
查找
int iIndex = myList.indexOf("Apple");
if (iIndex != -1) {
qDebug() << "Found at index:" << iIndex;
} else {
qDebug() << "not found";
}
插入和删除元素
myList.insert(1, "Orange");
myList.removeAt(2);
myList.removeOne("Cherry");
遍历容器元素
//使用at()函数遍历元素
for (int i = 0; i < myList.size(); i++) {
//qDebug() << myList[i];
qDebug() << myList.at(i);
}
//使用迭代器遍历元素
QList<QString>::iterator it;
for (it = myList.begin(); it != myList.end(); ++it) {
qDebug() << *it;
}
//使用range-based for 循环遍历元素(C++11及更高版本)
for (const QString &item : myList) {
qDebug() << item;
}
4.4 标准对话框
4.4.1 QFileDialog对话框
1、QFileDialog::getOpenFileName()函数,选择打开一个文件,函数返回的是选择文件的带路径的完整文件名,取消选择,则返回字符串为空
参数:
1、对话框标题,
2、初始化目录:打开对话框时的初始目录
3、文件过滤器:选择不同后缀,可以设置多组,如: QString filter = “文本文件(.txt);;图片文件(.jpg .gif);;所有文件(.*)”;每组文件之间用两个分号隔开,同一组内不同后缀之间用空格隔开
void MainWindow::on_btn_clicked()
{
QString curPath = QDir::currentPath(); //获取应用程序当前目录
QString dlgTitle = "选择一个文件";
QString filter = "文本文件(*.txt);;图片文件(*.jpg *.gif);;所有文件(*.*)";
QString fileName = QFileDialog::getOpenFileName(this, dlgTitle, curPath, filter);
if (!fileName.isEmpty()) {
qDebug() << "fileName:" << fileName;
}
}
2、QFileDialog::getOpenFileNames()函数,选择打开多个文件,返回值是一个字符串列表,列表的每一行是选择的一个文件
3、QFileDialog()::getExistingDirectory()函数,选择已有目录;一般使用QFileDialog::ShowDirsOnly,表示对话框中只显示目录
4、QFileDialog::getSaveFileName() ,选择保存文件名,已经存在的文件,会提示是否覆盖
4.4.2 QColorDialog对话框
QColorDialog::getColor(),选择颜色对话框,需要一个初始颜色,返回颜色变量,若取消选择,返回无效,通过QColor::isValid()函数来判断返回
void MainWindow::on_btn_clicked()
{
QPalette pal = m_pTextEdit->palette(); //获取现有palette
QColor iniColor = pal.color(QPalette::Text); //现有的文字颜色
QColor color = QColorDialog::getColor(iniColor, this, "选择颜色");
if (color.isValid()) {
pal.setColor(QPalette::Text, color);
m_pTextEdit->setPalette(pal);
}
4.4.3 QFontDialog对话框
QFontDialog::getFont(),选择字体,设置包括名称、大小、粗体、斜体等
4.4.4 QInputDialog标准输入对话框 √
有单行字符串输入、整数输入、浮点数输入、列表框选择输入和多行文本等多种输入方式。
1、输入文字:QInputDialog::getText()
显示一个对话框用于输入字符串,传递参数:对话框标题、提示标签文件、缺省输入、编辑框响应模式等。
void MainWindow::on_btn_clicked()
{
QString dlgTitle = "输入文字对话框";
QString txtLabel = "请输入文件名";
QString defaultInput = "新建文件.txt";
QLineEdit::EchoMode echoMode = QLineEdit::Normal;
bool isValid = false;
QString text = QInputDialog::getText(this, dlgTitle, txtLabel, echoMode, defaultInput, &isValid);
if (isValid) {
m_pTextEdit->appendPlainText(text);
}
}
2、输入整数:QInputDialog::getInt()
使用一个SpinBox组件输入整数,getInt()需要传递的参数包括数值大小范围、步长、初始值;确认选择输入后,将输入的整数值作为文本框字体的大小。
void MainWindow::on_btn_clicked()
{
QString dlgTitle = "输入文字对话框";
QString txtLabel = "设置字体大小";
int defaultValue = m_pTextEdit->font().pointSize();
int minValue = 6, maxValue = 50, stepValue = 1;
bool isValid = false;
int inputValue = QInputDialog::getInt(this, dlgTitle, txtLabel, defaultValue, minValue, maxValue, stepValue, &isValid);
if (isValid) {
QFont font = m_pTextEdit->font();
font.setPointSize(inputValue);
m_pTextEdit->setFont(font);
}
}
3、输入浮点数:QInputDialog::getDouble()
输入对话框使用一个QDoubleSpinBox作为输入组件,getDouble()的输入参数需要输入范围、初始值、小数点位数等。
void MainWindow::on_btn_clicked()
{
QString dlgTitle = "输入文字对话框";
QString txtLabel = "输入一个浮点数";
float defaultValue = 3.13;
float minValue = 0, maxValue = 1000;
int decimals = 2; //小数点位数
bool isValid = false;
float inputValue = QInputDialog::getDouble(this, dlgTitle, txtLabel, defaultValue, minValue, maxValue, decimals, &isValid);
if (isValid) {
QString str = QString::asprintf("输入了一个浮点数:%.2f", inputValue);
m_pTextEdit->appendPlainText(str);
}
}
4、下拉列表选择输入QInputDialog::getIntem()
可以从一个ComboBox组件的下拉列表中选择输入。需要一个QStringList变量为其ComboBox组件条目初始化,curIndex指明初始化选择项,editable表示对话框的ComboBox是否可编辑,若不能编辑,则只能在下拉列表中选择。
void MainWindow::on_btn_clicked()
{
QStringList items;
items << "优秀" << "良好" << "合格" << "不合格";
QString dlgTitle = "条目选择对话框";
QString txtLabel = "请选择级别";
int curIndex = 0; //初始选择项
bool editable = true; //ComboBox是否看编辑
bool isValid = false;
QString text = QInputDialog::getItem(this, dlgTitle, txtLabel, items, curIndex, editable, &isValid);
if (isValid && !text.isEmpty()) {
m_pTextEdit->appendPlainText(text);
}
}
4.5 QMessageBox √
4.5.1 QMessageBox::information
创建信息对话框,接受几个参数来配置对话框的内容和行为,并且通常以模态方式显示对话框,阻塞程序的执行,直到用户关闭对话框。
参数说明:
- parent:指定对话框的父窗口。如果为 nullptr,则对话框没有父窗口。
- title:对话框的标题,通常是一个字符串。
- text:对话框中要显示的信息文本,通常也是一个字符串。
- buttons:指定对话框中显示的标准按钮,它是一个枚举值,可以根据需要选择不同的按钮组合。默认情况下,它是 QMessageBox::Ok,表示只有一个“确定”按钮。你可以使用位掩码将多个按钮组合在一起,例如 QMessageBox::Ok |QMessageBox::Cancel。
- defaultButton:指定默认选中的按钮,通常是一个标准按钮。默认是QMessageBox::NoButton,表示没有默认按钮。
void MainWindow::on_btn_clicked_info()
{
QMessageBox::StandardButton button = QMessageBox::information(nullptr, "information", "是否退出窗口",
QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton);
if (button == QMessageBox::StandardButton::Yes) {
qDebug() << "QMessageBox::StandardButton::Yes";
} else if (button == QMessageBox::StandardButton::No) {
qDebug() << "QMessageBox::StandardButton::No";
}
}
4.5.2 QMessageBox::critical
创建一个临界错误对话框,向用户显示错误并要求用户采取行动。以不同的图标和按钮组合显示,以强调错误的重要性。
4.5.3 QMessageBox::warning
创建一个警告对话框,向用户显示警告。
4.5.4 QMessageBox::question
创建一个询问对话框,通常用于向用户提出一个问题,以便用户可以选择“是”或“否”的答案。
4.5.5 QMessageBox::about
创建一个关于对话框,通常用于向用户显示应用程序的信息、版本号和作者等相关信息。
4.5.5 QMessageBox::exec
exec 函数没有直接的参数,因为它是在创建 QMessageBox 对象后使用的。首先,你需要创建一个 QMessageBox 对象并设置其属性,然后调用 exec 函数来显示对话框,并等待用户响应。
5. 事件
5.1 事件系统
5.1.1 事件种类
事件作为一个对象,继承自QEvent类
键盘事件 | QKeyEvent |
---|---|
鼠标事件 | QMouseEvent |
定时器事件 | QTimerEvent |
滚轮事件 | QWheelEvent |
事件传递顺序
//声明重写事件
void keyPressEvent(QKeyEvent *event) override;
//编写内容
void MyLineEdit::keyPressEvent(QKeyEvent *event)
{
}
//event()函数使用
if (event->type() == QEvent::KeyPress) {
}
//重写eventFilter()
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == m_pLineEdit) {
if (event->type() == QEvent::KeyPress) {
qDebug() << "Widget的事件过滤器";
}
}
return QMainWindow::eventFilter(obj, event);
}
5.1.2 鼠标事件
事件重写
//点击
virtual void mousePressEvent(QMouseEvent *event) override;
//释放
virtual void mouseReleaseEvent(QMouseEvent *event) override;
//双击
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
//移动
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void wheelEvent(QWheelEvent *event) override;
具体应用
//左击
if (event->button() == Qt::LeftButton)
//右击
if (event->button() == Qt::RightButton)
//位置
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
event->globalPos()
//角度
void MainWindow::wheelEvent(QWheelEvent *event)
{
event->delta()
5.1.3 键盘事件
获取具体的按键 | key()函数 | 根据Qt::Key关键字查看 |
---|---|---|
修饰键 | QKeyEvent的modifiers()函数 | 使用Qt::Keyboard-Modifier关键字来查看 |
protected:
virtual void keyPressEvent(QKeyEvent *event) override;
virtual void keyReleaseEvent(QKeyEvent *event) override;
//
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if (event->modifiers() == Qt::ControlModifier) {
if (event->key() == Qt::Key_M) {
this->setWindowState(Qt::WindowMinimized);
}
}
QMainWindow::keyPressEvent(event);
}
//-
void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
qDebug() << event->key();
QMainWindow::keyReleaseEvent(event);
}
5.1.4 定时器事件
- QTimerEvent类用来描述一个定时器事件
- 使用int Qobject::startTimer(int interval)函数,开启一个定时器,毫秒为单位
- 返回一个整型编号来代表这个定时器
- 定时器溢出时,在timerEvent()函数中操作
virtual void timerEvent(QTimerEvent *event) override;
m_timer_id = startTimer(1000);
void MainWindow::timerEvent(QTimerEvent *event)
{
if (event->timerId() == m_timer_id) {
qDebug() << "timer";
QMainWindow::timerEvent(event);
}
5.1.5 事件过滤
在一个部件中监控其他多个部件的事件
installEventFilter()和eventFilter()
m_pTextEdit->installEventFilter(this);
m_pSpinBox->installEventFilter(this);
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == m_pTextEdit) {
if (event->type() == QEvent::Wheel) {
//将event强制转换为发生的事件的类型
QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
if (wheelEvent->delta() > 0) {
m_pTextEdit->zoomIn();//放大
} else {
m_pTextEdit->zoomOut();//缩小
}
return true;
} else {
return false;
}
} else if (obj == m_pSpinBox) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Space) {
m_pSpinBox->setValue(0);
return true;
} else {
return false;
}
}
}
return QMainWindow::eventFilter(obj, event);
}
6. 显示
6.1 绘制
6.1.1 QPainter用法
void MainWindow::paintEvent(QPaintEvent *event)
{
/* 画圆 */
QRectF rect_ellipse(100.0, 100.0, 80.0, 80.0);
QPainter painter(this);
painter.setPen(Qt::blue);
painter.drawEllipse(rect_ellipse);
/* 画字 */
painter.setFont(QFont("Arial", 50));
painter.drawText(rect(), Qt::AlignCenter, "关于");
/* 画多边形 */
QRectF rect_angle(100.0, 20.0, 80.0, 60);
int start_angle = 30 * 16;
int span_angle = 120 * 16;
painter.drawArc(rect_angle, start_angle, span_angle);
QPointF points[4] = {
QPointF(10.0, 80.0),
QPointF(20.0, 10.0),
QPointF(80.0, 30.0),
QPointF(90.0, 70.0),
};
painter.drawConvexPolygon(points, 4);
/* 画线 */
QLineF line(QPoint(0, 0), QPoint(100.0, 100.0));
painter.drawLine(line);
QPointF points_1[3] = {
QPointF(110.0, 180.0),
QPointF(120.0, 110.0),
QPointF(180.0, 130.0),
};
painter.drawPolyline(points_1, 3);
/* 画矩形 */
QRectF rectangle(200.0, 20.0, 80.0, 60.0);
painter.drawRect(rectangle);
/* 画圆角矩形 */
QRectF rectangle_1(200.0, 120.0, 80.0, 60.0);
painter.drawRoundedRect(rectangle_1, 15.0, 15.0);
/* 画单个点 */
QPen pen;
pen.setWidth(6);
pen.setColor(Qt::red);
painter.setPen(pen);
painter.drawPoint(200, 200);
/* 画多个点 */
QPointF point[10];
painter.setPen(pen);
for (int i = 0; i < 10; ++i) {
point[i].setX(2.0 + i * 10);
point[i].setY(130.0);
}
painter.drawPoints(point, 10);
/* 画单个直线 */
pen.setWidth(5);
pen.setColor(Qt::red);
painter.setPen(pen);
painter.drawLine(rect().topLeft(), rect().bottomRight());
/* 画圆点 */
painter.setPen(QColor(Qt::transparent));
painter.setBrush(QBrush(Qt::red));
painter.drawEllipse(100,250,10,10);
QWidget::paintEvent(event);
}
6.2 QSS
6.2.1 基本语法
- 语法类似于CSS,通过设置属性和值的方式定义样式
- 样式选择器:支持不同的选择器,可以根据控件的类型、名称、状态等来选择应用样式
QLabel:选择所有标签控件。
QPushButton#myButton:选择具有id为“myButton”的QPushButton。
QLineEdit:focus:选择获得焦点的QLineEdit。
- 资源文件中设置:将QSS样式文件添加到Qt资源文件(.qrc)中,然后通过资源路径加载。
QApplication a(argc, argv);
QFile styleFile(":/stylesheets/style.qss");
styleFile.open(QFile::ReadOnly);
QString style = QLatin1String(styleFile.readAll());
a.setStyleSheet(style);