目录
定时器法
一、重载函数mouseDoubleClickEvent
二、事件过滤器 (测试 OK)(*****)
QT按钮实现鼠标双击事件 (***)
QPushButton “双击”事件代码:样例源码 测试OK (*****)
QT鼠标事件穿透,使QLabel、QPushbutton等上层控件可以被穿透:
注:QLabel 在设置了“穿透”之后,会造成原来能够实现的鼠标点击 Label的功能、失效。
参考:
Qt Event事件详解 (*精*)
https://blog.youkuaiyun.com/ken2232/article/details/130272182
----------------------------------
Qt默认,QPushButton没有“双击”的槽函数。但有“单击”的槽函数。
====================
Qt报错:member access into incomplete type 'QMouseEvent'
#include <QMouseEvent> //需要在头文件中添加这个头文件,OK。
参考:
Qt 事件总结(鼠标、键盘) QMouseEvent、QKeyEvent
https://blog.youkuaiyun.com/m0_73443478/article/details/127821498
Qt开发基础(11)——event事件分发器和过滤器 ******
https://blog.youkuaiyun.com/bigData1994pb/article/details/119726769
Qt学习笔记(十五):QPushButton 按钮的常用方法 ******
获取 和 设置 按钮上的文本信息:
设置按钮控件获取焦点:
设置鼠标位于按钮控件区域时,光标的类型:
设置控件背景透明:即将控件外观设为平铺
设置按钮样式:前景色,背景色,边框等;需要通过样式表来修改
定时器法
https://blog.youkuaiyun.com/m0_48990191/article/details/126979971
参考:
char cnt =0;
void delayTime(int k)
{
QEventLoop eventloop;
//QTimer::singleShot(50*k, &eventloop, SLOT(quit()));
QTimer::singleShot(50*k, &eventloop, SLOT(quit()));
eventloop.exec();
}
void MainWindow::on_pushButton_clicked()
{
cnt++;
delayTime(10);
if(cnt == 1)
{
qDebug()<<"单击";
cnt = 0;
}
else if (cnt >= 2)
{
qDebug()<<"双击";
cnt = 0;
}
}
最佳应用场景:部件数量少的场景
QEventLoop事件循环的使用
https://blog.youkuaiyun.com/qq_42108501/article/details/125210922
最佳应用场景:对简单信号槽应用的扩展?
** QT 控件增加双击事件 ******
https://blog.youkuaiyun.com/ligare/article/details/125379742
一、重载函数mouseDoubleClickEvent
class SpinBoxAndCombox: public QWidget
{
Q_OBJECT
protected:
// 然后重新实现鼠标双击事件
void mouseDoubleClickEvent(QMouseEvent* e);
public:
SpinBoxAndCombox(QWidget* parent = nullptr) : SpinBoxAndCombox(parent){ };
};
void SpinBoxAndCombox::mouseDoubleClickEvent(QMouseEvent *event)
{
if (event->buttons() == Qt::LeftButton)
{
qDebug() << "12345";
}
}
最佳应用场景:屏幕绘图?
样例 功能实现:
样例针对的是:SpinBoxAndCombox::,因此,SpinBoxAndCombox::可以接收到双击信号。
如果改成如下代码,则:MainWindow::整个窗口可以接收到双击信号。
而在 QPushButton上进行鼠标“双击”,是没有反应的。上层的 QPushButton遮挡了 “双击”信号;无法穿透到 MainWindow,所以没有反应。
一般来说,点击 MainWindow就可以获得与坐标有关的一些信号。但当光标在QPushButton上时,这时点击鼠标,将获得与 QPushButton有关的信号了,而不是与 ui界面有关的坐标信号;此时,需要对 QPushButton进行“穿透”设置,相当于此时可以无视 QPushButton的遮挡,于是,就又可以获得ui坐标信号了。
ui->pushButton->setAttribute(Qt::WA_TransparentForMouseEvents); //设置 QPushButton可以被穿透,这样双击QPushButton,就有反应了。
https://blog.youkuaiyun.com/weixin_43246170/article/details/127383224
void MainWindow:: mouseDoubleClickEvent(QMouseEvent *event)
{
if (event->buttons() == Qt:: LeftButton)
{
qDebug() << "mouse Double Click: active 激发.";
}
}
?除非为 QPushButton单独采用一个类来实现,并将mouseDoubleClickEvent(QMouseEvent *event) 的作用域限定为 QPushButton。但这样就太繁琐了。
假如一个窗口有 10个部件,那么,难道每一个部件都需要编写 一个mouseDoubleClickEvent函数吗?
这就是事件过滤器的好处了。
二、事件过滤器 (测试 OK)(*****)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
virtual bool eventFilter(QObject * obj,QEvent *event) override;
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
最佳应用场景:部件数量多的场景?与定时器双击功能相比。
注a1:event 输出
qDebug() << event;
QMouseEvent(MouseButtonDblClick, LeftButton, localPos=157,95, screenPos=861,200)
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->widget->installEventFilter(this); //widget控件安装事件过滤器
}
MainWindow::~MainWindow()
{
delete ui;
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == ui->widget) // 你要过滤的对象
if (event->type() == QEvent::MouseButtonDblClick)
{ // 你要过滤的对象的事件类型
// 你自己期望实现的功能,在这里我的实现是新建一个标签页以及新的文本编辑栏
return true; // 注意这里一定要返回true,表示你要过滤该事件原本的实现
}
return false; // 返回false表示不过滤,还按默认的来
}
注a2:event 输出
直接安装在按键上,OK
ui->installEventFilter(this); // pushButton控件安装事件过滤器
QMouseEvent(MouseButtonDblClick, LeftButton, localPos=49,8, screenPos=639,368)
注a3:综合比较
注a1/2的共同点,输出的数据相同
qDebug() << event;
QMouseEvent(MouseButtonDblClick, LeftButton, localPos=157,95, screenPos=861,200)
注a1/2的不同点:
注a1并没有直接关联部件:需要进行坐标换算等等。如屏幕绘图场景?
注a2被安装在部件上:可以直接对部件进行双击,有效。扩展简单信号槽的应用?
QPushButton “双击”事件代码:样例源码 测试OK (*****)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMouseEvent> //需要在头文件中添加这个头文件,OK。
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// ui->pushButton->setAttribute(Qt::WA_TransparentForMouseEvents);
ui->pushButton->installEventFilter(this); //pushButton控件安装事件过滤器
}
MainWindow::~ MainWindow()
{
delete ui;
}
bool MainWindow:: eventFilter(QObject *obj, QEvent *event)
{
if (obj == ui->pushButton) // 你要过滤的对象
{
if (event->type() == QEvent:: MouseButtonDblClick)
{
// 你要过滤的对象的事件类型
// 你自己期望实现的功能,在这里我的实现是新建一个标签页以及新的文本编辑栏
qDebug()<<"pushButton MouseButtonDblClick : active";
//拦截
return true; // 注意这里一定要返回true,表示你要过滤该事件原本的实现
}
else
{
//不进行拦截
return false; // 返回false表示不过滤,还按默认的来
}
}
else
{
//当不确定是否继续传播时,按照父类的方法来处理
//即调用父类的evenFilter函数
return QMainWindow::eventFilter(obj, event);
}
}
要点说明:
#include <QMouseEvent>
ui->pushButton->installEventFilter(this); //pushButton控件安装事件过滤器
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
bool MainWindow:: eventFilter(QObject *obj, QEvent *event)
{
if (obj == ui->pushButton ) // 你要过滤的对象
{
if (event->type() == QEvent:: MouseButtonDblClick)
{
// 你要过滤的对象的事件类型
// 你自己期望实现的功能,在这里我的实现是新建一个标签页以及新的文本编辑栏
qDebug()<<"Debug_11: pushButton MouseButtonDblClick : active";
//拦截
return true; //(1) // 注意这里一定要返回true,表示你要过滤该事件原本的实现
}
else
{
qDebug()<<"Debug_22: pushButton MouseButtonDblClick : active";
//不进行拦截
return false; //(2) // 返回false表示不过滤,还按默认的来
}
else
{
return MainWindow::eventFilter(obj, event);
}
}
问题:
在 win下,OK.
在linux下,NG。出现:qt.qpa.xcb: internal error: void QXcbWindow::setNetWmStateOnUnmappedWindow() called on mapped window
源码说明abc:
双击信号的发出者和接收者,都是同一个 pushButton,这就产生了上述的问题?
只要光标处在 pushButton的有效范围之内,Debug_22 就有条件地一直输出;这个条件就是达到了 Qt规定的默认鼠标没有变化的时候,才停止输出。
ui->pushButton->installEventFilter(this); 在本例中,接收者本身就是自己,因此,实际上, return true; 进行拦截,是没有意义的。除非信号的发出者和接收者,不是同一个部件。
可能原因(?错误的分析 ?):冲突导致的问题?只要光标处在 pushButton的有效范围之内,信号的发出者(也是信号的接收者)就一直有条件地输出Debug_22;同时,信号的发出者又发出拦截信号,于是,由于Qt unlikely 的算法 if (Q_UNLIKELY(m_mapped)) 存在着某种问题,就造成了这种错误??
临时解决:
取消 (1)(2)两句,则 OK。 why ????????
从 源码说明abc 处来看:在这个例子中,取消掉,应该是没有问题的。
源码:
https://github.com/qt/qtbase/blob/dev/src/plugins/platforms/xcb/qxcbwindow.cpp
void QXcbWindow::setNetWmStateOnUnmappedWindow()
{
if (Q_UNLIKELY(m_mapped))
qCWarning(lcQpaXcb()) << "internal error: " << Q_FUNC_INFO << "called on mapped window";
C++关键字之likely和unlikely
什么是likely和unlikely
既然程序是我们程序员所写,在一些明确的场景下,我们应该比CPU和编译器更了解哪个分支条件更有可能被满足。
我们是否可将这一先验知识告知编译器和CPU, 提高分支预测的准确率,从而减少CPU流水线分支预测错误带来的性能损失呢?答案是可以!它便是likely和unlikely。
likely()与unlikely()函数的作用
https://blog.youkuaiyun.com/q2519008/article/details/83929064
#define likely(x) __builtin_expect(!!(x), 1)
也就是说明x==1是“经常发生的”或是“很可能发生的”。
所以使用likely ,执行if后面语句的可能性大些,编译器将if{}是的内容编译到前面
使用unlikely ,执行else后面语句的可能性大些,编译器将else{}里的内容编译到前面。
以上操作是有利于cpu预取,提高预取指令的正确率,因而可提高效率。
————————————————
QtConcurrent多线程 - map、mapped和mappedReduced
https://blog.youkuaiyun.com/douzhq/article/details/104758445
未解决:
结论:
有时,采用其他方法,比如定时器法,也不错。
毕竟 Qt IDE开发工具本身,也是有 bug的。
直接获取屏幕坐标
https://blog.youkuaiyun.com/Larry_Yanan/article/details/125046472
Qt:QPushButton 单击、双击响应区分
子类化
开发环境:win10+vs2015+qt5.9.1
背景:QPushButton的双击事件虽然一直有,但是在双击完成之前,总会响应到单击的事件处理或者连接槽,使用很不方便。自己子类化了一个QPushButton来区分这两种点击事件的处理
QT 中实现QLabel的点击事件(重写QLabel)
默认情况下,QLabel是不支持点击事件的,要实现QLabel的点击事件,一般有两种方式:
1、继承QLabel,重写鼠标点击事件,通过发送信号与父窗体实现通讯
2、安装事件过滤器,通过判断控件以及事件来实现
QToolButton双击事件
QToolButon自身信号不具有双击事件,如果想要实现双击事件,需要重写QToolButton。
首先需要继承QToolButtton,利用鼠标双击事件void mouseDoubleClickEvent(QMouseEvent *event);进行实现
MyToolButton.h
#ifndef MyToolButton_H
#define MyToolButton_H
#include <QtWidgets/QWidget>
#include <QtGui/QMouseEvent>
#include <QtWidgets/QToolButton>
//带双击事件的QToolButoon
class MyToolButton : public QToolButton
{
Q_OBJECT
public:
explicit MyToolButton(QWidget * parent = 0);
~MyToolButton();
//实现QToolButton左键双击事件
virtual void mouseDoubleClickEvent(QMouseEvent *event);
signals:
//双击信号
void doubleClicked();
};
#endif //MyToolButton_H
MyToolButton.cpp
#include "MyToolButton.h"
MyToolButton::MyToolButton(QWidget * parent) : QToolButton(parent)
{
}
MyToolButton::~MyToolButton()
{
}
//实现QToolButton左键双击事件
void MyToolButton::mouseDoubleClickEvent(QMouseEvent *event)
{
/* 也可在此写双击想要实现的事件*/
//如果需要自定义控件,则发送左键双击信号
//如果双击事件则发送双击事件信号
if (event->button() == Qt::LeftButton)
{
emit doubleClicked();
}
}
继承重写后接口实现双击事件,在需要使用的文件中加上MyToolButton.h文件,连接信号槽事件接口。
//创建自定义QToolButton
MyToolButton * m_toolButoon = new MyToolButton;
//连接信号槽事件
connect(m_toolButoon, SIGNAL(doubleClicked()), this, SLOT(slotTableShow1()));
————————————————
版权声明:本文为优快云博主「没有网名L」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/RYIJU5YUJTY/article/details/125404947
重写mouseDoubleClickEvent()函数
https://blog.youkuaiyun.com/qq_40714324/article/details/88862370
QPushButton实现双击效果
废话不多说,直接贴代码。只需继承QPushButton再重写mouseDoubleClickEvent()函数即可。这里判断了左键双击发出一个自定义信号doubleClicked()。
class Mybtn :public QPushButton
{
Q_OBJECT
public:
explicit Mybtn(QWidget *parent = 0):QPushButton(parent){}
virtual void mouseDoubleClickEvent(QMouseEvent *event) {
if(event->button() == Qt::LeftButton) {
emit doubleClicked();
}
}
signals:
void doubleClicked();
};
QT按钮实现鼠标双击事件 (***)
利用事件过滤器实现按钮双击功能,新手第一次写这个,网上找不到方便的方法,所以就直接上代码了。
首先,在需要点击的按钮或者控件设置事件过滤器。
例如:
ui->btnPressure->installEventFilter(this);
.......................
然后在.h文件添加事件函数
bool MainWindow::eventFilter(QObject *watched, QEvent *event);
在.cpp文件实现 ,另:项目需要用的比较多,所以给合在一起了。注意分开就好。
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
if(watched==ui->btnPressure||watched==ui->btnStart||watched==ui->btnPause||watched==ui->btnUseTime||watched==ui->btnAuxiliary||watched==ui->btnUser||watched==ui->btnTrigger||watched==ui->btnExit)
{
if(event->type()==QEvent::MouseButtonDblClick)
{
QMouseEvent *e = static_cast<QMouseEvent *>(event);
if(e->button() == Qt::LeftButton)
{
if(watched==ui->btnPressure)
qDebug()<<"参数双击了按钮";
else if(watched==ui->btnStart)
qDebug()<<"开始双击了按钮";
else if(watched==ui->btnPause)
qDebug()<<"双压机双击了按钮";
else if(watched==ui->btnUseTime)
qDebug()<<"治疗时间机双击了按钮";
else if(watched==ui->btnAuxiliary)
qDebug()<<"反搏比双击了按钮";
else if(watched==ui->btnUser)
qDebug()<<"用户管理双击了按钮";
else if(watched==ui->btnTrigger)
qDebug()<<"触发模式双击了按钮";
else if(watched==ui->btnExit)
qDebug()<<"退出双击了按钮";
}
}
}
return QWidget::eventFilter(watched, event);
}
————————————————
版权声明:本文为优快云博主「缄默221」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/weixin_70432649/article/details/126643190
思考:
事件循环:本质上,就是“软中断”而已?
信号槽:本质上,就是复杂一些的信号发送小模块和信号接收模块而已?