【QT】系统-上

在这里插入图片描述

欢迎来到Cefler的博客😁
🕌博客主页:折纸花满衣
🏠个人专栏:QT

在这里插入图片描述


目录

  • 👉🏻事件
    • QWidget中常见的事件
  • 👉🏻处理鼠标事件:leaveEvent和enterEvent
  • 👉🏻处理定时器事件
  • 👉🏻QFile
    • 代码练习

👉🏻事件

在这里插入图片描述

QT事件的基本概念是QT框架中用于处理各种动作或状态变化的重要机制。以下是对QT事件基本概念的详细介绍:

🌈一、事件的定义

在QT中,事件(Event)是指由特定对象发生的动作或状态变化,这些动作或变化可以来源于用户操作(如鼠标点击、键盘输入)、系统信号(如定时器超时、网络数据到达)或其他程序内部的事件。事件是QT实现“事件驱动(Event Driven)”程序设计的基础。

🌈二、事件的分类

QT中的事件可以根据其来源和类型进行分类,包括但不限于以下几种:

  • 用户输入事件:如鼠标点击(mousePressEvent、mouseReleaseEvent、mouseMoveEvent、mouseDoubleClickEvent等)、键盘输入(keyPressEvent、keyReleaseEvent等)。
  • 系统事件:如窗口显示、窗口关闭、定时器事件(QTimerEvent)等。
  • 自定义事件:开发者可以根据需要创建并发送自定义的事件。

🌈三、事件的处理机制

QT中的事件处理机制基于事件循环,即应用程序不断地从操作系统接收事件并进行处理。具体过程如下:

  1. 事件捕获:QT从可能产生事件的地方(如操作系统、定时器、网络等)捕获事件,并将其转化为带有事件信息的对象(QEvent及其子类)。
  2. 事件分发:QT调用QCoreApplication::notify()函数对事件进行分发,将事件对象发送给需要处理事件的对象。
  3. 事件处理:QObject对象调用QObject::event()函数接收事件。event()函数根据事件的类型,调用对应的事件处理函数(如mousePressEvent、keyPressEvent等)。如果事件处理函数返回true,则表示事件已被处理;否则,事件可能会继续传递给父对象或进行其他处理。

🌈 四、事件处理函数的重写

在QT中,几乎所有的事件处理函数都是虚函数,开发者可以在子类中重新实现这些函数以自定义事件的处理逻辑。例如,可以在QWidget的派生类中重写mousePressEvent()函数来处理鼠标按下事件。

🌈 五、事件过滤器

除了重写事件处理函数外,QT还提供了事件过滤器(Event Filter)机制,允许对象在事件到达事件处理函数之前对事件进行拦截和处理。通过安装事件过滤器,开发者可以在不修改原有代码的情况下增加对事件的处理逻辑。

🌈 六、事件与信号槽的区别

虽然事件和信号槽都是QT中用于处理对象间通信的机制,但它们之间存在一些区别:

  • 触发时机:事件通常是由系统或用户操作触发的,而信号则是由对象内部状态变化触发的。
  • 处理方式:事件处理通常需要开发者显式地编写事件处理函数来响应,而信号槽则通过连接信号与槽函数来实现自动响应。
  • 灵活性:事件处理提供了更高的灵活性,因为开发者可以在事件处理函数中执行更复杂的逻辑,并可以通过事件过滤器对事件进行拦截和处理。而信号槽则更加简洁和直观,适用于对象间简单的通信。

综上所述,QT事件是QT框架中用于处理各种动作或状态变化的重要机制。通过理解事件的基本概念、分类、处理机制以及事件处理函数的重写和事件过滤器的使用,开发者可以更加灵活地设计并实现QT应用程序中的交互逻辑。

QWidget中常见的事件

