QT——记事本项目

目录

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++ 提供了四种强制转换运算符,每种都有特定的用途和适用场景:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/463763.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis-“自动分片、一定程度的高可用性”(sharding水平拆分、failover故障转移)特性(Sentinel、Cluster)

文章目录 零、写在前面一、水平拆分(sharding/分片)、故障转移(failover)机制介绍水平拆分&#xff08;Sharding&#xff09;故障转移机制 二、Redis的水平拆分的机制有关的配置1. 环境准备2. 配置文件配置3. 启动所有Redis实例4. 创建集群5. 测试集群读/写6. 集群管理 三、Red…

OpenCV视觉分析之目标跟踪(7)目标跟踪器类TrackerVit的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 VIT 跟踪器由于特殊的模型结构而变得更快且极其轻量级&#xff0c;模型文件大约为 767KB。模型下载链接&#xff1a;https://github.com/opencv/…

yolov8训练及测试(ubuntu18.04、tensorrt、ros)

1 数据集制作 1.1标注数据 Linux/Ubuntu/Mac 至少需要 Python 2.6 &#xff08;推荐使用 Python 3 或更高版本 及 PyQt5&#xff09; Ubuntu Linux (Python 3 Qt5) git clone https://gitcode.com/gh_mirrors/la/labelImg.git sudo apt-get install pyqt5-dev-tools cd lab…

海睿思产品体系二次开发能力介绍

海睿思产品体系支持用户通过编写开发代码&#xff08;含低代码&#xff09;&#xff0c;提供定制化功能&#xff0c;解决数据治理和共享场景的个性化需求。 1、数据集成 应用场景&#xff1a;自定义数据集成能力 开发语言&#xff1a;JAVA 使用效果&#xff1a; 1&#xff…

SpringMVC笔记 一万字

此笔记来自于B站尚硅谷 文章目录 一、SpringMVC 简介1、什么是MVC2、什么是SpringMVC3、SpringMVC的特点 二、HelloWorld1、开发环境2、创建maven工程a>添加web模块b>打包方式&#xff1a;warc>引入依赖 3、配置web.xmla>默认配置方式b>扩展配置方式 4、创建请求…

Maven随笔

文章目录 1、什么是MAVEN2、Maven模型3、Maven仓库4、项目集成1_Idea集成Maven设置2_创建Maven项目3_POM配置详解4_maven 坐标详情5_Maven工程类型6_导入Maven项目 5、依赖管理1_依赖配置2_依赖传递3_可选依赖4_排除依赖4_可选依赖和排除依赖的区别5_依赖范围6_继承与聚合7_版本…

看门狗有什么用?

看门狗(WATCH-DOG Timer)全称看门狗定时器 用途&#xff1a;防止程序死机&#xff08;主要用途&#xff09; 或 单纯用来计时 直接上代码&#xff1a; 只要程序可以正常运行&#xff0c;看门狗就会清零&#xff0c;如果崩了&#xff0c;看门狗就会复位程序

云原生开源开发者沙龙丨AI 应用工程化专场杭州站邀您参会

云原生开源开发者沙龙 AI 原生应用架构专场&#xff0c;邀您一起交流&#xff0c;探索 AI 原生应用的工程化落地&#xff01; 活动简介 AI 驱动的应用程序开发、部署和运维&#xff0c;给应用带来了新的生命力和想象空间。但大部分开发者对 AI 应用的编程框架、可观测体系、网…

UFO:Windows操作系统的具象智能代理

近年来&#xff0c;随着AI技术的发展&#xff0c;智能代理在各种应用中扮演着越来越重要的角色。微软推出的UFO&#xff08;User-Focused Operator&#xff09;正是这样一个出色的多代理框架&#xff0c;旨在通过无缝导航和操作&#xff0c;满足用户在Windows操作系统中跨多个应…

基于人工智能的搜索和推荐系统

