【Qt-Event-信号和槽】

Qt编程指南

  • ■ Qt事件
    • ■ Qt鼠标事件
    • ■ Qt事件同步和异步分发
    • ■ Qt事件循环(exec、eventloop)
    • ■ Qt事件-发送-过滤
    • ■ QT事件过滤
  • ■ 信号和槽
    • ■ 一个信号可以连接多个槽
    • ■ 多个信号可以连接同一个槽
    • ■ 一个信号可以连接另外一个信号
    • ■ 信号槽连接
    • ■ [=]()

■ Qt事件

  1. Qt使用了一个事件队列,当新的事件发生时,会被追加到事件队列的尾部,前一个事件完成以后,取出后面的时间进行处理。
  2. 必要时候Qt事件也是可以不进入事件队列的,而是直接处理。
  3. 事件还可以使用 “事件过滤器” 进行过滤。
  4. 我们使用组件关心的是信号槽;如果自定义组件,我们关心的是事件,因为我们可以通过事件来改变组件的默认操作。
  5. QApplication对象,然后调用了它的exec()函数,其实这个函数就是开始QT的事件循环,
  6. Qt创建一个事件对象,QT所有的事件都继承于QEvent类。在事件对象创建完毕后,QT将这个事件对象传递给QObject的event()函数。Event()函数不直接处理事件,而是按照事件对象的类型分派特定的事件处理函数。
  7. Qt事件处理分五个层次:重定义事件处理函数、重定义event()函数、为单个组件安装事件过滤器、为QApplication安装事件过滤器、重定义QCoreApplication的notify()函数。这几个层次的控制是逐层增大的。
  8. 事件比信号槽优点:1事件分发可以使同步也可以使异步的,2 事件可以使用过滤器。

■ Qt鼠标事件

1.鼠标键按下
virtual void mousePressEvent (QMouseEvent*);
2.鼠标键弹起
virtual void mouseReleaseEvent (QMouseEvent*);
3.鼠标键双击
virtual void mouseDoubleClickEvent (QMouseEvent*);
4.鼠标键按下的同时移动
virtual void mouseMoveEvent (QMouseEvent*);
触发按键:
Qt::MouseButton QMouseEvent::button (void);
Qt::LeftButton
Qt::MiddleButton
Qt::RightButton
按键状态:
Qt::MouseButtons QMouseEvent::buttons (void);
Qt::LeftButton
#include mouseevent.h
MouseEvent::MouseEvent(QWidget *parent): QMainWindow(parent)
{setWindowTitle(tr(鼠标事件));statusLabel = new QLabel;statusLabel->setText(tr(当前位置:));statusLabel->setFixedWidth(100);MousePosLabel = new QLabel;MousePosLabel->setText(tr());MousePosLabel->setFixedWidth(100);statusBar()->addPermanentWidget(statusLabel);statusBar()->addPermanentWidget(MousePosLabel);this->setMouseTracking(true);resize(400,200);
}MouseEvent::~MouseEvent()
{    
}void MouseEvent::mousePressEvent(QMouseEvent *e)
{QString str=(+QString::number(e->x())+,+QString::number(e->y())+);if(e->button()==Qt::LeftButton){statusBar()->showMessage(tr(左键:)+str);}else if(e->button()==Qt::RightButton){statusBar()->showMessage(tr(右键:)+str);}else if(e->button()==Qt::MidButton){statusBar()->showMessage(tr(中键:)+str);}
}void MouseEvent::mouseMoveEvent(QMouseEvent *e)
{MousePosLabel->setText((+QString::number(e->x())+, +QString::number(e->y())+));
}void MouseEvent::mouseReleaseEvent(QMouseEvent *e)
{QString str=(+QString::number(e->x())+,+QString::number(e->y())+);statusBar()->showMessage(tr(释放在:)+str,3000);
}
void MouseEvent::mouseDoubleClickEvent(QMouseEvent *e){}

■ Qt事件同步和异步分发

sendEvent 发出的事件会立即被处理,也就是“同步”执行。
postEvent 发送的事件会被加入事件队列,在下一轮事件循环时才处理,也就是“异步”执行。
sendPostedEvents,是将已经加入队列中的准备异步执行的事件立即同步执行。

■ Qt事件循环(exec、eventloop)