在Qt框架中,QWidget是所有用户界面对象的基类,它提供了大量的事件处理机制,允许开发者对用户的操作、系统事件等进行响应。以下是一些在QWidget中常见的事件类型及其简要介绍:

  1. 键盘事件(Keyboard Events)

    • keyPressEvent(QKeyEvent *event): 当有按键被按下时触发。
    • keyReleaseEvent(QKeyEvent *event): 当按键被释放时触发。
    • keyPressEventkeyReleaseEvent允许你处理键盘输入,比如识别用户按下了哪个键。
  2. 鼠标事件(Mouse Events)

    • mousePressEvent(QMouseEvent *event): 当鼠标按钮被按下时触发。
    • mouseReleaseEvent(QMouseEvent *event): 当鼠标按钮被释放时触发。
    • mouseMoveEvent(QMouseEvent *event): 当鼠标在窗口内部移动时触发。
    • mouseDoubleClickEvent(QMouseEvent *event): 当鼠标双击时触发。
      这些事件使得开发者可以响应用户的鼠标点击、移动和双击等操作。
  3. 焦点事件(Focus Events)

    • focusInEvent(QFocusEvent *event): 当控件获得焦点时触发。
    • focusOutEvent(QFocusEvent *event): 当控件失去焦点时触发。
      这些事件允许开发者处理控件获得或失去焦点时的行为。
  4. 定时器事件(Timer Events)

    • timerEvent(QTimerEvent *event): 当定时器触发时调用。你可以通过startTimer()方法启动一个定时器,并在timerEvent中处理定时任务。
  5. 重绘事件(Paint Events)

    • paintEvent(QPaintEvent *event): 当控件需要被重绘时触发。在这个事件中,你应该使用QPainter来绘制控件的内容。
  6. 大小改变事件(Resize Events)

    • resizeEvent(QResizeEvent *event): 当控件的大小改变时触发。
  7. 移动事件(Move Events)

    • moveEvent(QMoveEvent *event): 当控件的位置改变时触发。
  8. 关闭事件(Close Events)

    • closeEvent(QCloseEvent *event): 当控件接收到关闭请求时触发(例如,用户点击了窗口的关闭按钮)。你可以在这个事件中阻止窗口的关闭。
  9. 拖放事件(Drag and Drop Events)

    • 拖放事件包括dragEnterEvent, dragMoveEvent, dragLeaveEvent, dropEvent等,允许你实现复杂的拖放功能。
  10. 其他事件

    • Qt还提供了许多其他类型的事件,如滚轮事件(wheelEvent)、显示和隐藏事件(showEvent, hideEvent)、上下文菜单事件(contextMenuEvent)等,以满足不同的应用需求。

这些事件处理函数通常需要在你的QWidget派生类中重写,以实现对特定事件的自定义响应。通过事件处理,你可以创建出更加丰富和交互性强的用户界面。

👉🏻处理鼠标事件:leaveEvent和enterEvent

在这里插入图片描述
从文档说明可以看到,我们如果想重写leaveEvent和enterEvent方法并使用,必须先创建控件的子类,并在子类中重写。
在这里插入图片描述
在这里插入图片描述

如果我们在ui中添加的是QLabel控件,而自定义了一个MyLabel子类(继承于QLabel),此时重写了事件方法,如果我们想让事件触发,必须将QLabel控件提升为我们自定义的MyLabel类型
在这里插入图片描述
在这里插入图片描述

之后如果我们想要处理其它事件,就按照这样的套路即可:
比如处理鼠标点击事件,参考下事件方法原型去做
在这里插入图片描述

👉🏻处理定时器事件

在这里插入图片描述

#include "widget.h"
#include "ui_widget.h"
#include<QKeyEvent>
#include<QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    timeId = this->startTimer(1000);//打开定时器;timeId相当于文件描述符

}

Widget::~Widget()
{
    delete ui;
}
void Widget::timerEvent(QTimerEvent *event)
{
    if(timeId==event->timerId())
    {
        int value = ui->lcdNumber->intValue();
        if(value<=0)
        {
            this->killTimer(timeId);//关掉定时器

        }
        else
        {
            value-=1;
            ui->lcdNumber->display(value);
        }
    }
}

👉🏻QFile

在这里插入图片描述

QFile 是 Qt 框架中用于文件操作的一个类,它提供了对文件系统进行读写操作的接口。QFile 类使得对文件的打开、读写、关闭等操作变得简单而直接。它是 Qt 核心模块(QtCore)的一部分,因此在使用时需要包含对应的头文件 <QFile>

🌏 主要特点

  • 文件操作QFile 提供了对文件的打开、关闭、读写等基本操作。
  • 二进制或文本模式:可以指定文件以二进制模式或文本模式打开,以适应不同的数据需求。
  • 错误处理:提供了丰富的错误处理机制,可以通过 error() 函数获取最后发生的错误,通过 errorString() 获取错误的描述字符串。
  • 文件信息:可以获取文件的名称、大小、最后修改时间等基本信息。
  • 灵活性:可以与 QIODevice 类的其他子类(如 QBuffer, QTcpSocket 等)一起使用,实现更复杂的文件和网络操作。

🌏 常用成员函数

  • QFile::QFile(const QString &name):构造函数,通过文件名构造一个 QFile 对象。
  • bool QFile::open(OpenMode mode):打开文件。OpenMode 是一个枚举类型,可以指定文件的打开模式,如只读、只写、追加等。
  • bool QFile::close():关闭文件。
  • qint64 QFile::size() const:返回文件的大小(以字节为单位)。
  • bool QFile::exists() const:检查文件是否存在。
  • QString QFile::fileName() const:返回文件的名称。
  • QFile::FileError QFile::error() const:返回最后发生的错误。
  • QString QFile::errorString() const:返回最后一次错误的描述字符串。
  • qint64 QFile::read(char *data, qint64 maxlen):从文件中读取数据到缓冲区 data 中,最多读取 maxlen 字节。
  • qint64 QFile::write(const char *data, qint64 len):向文件中写入数据。

🌏 使用示例

下面是一个简单的示例,展示了如何使用 QFile 读取文件内容:

#include <QFile>
#include <QTextStream>
#include <QDebug>

int main() {
    QFile file("example.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "Cannot open file for reading:" << file.errorString();
        return -1;
    }

    QTextStream in(&file);
    QString line;
    while (!in.atEnd()) {
        line = in.readLine();
        qDebug() << line;
    }

    file.close();
    return 0;
}

在这个示例中,我们首先尝试以只读和文本模式打开名为 “example.txt” 的文件。如果文件成功打开,我们使用 QTextStream 来逐行读取文件内容,并通过 qDebug() 输出每一行。最后,我们关闭文件。注意,这里使用了 QIODevice::Text 标志来指定以文本模式打开文件,这对于处理文本文件(如 CSV、TXT 等)很有用。如果处理的是二进制文件,则应该省略此标志。

代码练习

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QTextEdit>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void  handle1();
    void  handle2();

private:
    Ui::MainWindow *ui;
    QTextEdit* edit;
};
#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QMenuBar>
#include<QMenu>
#include<QStatusBar>
#include<QAction>
#include<QTextEdit>
#include<QFileDialog>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //创建菜单栏
    QMenuBar* manubar = this->menuBar();

    //创建菜单
    QMenu* menu1 = new QMenu("文件");
    manubar->addMenu(menu1);
    //添加菜单选项
    QAction* action1 = new QAction("打开");
    QAction* action2 = new QAction("保存");
    menu1->addAction(action1);
    menu1->addAction(action2);

    //指定一个输入框
     edit = new QTextEdit();
    QFont font;
    font.setPixelSize(20);
    edit->setFont(font);
    this->setCentralWidget(edit);

    //连接Action的信号槽
    connect(action1,&QAction::triggered,this,&MainWindow::handle1);
     connect(action2,&QAction::triggered,this,&MainWindow::handle2);
}

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

void MainWindow::handle1()
{
    //1.读取打开文件的文件路径
    QString path = QFileDialog::getOpenFileName();

    //2.将读取到的文件路径显示到状态栏
    QStatusBar* statusbar = this->statusBar();
    statusbar->showMessage(path);
    //3.根据用户选择的路径,构造一个QFile对象,并打开文件
    QFile file(path);
    bool ret = file.open(QIODevice::ReadOnly);
    if(!ret)
    {
        //如果打开失败
        statusbar->showMessage(path + " 打开失败!");
    }
    //4.读取文件内容

    QString text = file.readAll();

    //5.关闭文件
    file.close();

    //6.将读取的内容显示到输入框中
    edit->setText(text);
}

void MainWindow::handle2()
{
    //1.读取打开文件的文件路径
    QString path = QFileDialog::getSaveFileName();

    //2.将读取到的文件路径显示到状态栏
    QStatusBar* statusbar = this->statusBar();
    statusbar->showMessage(path);
    //3.根据用户选择的路径,构造一个QFile对象,并打开文件
    QFile file(path);
    bool ret = file.open(QFile::WriteOnly);//
    if(!ret)
    {
        //如果打开失败
        statusbar->showMessage(path + " 打开失败!");
    }
    //4.输写文件内容

    const QString& text = edit->toMarkdown();

    //5.将输写的内容写进新文件中
    file.write(text.toUtf8());

    //6.关闭文件
    file.close();


}


在这里插入图片描述


如上便是本期的所有内容了,如果喜欢并觉得有帮助的话,希望可以博个点赞+收藏+关注🌹🌹🌹❤️ 🧡 💛,学海无涯苦作舟,愿与君一起共勉成长
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

API接口什么意思?电商API接口有什么作用

API接口简介&#xff1a; 从技术层面上来看&#xff0c;API是一系列函数、协议和工具&#xff0c;它们定义了软件组件如何交互&#xff0c;让开发者无需了解对方内部工作原理就可以使用对方的功能或服务。 事实上&#xff0c;API接口在电商行业中的应用较为广泛。 具体来看&…

Msf之Python分离免杀

Msf之Python分离免杀 ——XyLin. 成果展示&#xff1a; VT查杀率:8/73 (virustotal.com) 火绒和360可以过掉&#xff0c;但Windows Defender点开就寄掉了 提示&#xff1a;我用360测的时候&#xff0c;免杀过了&#xff0c;但360同时也申报了&#xff0c;估计要不了多久就寄…

【2025】中医药健康管理小程序(安卓原生开发+用户+管理员)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

vue2.0+ts注册全局函数和几个递归查找

vue2.0ts注册全局函数和几个递归查找 一、main.ts 一、main.ts // 定义你的全局函数,判断是否有按钮权限 interface Item {label: string;checked: number;[k: string]: any; } // 获取按钮时候权限 function globalLable(arr: Item[], label: string): boolean {for (const i…

未授权扫描工具-APIFinder

该工具目的是为了发现某文件中的路径&#xff0c;然后拼接到某url后&#xff0c;通过响应码及返回长度&#xff0c;快速定位并判断其是否存在未授权。 APIFinder [-h] [-u URL1] [-f file] [-U URL2] [-i RES] 参数描述-u目标url(例如:http://xxx.com/x.js)-f目标文件(由于一些…

《深度学习》—— 神经网络模型对手写数字的识别

神经网络模型对手写数字的识别 import torch from torch import nn # 导入神经网络模块 from torch.utils.data import DataLoader # 数据包管理工具&#xff0c;打包数据, from torchvision import datasets # 封装了很多与图像相关的模型&#xff0c;数据集 from torchvi…

神经网络 卷积层 参数共享

参数共享常用于神经网络卷积层中&#xff0c;共享的实际上就是说卷积核中的参数一直保持不变&#xff0c;如下所示就可以称为共享参数啦&#xff01;&#xff01;

【秋招笔试-支持在线评测-试读版】9.19小米秋招(已改编)-三语言题解

&#x1f36d; 大家好这里是 春秋招笔试突围&#xff0c;一起备战大厂笔试 &#x1f4bb; ACM金牌团队&#x1f3c5;️ | 多次AK大厂笔试 &#xff5c; 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; 和 手里的小花花…

C++掉血迷宫

目录 开头程序程序的流程图程序游玩的效果下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。 程序 #include <iostream> #include <string> #include <cstring> using namespace std; enum RBYG {R 1,B 2,Y 4,G 7, }; struct heal {int ix…

python_uiautoanimation实现自动化微信聊天

文章目录 ⭐前言⭐微软inspect工具定位元素&#x1f496;工具查找属性 ⭐查找微信窗口&#x1f496;命令行查找运行窗口 ⭐查找微信的聊天窗口⭐封装发送消息⭐定时查询消息⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享python_uiautoanimation实现自动化微…

平价头戴式蓝牙耳机有哪些?四款公认平价性能超强品牌机型推荐