互联网上的搜索历史分析和用户活动是个性化推荐的基础&#xff0c;这些推荐已成为电子商务行业和在线业务的强大营销工具。随着人工智能的使用&#xff0c;在线搜索也在改进&#xff0c;因为它会根据用户的视觉偏好提出建议&#xff0c;而不是根据每个客户的需求和偏好量身定制…

使用ffmpeg和mediamtx模拟多通道rtsp相机

首先下载ffmpeg&#xff0c;在windows系统上直接下载可执行文件&#xff0c;并配置环境变量即可在命令行当中调用执行。 下载地址&#xff1a; https://ffmpeg.org/再在github上下载mediamtx搭建rtsp服务器&#xff0c;使用ffmpeg将码流推流到rtsp服务器。 下载地址&#xff1…

Spring Boot框架:校园社团信息管理的现代化解决方案

3系统分析 3.1可行性分析 通过对本校园社团信息管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本校园社团信息管理系统采用SSM框架&#xff0c;JAVA作…

软件测试面试八股文个人总结

一、软件测试基础面试题 1、阐述软件生命周期都有哪些阶段? 常见的软件生命周期模型有哪些? 软件生命周期是指一个计算机软件从功能确定设计&#xff0c;到开发成功投入使用&#xff0c;并在使用中不断地修改、增补和完善&#xff0c;直到停止该软件的使用的全过程(从酝酿到…

彻底理解链表(LinkedList)结构

目录 比较操作结构封装单向链表实现面试题 循环链表实现 双向链表实现 链表&#xff08;Linked List&#xff09;是一种线性数据结构&#xff0c;由一组节点&#xff08;Node&#xff09;组成&#xff0c;每个节点包含两个部分&#xff1a;数据域&#xff08;存储数据&#xff…

C#/.NET/.NET Core优秀项目和框架2024年10月简报

前言 每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架&#xff08;每周至少会推荐两个优秀的项目和框架当然节假日除外&#xff09;&#xff0c;推文中有项目和框架的介绍、功能特点、使用方式以及部分功能截图等&#xff08;打不开或者打开GitHub很慢的同学可以优先查看…

数据库作业5

1&#xff0c;建立触发器&#xff0c;订单表中增加订单数量后&#xff0c;商品表商品数量同步减少对应的商品订单出数量,并测试 测试&#xff1a; 2.建立触发器&#xff0c;实现功能:客户取消订单&#xff0c;恢复商品表对应商品的数量 测试 3.建立触发器&#xff0c;实现功能:…

证书下行,这些高质量IT证书仍值得考

在快速变化的信息技术领域&#xff0c;专业认证不仅证明了个人的专业技能&#xff0c;还常常是许多企业在招聘时考虑的重要标准&#xff0c;因此很多IT朋友都会选择考一本证书来傍身。 然而&#xff0c;随着技术的发展和市场的变化&#xff0c;并不是所有的IT证书都能保持其原有…

华为荣耀曲面屏手机下面空白部分设置颜色的方法

荣耀部分机型下面有一块空白区域&#xff0c;如下图红框部分 设置这部分的颜色需要在themes.xml里面设置navigationBarColor属性 <item name"android:navigationBarColor">android:color/white</item>

【开源免费】基于SpringBoot+Vue.JS新闻推荐系统(JAVA毕业设计)

博主说明&#xff1a;本文项目编号 T 056 &#xff0c;文末自助获取源码 \color{red}{T056&#xff0c;文末自助获取源码} T056&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…

使用DJL和PaddlePaddle的口罩检测详细指南

使用DJL和PaddlePaddle的口罩检测详细指南 完整代码 该项目利用DJL和PaddlePaddle的预训练模型&#xff0c;构建了一个口罩检测应用程序。该应用能够在图片中检测人脸&#xff0c;并将每张人脸分类为“戴口罩”或“未戴口罩”。我们将深入分析代码的每个部分&#xff0c;以便…