QApplicaion::exec()、QMessageBox::exec()都是事件循环。其中前者又被称为主事件循环。QEventLoop::quit()能够终止事件循环。
当事件太多而不能马上处理完的时候,待处理事件被放在一个“队列”里,称为“事件循环队列”。当事件循环处理完一个事件后,就从“事件循环队列”中取出下一个事件处理之。当事件循环队列为空的时候,它和一个啥事也不做的永真循环有点类似,但是和永真循环不同的是,事件循环不会大量占用CPU资源。
事件循环的本质就是以队列的方式再次分配线程时间片。

事件循环是可以嵌套的,一层套一层,子层的事件循环执行exec()的时候,父层事件循环就处于中断状态;当子层事件循环跳出exec()后,父层事件循环才能继续循环下去。
如果某个子事件循环仍然有效,但其父循环被强制跳出,此时父循环不会立即执行跳出,而是等待子事件循环跳出后,父循环才会跳出。

■ Qt事件-发送-过滤

void frmInput2019::sendEvent(quint8 type, const QString &text)
{if (type == 0) {//切换中英模式QMouseEvent mousePress(QEvent::MouseButtonPress, QPoint(0, 0), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);QApplication::sendEvent(ui->labType->isVisible() ? ui->labType : ui->labType2, &mousePress);} else if (type == 1) {//隐藏汉字候选面板QMouseEvent mousePress(QEvent::MouseButtonPress, QPoint(0, 0), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);QApplication::sendEvent(ui->labMore, &mousePress);} else if (type == 2) {//删除QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier, QString());QApplication::sendEvent(currentWidget, &keyPress);} else if (type == 3) {//插入回车符QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier, QString(\n));QApplication::sendEvent(currentWidget, &keyPress);} else if (type == 4) {//插入字符QKeyEvent keyPress(QEvent::KeyPress, 0, Qt::NoModifier, QString(text));QApplication::sendEvent(currentWidget, &keyPress);}
}bool frmInput2019::eventFilter(QObject *watched, QEvent *event)
{//qDebug() << TIMEMS << watched << event;if (watched == this) {//处理自身拖动QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);//按下的时候记住坐标,移动到鼠标松开的位置if (event->type() == QEvent::MouseButtonPress) {if (mouseEvent->button() == Qt::LeftButton) {mousePressed = true;mousePoint = mouseEvent->globalPos() - this->pos();return true;}} else if (event->type() == QEvent::MouseButtonRelease) {mousePressed = false;return true;} else if (event->type() == QEvent::MouseMove) {//bottom为固定的底部禁用拖动if (mousePressed && position != "bottom") {this->move(mouseEvent->globalPos() - mousePoint);this->update();return true;}}} else if (watched == ui->labMore) {//打开更多汉字候选面板if (event->type() == QEvent::MouseButtonPress) {}} else if (watched == ui->labType) {//中英模式切换,由于采用的标签所以在这里处理if (event->type() == QEvent::MouseButtonPress) {setInputType(inputType == "english" ? "chinese" : "english");}} else if (watched == ui->labType2) {//固定切换到英文模式if (event->type() == QEvent::MouseButtonPress) {setInputType("english");}} else if (watched == ui->widgetCn) {//没有汉字或者按下的地方没有汉字或者当前汉字标签个数过少都不用继续if (pinyinHelper.getCount() == 0 || lastText.isEmpty()) {return false;}//记住最后按下拖动的时间,过短则认为是滑动,启动滑动动画//static bool pressed = false;static QPoint lastPos = QPoint();static QDateTime lastTime = QDateTime::currentDateTime();QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);if (event->type() == QEvent::MouseButtonPress) {} else if (event->type() == QEvent::MouseMove) {  }} else if (watched == ui->widgetMore) {//没有汉字或者按下的地方没有汉字或者当前汉字标签个数过少都不用继续if (pinyinHelper.getCount() == 0 || lastText.isEmpty()) {return false;      }//记住最后按下拖动的时间,过短则认为是滑动,启动滑动动画QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);if (event->type() == QEvent::MouseButtonPress) {} else if (event->type() == QEvent::MouseButtonRelease) {}} else if (event->type() == QEvent::MouseMove) {return true;}}} else if (watched->inherits("QLabel")) {//单击的是汉字标签QLabel *lab = (QLabel *)watched;//2022-1-7增加硬键盘模式下单击汉字标签选中if (useHardKeyBoard && event->type() == QEvent::MouseButtonPress) {return true;}if (!upper && inputType == "chinese") {if (lab->property("labCn").toBool()) {//记住最后按下的滚动条位置,如果滚动条一直没有变化则认为单击了标签static int lastPosition = 0;if (event->type() == QEvent::MouseButtonPress) {} else if (event->type() == QEvent::MouseButtonRelease) {                 if (event->type() == QEvent::MouseButtonPress) {} else if (event->type() == QEvent::MouseButtonRelease) {      } else if (event->type() == QEvent::RequestSoftwareInputPanel) {showPanel();} else if (event->type() == QEvent::CloseSoftwareInputPanel) {hidePanel();}}return QWidget::eventFilter(watched, event);
}

■ QT事件过滤

#include eventfilter.h
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QMouseEvent>
#include <QMatrix>EventFilter::EventFilter(QWidget *parent,Qt::WindowFlags f): QDialog(parent,f)
{setWindowTitle(tr(事件过滤));label1 = new QLabel;Image1.load(../image/1.png);label1->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);label1->setPixmap(QPixmap::fromImage(Image1));label2 = new QLabel;Image2.load(../image/2.png);label2->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);label2->setPixmap(QPixmap::fromImage(Image2));label3 = new QLabel;Image3.load(../image/3.png);label3->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);label3->setPixmap(QPixmap::fromImage(Image3));stateLabel = new QLabel(tr(鼠标按下标志));stateLabel->setAlignment(Qt::AlignHCenter);QHBoxLayout *layout=new QHBoxLayout;layout->addWidget(label1);layout->addWidget(label2);layout->addWidget(label3);QVBoxLayout *mainLayout = new QVBoxLayout(this);mainLayout->addLayout(layout);mainLayout->addWidget(stateLabel);label1->installEventFilter(this);label2->installEventFilter(this);label3->installEventFilter(this);
}EventFilter::~EventFilter()
{    
}bool EventFilter::eventFilter(QObject *watched, QEvent *event)
{if(watched==label1){if(event->type()==QEvent::MouseButtonPress){QMouseEvent *mouseEvent=(QMouseEvent *)event;if(mouseEvent->buttons()&Qt::LeftButton){stateLabel->setText(tr(左键按下左边图片));}else if(mouseEvent->buttons()&Qt::MidButton){stateLabel->setText(tr(中键按下左边图片));}else if(mouseEvent->buttons()&Qt::RightButton){stateLabel->setText(tr(右键按下左边图片));}QMatrix matrix;matrix.scale(1.8,1.8);QImage tmpImg=Image1.transformed(matrix);label1->setPixmap(QPixmap::fromImage(tmpImg));}if(event->type()==QEvent::MouseButtonRelease){stateLabel->setText(tr(鼠标释放左边图片));label1->setPixmap(QPixmap::fromImage(Image1));}}else if(watched==label2){if(event->type()==QEvent::MouseButtonPress){QMouseEvent *mouseEvent=(QMouseEvent *)event;if(mouseEvent->buttons()&Qt::LeftButton){stateLabel->setText(tr(左键按下中间图片));}else if(mouseEvent->buttons()&Qt::MidButton){stateLabel->setText(tr(中键按下中间图片));}else if(mouseEvent->buttons()&Qt::RightButton){stateLabel->setText(tr(右键按下中间图片));}QMatrix matrix;matrix.scale(1.8,1.8);QImage tmpImg=Image2.transformed(matrix);label2->setPixmap(QPixmap::fromImage(tmpImg));}if(event->type()==QEvent::MouseButtonRelease){stateLabel->setText(tr(鼠标释放中间图片));label2->setPixmap(QPixmap::fromImage(Image2));}}else if(watched==label3){if(event->type()==QEvent::MouseButtonPress){QMouseEvent *mouseEvent=(QMouseEvent *)event;if(mouseEvent->buttons()&Qt::LeftButton){stateLabel->setText(tr(左键按下右边图片));}else if(mouseEvent->buttons()&Qt::MidButton){stateLabel->setText(tr(中键按下右边图片));}else if(mouseEvent->buttons()&Qt::RightButton){stateLabel->setText(tr(右键按下右边图片));}QMatrix matrix;matrix.scale(1.8,1.8);QImage tmpImg=Image3.transformed(matrix);label3->setPixmap(QPixmap::fromImage(tmpImg));}if(event->type()==QEvent::MouseButtonRelease){stateLabel->setText(tr(鼠标释放右边图片));label3->setPixmap(QPixmap::fromImage(Image3));}}return QDialog::eventFilter(watched,event);
}

■ 信号和槽

SIGNAL 和 SLOT 是 Qt 的宏,用于指明信号和槽,并将它们的参数转换为相应的字符串。

■ 一个信号可以连接多个槽

connect(spinNum, SIGNAL(valueChanged(int)), this, SLOT(addFun(int));
connect(spinNum, SIGNAL(valueChanged(int)), this, SLOT(updateStatus(int));

■ 多个信号可以连接同一个槽

connect(ui->rBtnBlue,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
connect(ui->rBtnRed,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
connect(ui->rBtnBlack,SIGNAL(clicked()),this,SLOT(setTextFontColor()));

■ 一个信号可以连接另外一个信号

connect(spinNum, SIGNAL(valueChanged(int)), this, SIGNAL (refreshInfo(int));

严格的情况下,信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的参数。
如果不匹配,会出现编译错误或运行错误。
在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT。
当一个信号被发射时,与其关联的槽函数通常被立即执行,就像正常调用一个函数一样。
只有当信号关联的所有槽函数执行完毕后,才会执行发射信号处后面的代码。

/* 设定两个QPushButton对象的位置 */
pushButton1->setGeometry(300,200,80,40);
pushButton2->setGeometry(400,200,80,40);

■ 信号槽连接

connect(pushButton1, SIGNAL(clicked()), this, SLOT(pushButton1_Clicked()));
connect(pushButton2, SIGNAL(clicked()), this, SLOT(pushButton2_Clicked()));

=

connect(sndTimer,&QTimer::timeout,={
updateQStringList();
emit edit_textChanged(getstep().toInt(),m_stlist);
});

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

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

相关文章

音频修复增强软件iZotope RX 10 mac特点介绍

iZotope RX 10 mac是一款音频修复和增强软件。 iZotope RX 10 mac软件特点 声音修复&#xff1a;iZotope RX 10可以去除不良噪音、杂音、吱吱声等&#xff0c;使音频变得更加清晰干净。 音频增强&#xff1a;iZotope RX 10支持对音频进行音量调节、均衡器、压缩器、限制器等处…

LLM调研笔记

这里写目录标题 LLM调研1. 外挂知识库2. 微调数据prompting和fine-tuning的对比 3. NLP的发展4. 大语言模型的涌现能力5. 大模型的几个关键技术6. 数据预处理7. 主流架构8. 模型训练9. 大模型的微调10. 大模型的使用11. 大模型的评估 LLM调研 大模型的不足&#xff1a;在特定的…

[RISCV] 为android14添加一个新的riscv device

本篇博客将基于android-14-r18添加Sifive unmatched板子的支持。 Setup build envoronment Establishing a build environment $ sudo apt install git-core gnupg flex bison build-essential zip curl zlib1g-dev libc6-dev-i386 libncurses5 x11proto-core-dev libx11-de…

单例模式你了解嘛?

单例模式 单例模式&#xff08;Singleton Pattern&#xff09;是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个…

mysql(50) : 大数据导出为csv

代码 import com.alibaba.gts.flm.base.util.Mysql8Instance;import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.math.BigDecimal; import java.util.Iterator; import java.util.List; import java.util.Objects;public class 大数…

SpringSecurity6 | 登录失败后的JSON处理

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringSecurity6 ✨特色专栏: MySQL学习 🥭本文内容: SpringSecurity6 | 登录失败后的JSON处理 📚个人知识库: Leo知识库,…

LeetCode 75| 前缀和

目录 1732 找到最高海拔 724 找到数组的中心下标 1732 找到最高海拔 class Solution { public:int largestAltitude(vector<int>& gain) {int res 0;int sum 0;for(int num : gain){sum num;res max(res,sum);}return res;} }; 时间复杂度O(n) 空间复杂度O(…

JavaScript----变量和数据类型

1. 定义变量 JavaScript 是一种弱类型语言&#xff0c;也就是说不需要指定变量的类型&#xff0c;JavaScript的变量类型由它的值来决定&#xff0c; 定义变量需要用关键字 var, 一条JavaScript语句应该以“;”结尾 定义变量的语法格式: var 变量名 值; var iNum 123;var s…

Java架构师系统架构设计实践

目录 1 导语2 架构设计实践本章概述3 架构设计要素概述和规划4 架构设计模式5 架构设计输入6 架构设计输出7 架构设计要素总结 想学习架构师构建流程请跳转&#xff1a;Java架构师系统架构设计 1 导语 Java架构师在进行系统架构设计时&#xff0c;需要综合考虑多个方面&#…

单体项目-动态上下文问题

在HTML中使用Thymeleaf解决动态上下文问题&#xff0c;你可以使用Thymeleaf的模板语法来生成动态的链接&#xff08;例如CSS和JavaScript文件的链接&#xff09;以适应不同的应用程序上下文。以下是一个示例&#xff1a; <!DOCTYPE html> <html xmlns:th"http:/…

SAP PP 配置学习(二)

MRP 参数文件设定 扩允物料视图 删除物料 物料批量维护

【第12例】IPD技术规划流程及意义

目录 简介 技术规划流程 技术规划意义 CSDN相关课程 作者简介 简介 今天继续更新 IPD 进阶专栏。 这节内容主要来谈谈 IPD 技术规划流程及意义。

【C Primer Plus第六版 学习笔记】第十四章 结构和其他数据形式

有基础&#xff0c;进阶用&#xff0c;个人查漏补缺 建立结构声明&#xff1a;描述该对象由什么组成&#xff0c;即结构布局 格式&#xff1a; 关键字 标记&#xff08;可选&#xff09;{结构 }&#xff1b; 举例&#xff1a; struct book{char title[2];char author[4];float …

Redis遇到过的问题 (Could not get a resource from the pool )

生产上通过scan命令&#xff0c;查询一个大key耗时40s后&#xff0c;报 Could not get a resource from the pool&#xff0c;初步报错是连接池的连接数不够&#xff0c;从网上搜了一些解决方案。 排查过程&#xff1a; 一、首先需要先尝试连接redis&#xff0c;如果连接不上那…

Node.js(三)-模块的加载机制

1. 优先从缓存中加载 模块在第一次加载后会被缓存&#xff0c;这就意味着多次调用require()不会导致模块的代码被执行多次。 注意:不论是内置模块、用户自定义模块、还是第三方模块&#xff0c;它们都会优先从缓存中加载&#xff0c;从而提高模块的加载效率. 2. 内置模块的加…

Unity-.meta文件

.meta 文件的作用简单来说是建立 Unity 与资源之间的“桥梁”,可以将meta文件理解不同文件之间的桥梁,通过它引擎可以管理不同文件之间的依赖关系。在游戏中引用一个游戏资源,Unity 并不是直接按照文件的路径或者名称,而是使用一个独一无二的 GUID 来指向工程里该资源文件。…

c++案例汇总

文章目录 结构体案例案例1案例2 结构体案例 案例1 学校正在做毕设项目&#xff0c;每名老师带领5个学生&#xff0c;总共有3名老师&#xff0c;需求如下&#xff1a; 设计学生和老师的结构体&#xff0c;其中在老师的结构体中&#xff0c;有老师姓名和一个存放5名学生的数组作…

欧洲影像学人工智能和影像组 学文章审稿指南解读(一)--本手稿是否专注于AI/影像组学的报告?

欧洲影像学人工智能和影像组 学文章审稿指南解读 针对人工智能&#xff08;AI&#xff09;和影像组学领域的研究文章&#xff0c;欧洲影像学&#xff08;European Radiology&#xff09;期刊为审稿人提出了一系列特别的说明和要求。这些要求不仅仅是审稿的准则&#xff0c;更是…

Git 查询某段时间所有用户提交的代码量并过滤文件格式

获取代码提交用户 git log --format%aN| sort -u | while read name; do echo -en "$name\t"; done;获取代码提交文件的修改情况 git log --authorforwardhuan --prettytformat: --numstat获取代码提交文件的修改情况(过滤文件类型) git log --authorforwardhuan …

gin实现登录逻辑,包含cookie,session

users/login.html {{define "users/login.html"}} <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>登录页面</title> </head> <body><form method"post" a…