在追求高品质音乐体验的同时&#xff0c;许多消费者希望找到价格亲民的头戴式蓝牙耳机&#xff0c;市场上不乏性能卓越、价格实惠的产品&#xff0c;它们凭借出色的音质、舒适的佩戴体验和可靠的续航能力赢得了用户的青睐&#xff0c;那么在众多的头戴式蓝牙耳机内&#xff0c;…

提高数据集成稳定性:EMQX Platform 端到端规则调试指南

自 5.7.0 版本起&#xff0c;EMQX 支持了 SQL 调试&#xff0c;并支持在数据集成全流程中进行规则调试&#xff0c;使用户能够在开发阶段就全面验证和优化规则&#xff0c;确保它们在生产环境中的稳定高效运行。 点击此处下载 EMQX 最新版本&#xff1a;https://www.emqx.com/z…

移动开发(三):使用.NET MAUI打包第一个安卓APK完整过程

目录 一、修改AndroidManifest.xml 配置APP基本信息权限 二、修改项目属性调整输出Android包格式为APK 三、项目发布 四、APP分发 五、总结 之前给大家介绍过使用使用.NET MAUI开发第一个安卓APP,今天给大家介绍如何打包成APK,然后安装到安卓手机正常运行。这里还是沿用…

java序列化对象后读取数据错误的问题

今天学到了对象的序列化&#xff0c;就是将对象写入到文件中去&#xff0c;大家要直到我们普通的输入输出文件只是把数据的值写入了文件&#xff0c;而没有把数据的类型与之绑定&#xff0c;比如我向文件中写入100&#xff0c;那么这是字符串”100“还是整数100还是高精度浮点数…

算法.图论-建图/拓扑排序及其拓展

文章目录 建图的三种方式邻接矩阵邻接表链式前向星 拓扑排序拓扑排序基础原理介绍拓扑排序步骤解析拓扑排序模板leetcode-课程表 拓扑排序拓展食物链计数喧闹与富有并行课程 建图的三种方式 我们建图的三种方式分别是邻接矩阵, 邻接矩阵, 链式前向星 邻接矩阵 假设我们的点的…

Android14请求动态申请存储权限

Android14请求动态申请存储权限 Android14和Android15存储权限有增加多了选择部分&#xff0c;还是全部。一个小小的存储权限真的被它玩出了花来。本来Android13就将存储权限进行了3个细分&#xff0c;是图片&#xff0c;音频还是视频文件。 步骤一&#xff1a;AndroidManife…

24年蓝桥杯及攻防世界赛题-MISC-2

11 Railfence fliglifcpooaae_hgggrnee_o{cr} 随波逐流编码工具 分为5栏时,解密结果为:flag{railfence_cipher_gogogo} 12 Caesar rxms{kag_tmhq_xqmdzqp_omqemd_qzodkbfuaz} mode1 #12: flag{you_have_learned_caesar_encryption} 随波逐流编码工具 13 base64 base64解…

【machine learning-十-梯度下降-学习率】

学习率 学习率不同的学习率 在梯度下降算法中&#xff0c;学习率的选择很重要&#xff0c;不恰当的选择&#xff0c;甚至可能导致损失发散&#xff0c;而非收敛&#xff0c;下面就看一下学习率的影响。 学习率 学习率是下图中的红框圈出来的部分&#xff0c; 学习率是模型的超…

虹科干货 | CAN/CAN FD故障揭秘:快速排查与解决技巧

是否在处理CAN总线问题时感到头疼&#xff1f;是否在寻找简单直接的方法来解决那些看似复杂的连接故障&#xff1f;本文将为您提供实用技巧&#xff0c;让您能够轻松应对这些难题。 CAN总线因其高效、可靠的数据交换能力&#xff0c;在汽车、工业控制、航空航天等多个关键领域得…

《黑神话悟空》开发框架与战斗系统解析

本文主要围绕《黑神话悟空》的开发框架与战斗系统解析展开 主要内容 《黑神话悟空》采用的技术栈 《黑神话悟空》战斗系统的实现方式 四种攻击模式 连招系统的创建 如何实现高扩展性的战斗系统 包括角色属性系统、技能配置文件和逻辑节点的抽象等关键技术点 版权声明 本…