目录
1.给pushButton按键添加图片
1.1 首先复制存放图片的文件夹,打开Qt回到编辑页面,右键单击pro文件选择在Explorer中显示,将图片文件夹粘贴进去你的代码同目录即可
1.2 创建一个新的文件夹
1.3 点击Add Files,将所有图片添加进来,然后记得保存
1.4 如何给主窗口添加图片?进入ui界面,选中主窗体对象,右下方找到windowicon,点击选择资源添加图片即可。找到windowstitle可修改程序标题名称
1.5 右键单击pushButton选择样式表,点击添加资源,选中border-image即可为按键添加底图
2. 文件操作类QFile
3. 文件操作类QTextStream
4. 文件选择对话框 QFileDialog
4.1 实现文件的打开与读取
4.2 实现文件的保存
5. 创建下拉列表控件类QComboBox
5.1 第一种方法,直接在ui界面中给QComboBox组件添加选择项
5.2 第二种方法,通过代码的方式为QComboBox添加选择项
6.为记事本项目添加行列显示
6.1 解决思路:每当我输入一个字,光标位置就会发生改变,因此我需要去帮助文档中查找TextEdit中的光标位置发生改变的信号。可以进行信号与槽的连接,当光标位置改变发出信号,被槽函数捕捉,槽函数通过某个函数去获取到光标的行列值并且显示到QLabel上面
6.2 去帮助文档里面找QTextEdit的Signal信号,去找功能是光标位置发生改变时的函数
6.3接着去构造函数中添加connect函数连接该信号与槽函数
6.4 继续去帮助文档里面找QTextEdit的公有函数,功能是获取当前的行列,可以看到该函数的返回值是一个QTextCursor类的值,点击该函数查看具体的用法
7.记事本实现当前行高亮显示
7.1 ExtraSelection简介
8.消息对话框QMessageBox
QMessageBox是Qt框架中用于显示消息框的一个类,它常用于向用户显示信息、询问问题或者报告错误。以下是QMessageBox的一些主要用途:
9. 实现快捷键功能
9.1 示例代码
9.2快捷键实现放大和缩小字体
10.Qt事件概念的引入
10.1 在帮助文档中搜索QWidget可以看到很多有关事件的API
10.3 用事件自定义出一个按键
10.4 如何给自定义按键进行信号与槽的绑定
10.5事件重写实现滚轮控制字体的放大与缩小
10.6事件过滤器
1.给pushButton按键添加图片
1.1 首先复制存放图片的文件夹,打开Qt回到编辑页面,右键单击pro文件选择在Explorer中显示,将图片文件夹粘贴进去你的代码同目录即可
1.2 创建一个新的文件夹
1.3 点击Add Files,将所有图片添加进来,然后记得保存
1.4 如何给主窗口添加图片?进入ui界面,选中主窗体对象,右下方找到windowicon,点击选择资源添加图片即可。找到windowstitle可修改程序标题名称
1.5 右键单击pushButton选择样式表,点击添加资源,选中border-image即可为按键添加底图
2. 文件操作类QFile
//==========================================================================
// 读取
//==========================================================================
void Widget::on_btnRead_clicked()
{// 1.打开文件QFile file("D:/QT/test.txt");if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {qDebug() << "File open error";return; // 添加return以防止文件未打开时继续执行}// 2.读取文件信息QByteArray content = file.readAll();if (content.isEmpty()) {qDebug() << "File read error or empty file";file.close();return;}// 3.打印出文件中内容qDebug() << content.data();// 4.关闭文件file.close();
}//==========================================================================
// 写入
//==========================================================================
void Widget::on_btnWrite_clicked()
{// 1.打开文件QFile file("D:/QT/test2.txt");if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {qDebug() << "File open error";return;}// 2.向文件中写入内容QString data = "hello world! 我是米!";file.write(data.toUtf8());// 3.关闭文件file.close();
}
3. 文件操作类QTextStream
QTextStream是一个功能强大的类,用于处理文本数据,特别是在需要考虑字符编码和文本格式化情 况下。通过这些特性,它提供了一种灵活而强大的方式来读写和操作文本。
//==========================================================================
// 读取
//==========================================================================
void Widget::on_btnstrRead_clicked() {// 1.打开文件QFile file("D:/QT/test.txt");if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {qDebug() << "File open error";return; // 添加return以防止文件未打开时继续执行}QTextStream in(&file);in.setCodec("UTF-8"); // 设置编码为UTF-8// 2.读取整个文件的内容// QString context = in.read(file.size());// qDebug() << context; // 输出整个文件内容// 3.按行读取文件内容while (!in.atEnd()) {QString line = in.readLine();qDebug() << line; // 输出每一行的内容ui->textEdit->append(line); // 将文件中内容显示到textEdit中}// 4.关闭文件file.close();
}//==========================================================================
// 写入
//==========================================================================
void Widget::on_btnstreamWrite_clicked() {// 1.打开文件QFile file("D:/QT/test.txt");if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {qDebug() << "File open error";return; // 添加return以防止文件未打开时继续执行}// 2.向文件中写入内容QTextStream out(&file);out.setCodec("UTF-8"); // 设置编码为UTF-8out << "I write stream char to File"; // 向文件写入文本// 3.关闭文件file.close();
}
4. 文件选择对话框 QFileDialog
4.1 实现文件的打开与读取
void Widget::on_btnOpen_clicked()
{// 打开文件选择对话框,默认打开路径为"C:/Users/mi/Desktop/Qt Project",只显示txt文件QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),"C:/Users/mi/Desktop/Qt Project", // 默认路径tr("Text files (*.txt)")); // 限制为txt文件格式// 打印选中文件的路径qDebug() << fileName << endl;// 1. 尝试打开选中的文件QFile file(fileName);if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {qDebug() << "File open error";return;}// 2. 清空 QTextEdit 中的现有内容ui->textEdit->clear();QTextStream in(&file);in.setCodec("UTF-8");// 3. 逐行读取文件内容并追加到 QTextEdit 中while (!in.atEnd()){QString line = in.readLine();ui->textEdit->append(line);}// 4. 关闭文件file.close();
}
4.2 实现文件的保存
// 1.打开文件对话框,选择保存的路径和文件名
QString fileName = QFileDialog::getSaveFileName(this, tr("保存文件"),"C:/Users/mi/Desktop/untitled.txt",tr("Text files (*.txt *doc)")); // 只显示 .txt 和 .doc 文件类型// 2.输出用户选择的文件名到控制台
qDebug() << fileName << endl;// 3.设置要保存的文件名(路径)
QFile file;
file.setFileName(fileName);// 4.以“只写”模式和“文本”类型打开文件
if(file.open(QIODevice::WriteOnly | QIODevice::Text)){qDebug() << "file open error";
}// 5.将 QTextEdit 的内容写入文件
QTextStream out(&file);
out.setCodec("UTF-8");out << ui->textEdit->toPlainText();// 6.关闭文件
file.close();
5. 创建下拉列表控件类QComboBox
5.1 第一种方法,直接在ui界面中给QComboBox组件添加选择项
5.2 第二种方法,通过代码的方式为QComboBox添加选择项
#include <QComboBox>
#include <QVBoxLayout>
#include <QWidget>class ComboBoxDemo : public QWidget {Q_OBJECTpublic:ComboBoxDemo() {// 创建一个 QComboBox 对象QComboBox *comboBox = new QComboBox(this);// 添加选项comboBox->addItems({"选项 1", "选项 2", "选项 3"});// 设置为可编辑comboBox->setEditable(true);// 连接信号和槽函数,当选择项改变时触发 onSelectionChanged(int)connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onSelectionChanged(int)));// 创建垂直布局并将 QComboBox 添加到其中QVBoxLayout *layout = new QVBoxLayout(this);layout->addWidget(comboBox);}private slots:// 当选中的项改变时执行的处理逻辑void onSelectionChanged(int index) {// 在这里添加你想要的逻辑qDebug() << "当前选中的索引是: " << index;}
};
6.为记事本项目添加行列显示
6.1 解决思路:每当我输入一个字,光标位置就会发生改变,因此我需要去帮助文档中查找TextEdit中的光标位置发生改变的信号。可以进行信号与槽的连接,当光标位置改变发出信号,被槽函数捕捉,槽函数通过某个函数去获取到光标的行列值并且显示到QLabel上面
6.2 去帮助文档里面找QTextEdit的Signal信号,去找功能是光标位置发生改变时的函数
6.3接着去构造函数中添加connect函数连接该信号与槽函数
connect(ui->textEdit, SIGNAL(cursorPositionChanged()), this, SLOT(oncursorPositionChanged()));
6.4 继续去帮助文档里面找QTextEdit的公有函数,功能是获取当前的行列,可以看到该函数的返回值是一个QTextCursor类的值,点击该函数查看具体的用法
//====================================================================================
//当QtextEdit中的光标位置发生移动时,将行列显示到右下角的QLabel上面
//====================================================================================
void Widget::oncursorPositionChanged(){QTextCursor cursor = ui->textEdit->textCursor();// 当前光标的行数QString blockNum = QString::number(cursor.blockNumber()+1);//当前光标的列数QString columnNum = QString::number(cursor.columnNumber()+1);const QString labelMes="L:"+blockNum+",C:"+columnNum+"";// 修改QLabel中的文本内容ui->labelPosition->setText(labelMes);
}
7.记事本实现当前行高亮显示
帮助文档 ——> 搜索QTextEdit ——> Public Functions
——> void QTextEdit::setExtraSelections(const QList<QTextEdit::ExtraSelection> &selections)
可以看到setExtraSelections函数的参数是一个QList列表,并且列表中的元素是ExtraSelection类型的,那么我们进一步点击ExtraSelection查看,可以看到该类型包含一下俩个参数,用于定位当前位置和颜色属性。
void Widget::oncursorPositionChanged() {QTextCursor cursor = ui->textEdit->textCursor();// 当前光标的行数QString blockNum = QString::number(cursor.blockNumber() + 1);// 当前光标的列数QString columnNum = QString::number(cursor.columnNumber() + 1);const QString labelMes = "L:" + blockNum + ", C:" + columnNum;// 修改 QLabel 中的文本内容ui->labelPosition->setText(labelMes);// 设置当前行高亮QList<QTextEdit::ExtraSelection> extraSelections;// 创建 ExtraSelection 对象并设置光标及颜色QTextEdit::ExtraSelection ext;ext.cursor = cursor; // 使用当前光标定位QBrush qBrush(Qt::blue); // 高亮颜色ext.format.setBackground(qBrush); // 设置背景颜色ext.format.setProperty(QTextFormat::FullWidthSelection, true); // 设置为全宽选择// 将设置好的 ExtraSelection 添加到列表中extraSelections.append(ext);// 设置 QTextEdit 的额外选择项ui->textEdit->setExtraSelections(extraSelections);
}
7.1 ExtraSelection简介
QTextEdit:: ExtraSelection是一个在QTextEdit中用来表示额外的文本选择和高亮的结构。
1.ExtraSelection 结构体:**QTextEdit:: ExtraSelection 是一个结构体,包含了两个主要成员 QTextCursor和QTextCharFormat。QTextCursor表示在文本中的一个位置或者区间,而QTextCharFormat用于定义这个区间的格式,比如背景颜色、字体等。
2.设置ExtraSelection:**你可以创建一个或多个ExtraSelection对象,为它们设置相应的光标位置和格式,然后通过QTextEdit的setExtraSelections方法将这些对象应用到文本编辑器中。这样,你可以对文本的特定部分应用特定的格式,而不影响其他文本。
3.高亮当前行:**要高亮显示当前行,你需要在cursorPositionChanged()信号的槽函数中创建一个ExtraSelection对象。使用当前的QTextCursor对象(通过textCursor()方法获取)来确定当前行的位置,并设置背景颜色为你选择的高亮颜色。
QTextCharFormat类是Qt框架中的一部分,用于描述文本字符的格式。这个类提供了丰富的接口来设置和获取文本字符的各种属性,如字体、颜色、背景色等。QTextCharFormat通常用于富文本处理可以在像QTextEdit和QTextDocument这样的类中使用下面列出了QTextCharFormat的一些常用功能和方法:
1.设置和获取字体样式:
- 使用setFont()方法设置字体。
- 通过font()方法获取当前字体。
2.设置字体属性:
- setFontWeight():设置字体的粗细。
- setFontItalic():设置字体是否倾斜。
- setFontUnderline():设置是否有下划线。
3.设置文本颜色和背景色:
- setForeground():设置文本的前景色(即字体颜色)。
- setBackground():设置文本的背景色。
4.其他文本属性:
- setToolTip():设置文本的工具提示。
- setAnchor():设置文本是否为超链接。
- setAnchorHref():设置超链接的目标URL。
#include <QApplication>
#include <QTextEdit>
#include <QTextCharFormat>int main(int argc, char *argv[]) {QApplication a(argc, argv);// 创建 QTextEdit 编辑器QTextEdit editor;// 创建一个 QTextCharFormat 对象来定义文本格式QTextCharFormat format;format.setFontWeight(QFont::Bold); // 设置字体为粗体format.setForeground(Qt::blue); // 设置文本颜色为蓝色format.setBackground(Qt::yellow); // 设置文本背景为黄色// 获取编辑器的 QTextCursorQTextCursor cursor = editor.textCursor();// 移动光标到文本开始位置,并插入带格式的文本cursor.movePosition(QTextCursor::Start);cursor.insertText("Hello, World!", format);// 显示编辑器窗口editor.show();// 启动应用程序事件循环return a.exec();
}
8.消息对话框QMessageBox
QMessageBox是Qt框架中用于显示消息框的一个类,它常用于向用户显示信息、询问问题或者报告错误。以下是QMessageBox的一些主要用途:
8.1示例代码
#include <QApplication>
#include <QMessageBox>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 创建消息框QMessageBox msgBox;msgBox.setWindowTitle("Message Title"); // 设置窗口标题msgBox.setText("This is the main message text."); // 设置主要消息文本msgBox.setInformativeText("This is additional informative text."); // 设置附加信息msgBox.setIcon(QMessageBox::Information); // 设置图标为信息类型// 添加按钮msgBox.addButton(QMessageBox::Ok); // 确定按钮msgBox.addButton(QMessageBox::Cancel); // 取消按钮msgBox.setDefaultButton(QMessageBox::Ok); // 默认按钮设为确定// 执行消息框并获取用户的响应int ret = msgBox.exec();// 根据用户点击的按钮执行操作if (ret == QMessageBox::Ok) {// 用户点击了 OK} else if (ret == QMessageBox::Cancel) {// 用户点击了 Cancel}return app.exec();
}
8.2自定义按键
// 创建消息框QMessageBox msgBox;msgBox.setWindowTitle("Message Title"); // 设置窗口标题msgBox.setText("保存对此文件所做修改?"); // 设置主要消息文本msgBox.setIcon(QMessageBox::Information); // 设置图标为信息类型// 自定义按钮QPushButton *saveButton = msgBox.addButton(tr("保存"), QMessageBox::AcceptRole); // 自定义保存按钮QPushButton *discardButton = msgBox.addButton(tr("不保存"), QMessageBox::DestructiveRole); // 自定义不保存按钮QPushButton *returnButton = msgBox.addButton(tr("返回"), QMessageBox::RejectRole); // 自定义返回按钮// 执行消息框并获取用户的响应msgBox.exec();// 用户点击了保存============================================================================if (msgBox.clickedButton() == saveButton) {}else if(msgBox.clickedButton() == discardButton){}
9. 实现快捷键功能
在Qt中实现快捷键功能通常涉及到QShortcut类的使用。下面是一个简单的代码示例,展示了如何在 Qt应用程序中为特定功能设置快捷键:
Ctrl + O 弹出文件选择对话框,用于打开某个文件
Ctrl + S 弹出文件保存对话框,进行保存文件
9.1 示例代码
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{// 创建一个快捷键 Ctrl + N 并关联到窗口QShortcut *shortcut = new QShortcut(QKeySequence("Ctrl+N"), this);// 当快捷键被按下时,显示一个消息框QObject::connect(shortcut, &QShortcut::activated, [this]() {QMessageBox::information(this, "Shortcut Activated", "Ctrl+N was pressed");});// 当快捷键被按下时,调用保存文件的槽函数QObject::connect(shortcut, &QShortcut::activated, this, &Widget::on_pushButton_clicked);
}
9.2快捷键实现放大和缩小字体
在帮助文档中看QTextEdit,public functions里面有字体相关的说明
但是我们仅仅从这些函数,无法获取到当前控件的字体,我们需要看它的父类
它的父类里面好像也没有,继续往下找
好像也没有,继续往下找
此时找到了font()函数,其属于QFont类,在该类下面包含了许多有关于字体相关的API
QShortcut *shortZoomIn = new QShortcut(QKeySequence("Ctrl+Shift+="), this);QObject::connect(shortZoomIn, &QShortcut::activated, [=](){QFont Font = ui->textEdit->font(); // 获取当前字体int fontSize = Font.pointSize(); // 获取当前字体大小QFont newFont("Arial", fontSize + 1); // 改变当前字体大小ui->textEdit->setFont(newFont);});
10.Qt事件概念的引入
Qt框架内部为我们提供了一些列的事件处理机制,当窗口事件产生之后,事件会经过: 事件派发->事件过滤->事件分发->事件处理几个阶段。
Qt窗口中对于产生的一系列事件都有默认的处理动作,如果我们有特殊需求就需要在合适的阶段重写事件的处理动作,比如信号与槽就是一种事件(event)是由系统或者Qt本身在不同的场景下发出的。
当用户按下移动鼠标、敲下键盘,或者是窗口关闭大小发生变化隐藏或显示都会发出一个相应事件。一些事件在对用户操作做出响应时发出,如鼠标键盘事件等;
另一些事件则是由系统自动发出, 如计时器事件。每一个Qt应用程序都对应一个唯一的QApplication应用程序对象,然后调用这个对的 exec()函数,这样Qt框架内部的事件检测就开始了(程序将进入事件循环来监听应用程序的事件)。
10.1 在帮助文档中搜索QWidget可以看到很多有关事件的API
10.2重写事件:程序关闭之前进行询问
// 鼠标进入窗口时
void Widget::enterEvent(QEvent *event)
{qDebug() << "mouse enter";}// 鼠标离开窗口时
void Widget::leaveEvent(QEvent *event)
{qDebug() << "mouse leave";
}// 鼠标滚轮发生变化时
void Widget::wheelEvent(QWheelEvent *event)
{qDebug() << "mouse become";qDebug() << event->angleDelta();
}// 窗口关闭时
void Widget::closeEvent(QCloseEvent *event)
{int ret = QMessageBox::warning(this, tr("提示!"),tr("确定退出应用程序吗?"),QMessageBox::Ok | QMessageBox::No);switch(ret){case QMessageBox::Ok : //关闭窗口event->accept();break;case QMessageBox::No: //返回应用程序event->ignore();break;}}// 窗口大小发生改变时
void Widget::resizeEvent(QResizeEvent *event)
{qDebug() << "oldSize:" << event->oldSize()<<"newSize" << event->size();
}
10.3 用事件自定义出一个按键
自定义按键涉及到的事件有鼠标的进入,离开,点击
- 在当前项目中添加一个
mybutton
类,并使其继承于QWidget
类 - 来到
mybutton
的头文件中,添加保护类成员函数:事件函数。 - 并通过
Alt+Enter
快捷键快速向mybutton.cpp
中添加事件函数的框架。添加完后通过F4快捷键快速切换到mybutton.h
头文件中
-
接着实现该按键在最初始的状态就是一个图片,首先去
mybutton.h
头文件中添加一个私有成员QPixmap pic;
。然后去mybutton
类的构造函数中利用pic
对象去加载图片(注意在此之前先添加你需要的图片到整个工程文件中)
#include "mybutton.h"
#include <QPainter>myButton::myButton(QWidget *parent) : QWidget(parent)
{// 加载初始图片pic.load(":/icon/o1.png");// 设置按钮的固定大小为图片的大小//setFixedSize(pic.size());setFixedSize(100,100);// 刷新界面,触发 paintEvent 进行绘制update();
}void myButton::enterEvent(QEvent *event)
{// 当鼠标进入按钮区域时,加载悬停状态的图片pic.load(":/icon/o3.png");// 刷新界面,更新显示图片update();
}void myButton::leaveEvent(QEvent *event)
{// 当鼠标离开按钮区域时,恢复初始状态的图片pic.load(":/icon/o1.png");// 刷新界面,更新显示图片update();
}void myButton::mousePressEvent(QMouseEvent *event)
{// 当鼠标按下时,加载点击状态的图片pic.load(":/icon/o2.png");// 刷新界面,更新显示图片update();
}void myButton::paintEvent(QPaintEvent *event)
{// 创建一个 QPainter 对象,负责绘制图片QPainter painter(this);// 使用 QPainter 在按钮区域内绘制当前加载的图片painter.drawPixmap(rect(), pic);
}
- 接着去到
widget.cpp
的ui界面中,添加一个Widget窗口组件,并提升其为myButton
类
10.4 如何给自定义按键进行信号与槽的绑定
(1)给 widget.h
中包含 #include “mybutton.h”
(2)给 mybutton.h
中 添加一个信号 void clicked();
(3)给 mybutton.c
中的点击事件中添加发送信号(发送点击事件时,切换图片,发送信号)
void myButton::mousePressEvent(QMouseEvent *event)
{// 当鼠标按下时,加载点击状态的图片pic.load(":/icon/o2.png");// 刷新界面,更新显示图片update();// 发送点击信号emit clicked();
}
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 当检测到clicked信号时,通过Lambda表达式输出调试内容connect(ui->myBtn, &myButton::clicked, [=](){qDebug() << "myButton is clicked";});
}
10.5事件重写实现滚轮控制字体的放大与缩小
(1)在记事本项目中新建一个类MyTextEdit,使其继承与QTextEdit
(2) 向 mytextedit.h 中添加保护成员事件函数
#ifndef MYTEXTEDIT_H
#define MYTEXTEDIT_H#include <QTextEdit>class MyTextEdit : public QTextEdit
{
public:MyTextEdit(QWidget *parent);
protected:void wheelEvent(QWheelEvent *e) override; // 鼠标滚轮事件void keyPressEvent(QKeyEvent *e) override; // 按键按下事件void keyReleaseEvent(QKeyEvent *e) override; // 按键松开事件
private:bool ctrlKeyPressed = 0;
};#endif // MYTEXTEDIT_H
(3)mytextedit.cpp
#include "mytextedit.h"
#include <QWheelEvent>
#include <QDebug>// UStudent::UStudent(String name, int age, String class, String Id) : Student(String name, int age, String class)
MyTextEdit::MyTextEdit(QWidget *parent) : QTextEdit(parent)
{
}// 鼠标滚轮事件
void MyTextEdit::wheelEvent(QWheelEvent *e)
{//qDebug() << e->angleDelta().y(); // 输出120代表鼠标滚轮向上,输出-120代表鼠标滚轮向下if(ctrlKeyPressed == 1){if(e->angleDelta().y()>0){zoomIn(); // 字体放大}else if(e->angleDelta().y() < 0){zoomOut(); // 字体缩小}e->accept(); // 表明了该鼠标滚轮事件已被处理,而不会继续将该事件进一步传播}else{ // 如果Ctrl按键没有被按下,只有鼠标滚轮事件,则由其父类执行鼠标滚轮默认操作QTextEdit::wheelEvent(e);}
}// 键盘按键按下事件
void MyTextEdit::keyPressEvent(QKeyEvent *e)
{if(e->key() == Qt::Key_Control){qDebug() << "ctrl Pressed";ctrlKeyPressed = 1;}QTextEdit::keyPressEvent(e);
}// 键盘按键松开事件
void MyTextEdit::keyReleaseEvent(QKeyEvent *e)
{if(e->key() == Qt::Key_Control){qDebug() << "ctrl Release";ctrlKeyPressed = 0;}QTextEdit::keyReleaseEvent(e);
}
(4)提升原 textEdit为mytextedit
10.6事件过滤器
**派发——>过滤——>分发——>处理**
(通过修改子类代码的情况下修改事件的行为,属于修改事件的处理阶段)
在 Qt 的事件处理过程中,事件过滤器(Event Filter) 是一种强大的机制,可以在事件到达目标对象之前拦截并处理它。通过事件过滤器,你可以共享不同对象的事件处理逻辑,或者在父对象中集中处理某些特定的事件。以下是如何引入和使用事件过滤器的步骤: ### 1. 定义事件过滤器: 事件过滤器通常是一个继承自 QObject 的类,重写 QObject::eventFilter() 方法。这个方法会在事件传递到目标对象之前被调用。 ### 2. 安装事件过滤器: 使用 QObject::installEventFilter() 方法将事件过滤器安装到某个对象上。安装后,事件会在发送给目标对象之前先经过过滤器。例如,如果想在父窗口中过滤子窗口的事件,需要在父对象上调用 installEventFilter(),并传递子窗口作为参数。 ### 3. 实现事件过滤器逻辑: 在 eventFilter() 方法内部,你可以编写自定义逻辑来决定是否处理或忽略事件。如果返回 true,事件被处理,不会继续传递;如果返回 false,事件将继续传递给目标对象。 ### 4. 事件分发: 当事件发生时,Qt 首先会将事件发送到安装了事件过滤器的对象,调用 eventFilter()。 ### 5. 决定是否传递事件: 根据 eventFilter() 的返回值,Qt 决定是否继续向目标对象传递事件。如果返回 true,事件处理结束;如果返回 false,事件会继续传递给目标对象。 ### 6. 目标对象处理事件: 如果事件过滤器允许事件继续传递,目标对象将像没有过滤器时那样处理事件。 ### 事件过滤器的适用场景: - 当你想改变子类事件的行为,而不修改其代码。 - 当多个对象共享相同的事件处理逻辑。 |
第一步:去头文件声明事件过滤函数
public:
bool eventFilter(QObject *watched, QEvent *event);
第二步:在Widget构造函数中为textEdit安装了事件过滤器,为滚轮字体做准备
ui->textEdit->installEventFilter(this);
- 第三步:实现过滤函数
先去帮助文档中查找QEvent,看看事件有哪些类型,我们此处需要的是鼠标滚轮事件和Ctrl按键按下事件,但是由于一次只能捕捉一个事件,所以我们需要通过Api去判断Ctrl按键是否被按下,就不使用Ctrl按键按下事件
- 第四步:根据经验可知,可通过QGuiApplication类中的下面函数去判断哪个按键被按下
Qt::KeyboardModifiers QGuiApplication::keyboardModifiers()
该Api返回值是Qt::KeyboardModifiers
类型的,点击进去可以看到该类型包含以下按键,我们需要的是返回值为Ctrl按键
- 第五步:开始编写过滤函数
// 事件过滤函数
bool Widget::eventFilter(QObject *watched, QEvent *event)
{if(event->type() == QEvent::Wheel){if(QGuiApplication::keyboardModifiers() == Qt::ControlModifier){qDebug() << "Ctrl and Wheel pressed";//此处需要你强制类型转换,因为QEvent类中并不包含QwheelEvent类的angleDelta()函数QWheelEvent *wheelEvent = (QWheelEvent *)event;if(wheelEvent->angleDelta().y() > 0){zoomInText();}else if(wheelEvent->angleDelta().y() < 0){zoomOutText();}return true; //不再继续传递}return false;}
}
在 C++ 中,强制类型转换(或类型转换)是将变量从一种类型转换为另一种类型的方式。C++ 提供了四种强制转换运算符,每种都有特定的用途和适用场景: