Qt中 mouseMoveEvent 无效 (***)

目录

qt控件鼠标事件失效的可能的处理办法 (*****)

控件重写mousePressEvent 时,点击在button时没有反应(*****)   https://bbs.csdn.net/topics/392071102

Qt::WA_TransparentForMouseEvents用法 (***)

Qt鼠标事件触发不了(**)

Qt事件穿透,解决QMouseEvent无效的问题

Qt中 mouseMoveEvent 无效

QTableWidget 安装事件过滤器无法监听到鼠标按下事件

Qt 实现控件不响应鼠标点击事件

------------------------------------

======================

控件重写mousePressEvent 时,点击在button时没有反应 (*****)

https://bbs.csdn.net/topics/392071102

控件重写mousePressEvent 时,点击在button时没有反应

    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
        btn1 = new QPushButton(this);
        btn2 = new QPushButton(this);
        btn3 = new QPushButton(this);

        layout1 = new QVBoxLayout;
        layout1->addWidget(btn1);
        layout1->addWidget(btn2);
        layout1->addWidget(btn3);

        setLayout(layout1);
        this->setFixedSize(400,400);
    }

    Widget::~Widget()
    {

    }

         

    void Widget::mousePressEvent(QMouseEvent *event)
    {
        qDebug()<<"click";  //当点击在button上时没反应
        QWidget::mousePressEvent(event);
    }


Little柯南 2017-01-04

我们来详细分析下你的程序:

1、void Widget::mousePressEvent(QMouseEvent *event);//对吧,你的鼠标点击事件是相对widget的,所以你点击你的widget才会将这个事件生效

2、我们怎么实现button点击有这个效果了?安装事件管理器,详见下面:

//安装在部件

button->installEventFilter(this);  //对比 this->installEventFilter(this);

                 

bool widget::eventFilter(QObject *obj, QEvent *event)

{

        QMouseEvent *MouseEvent = static_cast<QMouseEvent *>(event);  //注1

        if ((event->type() == QEvent::MousePressEvent) && (MouseEvent->buttons() ==         Qt::LeftButton))  // MousePressEvent-->>MouseButtonPress

        {

                //这里边写你的操作

        }

        return QDialog::eventFilter(obj, event);

}

注1: Qt QEvent 转换为 QMouseEvent ,QKeyEvent....等子类

QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);

注2: QT学习(三)事件过滤器   https://blog.csdn.net/Cold_Sun_/article/details/100024728

注3:Qt默认的部件,自带了各种鼠标单击/双击等等之类的槽函数,使用起来简单。

但是,如果需要重写鼠标事件函数,则需要采用不同的思路来重写实现这些功能。

注4: this->installEventFilter(this);:表示事件过滤器被安装在整个窗口上,整个窗口所有的坐标点都是事件接收者。应用场景:绘图等。

1. 输出结果:鼠标只要在 整个窗口的有效范围之内,就会发生事件捕获。除非鼠标不动达到 Qt设计的规定时,才会停止继续执行捕获的操作。

event 000: QHoverEvent(HoverMove, 0x77c010)

event 000: QHoverEvent(HoverMove, 0x77c010)

event 000: QMouseEvent(NonClientAreaMouseMove, localPos=-5,515, screenPos=887,652)

event 000: QEvent(Leave, 0x77c470)

event 000: QHoverEvent(HoverLeave, 0x77c4d0)

event 000: QEvent(WindowDeactivate, 0x77c850)

event 000: QEvent(ActivationChange, 0x77c810)

button->installEventFilter(this); 表示事件过滤器被安装在button上,整个button所有的坐标点都是事件接收者。应用场景:按钮、开关等。

输出结果:与this->installEventFilter(this);的唯一区别?鼠标只要在 整个button的有效范围之内,。。。

注5: Qt 默认的 pushButtun,具有相应鼠标 “双击”槽函数的功能。但是,一但重写了事件函数,此时,pushButtun的鼠标点击功能就会失效了。只有官方默认的、pushButtun事件函数才具有鼠标捕获功能。

重写之后,需要使用 installEventFilter(this);函数,有用户来重新实现 pushButtun的鼠标功能。一般是在 widget类窗口中实现,而不是在每一个部件的类中实现(这种实现方法,太重复了、繁琐、啰嗦)。

这种实现方法,与官方默认的 pushButtun鼠标点击槽函数的实现方法,表面上似乎是不相同的实现方法。

未狂 2017-01-03
 明明写的是 QWidget的mousePreeEvent,凭什么让QPushButton有反应

小乌龟在大乌龟背上 2016-12-29

你明明widget来重写的,当然点击button没用,点击widget才有用

注:

1. 这里仅对 widget有效,即点击 widget的任何一个地方,都有效。

2. 点击部件无效。除非:

ui->radioButton->setAttribute(Qt::WA_TransparentForMouseEvents, true);

DreamLife. 2017-01-04
 需要注册才可以  //自定义事件,才需要吧?

菜园小火车 2016-12-30
 一种方法:判断press的时候鼠标是否在范围里面发送信号。

2,做一个信号,把btn的信号连接过来。 还有一种InstanllEvent啥的 貌似也可以的

参考:

Qt中为控件重写鼠标点击事件!!!

引用 4 楼 chengchaooppo 的回复:

installEventFilter  可以实现.


注2:QT学习(三)事件过滤器

https://blog.csdn.net/Cold_Sun_/article/details/100024728

在设计的过程中遇到了一个问题,我在派生类里重载了mousemoveevent,程序运行时,发现点击这个派生类时,主窗口也会接收到这个事件。

解决方法:在定义的派生类中添加事件过滤器,接收到mousemoveevent事件后就将其处理不让其继续向下传递。

以下为代码:

先注册事件过滤器:

this->installEventFilter(this);

因为想要过滤的控件注册,因为我这里是对这个类进行过滤故用this

然后就是重载eventFilter

bool eventFilter(QObject *target,QEvent *event);

bool Animationbutton::eventFilter(QObject *target,QEvent *event)
{
    if (target==this)
    {
        if (event->type()==QEvent::MouseMove)
        {
            mouseClicked();
            return true;
        }
        else
            return false;
    }
    else
        return QWidget::eventFilter(target,event);
}

这样在运行的时候就解决了上述问题。
————————————————
版权声明:本文为CSDN博主「Cold_Sun_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Cold_Sun_/article/details/100024728

=================================

qt控件鼠标事件失效的可能的处理办法 (*****)

https://blog.csdn.net/Johnisjohn/article/details/88690613

Qt程序中,比如我们有一个控件,但是这个控件的鼠标按钮失效了,而控件外侧的鼠标事件却没有失效,原因可能是没有给这个控件做如下设置:

ui->radioButton->setAttribute(Qt::WA_TransparentForMouseEvents, true);

Qt::WA_TransparentForMouseEvents用法 (***)

Qt助手中对Qt::WA_TransparentForMouseEvents的解释如下:

When enabled, this attribute disables the delivery of mouse events to the widget and its children. Mouse events are delivered to other widgets as if the widget and its children were not present in the widget hierarchy; mouse clicks and other events effectively "pass through" them. This attribute is disabled by default.

大意是:

当该属性被激活启用时,将会使所有发送到窗体和窗体内部子控件的鼠标事件无效

鼠标事件被分发到其它的窗体部件,就像本窗体部件及本窗体内的子控件没有出现在窗体层次体系中。

鼠标单击和鼠标其它事件高效地穿过(即绕开)本窗体部件及其内的子控件,这个属性默认是禁用未开启的。

测试例子如下:

    #include "QtWidgetsApplication1.h"
    #include "QtTestWidget.h"
    #include<QDebug>
     
    QtWidgetsApplication1::QtWidgetsApplication1(QWidget* parent)
        : QWidget(parent)
    {
        ui.setupUi(this);
     
        setWindowTitle("parent");
     
        QtTestWidget* p = new QtTestWidget(this);
     
        QVBoxLayout* pLayout = new QVBoxLayout(this);
        pLayout->addWidget(p);
        pLayout->addWidget(ui.pushButton);
        setLayout(pLayout);
     
        // 设置本窗体上的类型为QtTestWidget的子窗体p的
        // Qt::WA_TransparentForMouseEvents属性为true,则
        // 在p上单击鼠标左键,不能响应QtTestWidget的mousePressEvent函数。
        p->setAttribute(Qt::WA_TransparentForMouseEvents, true);
     
        // 本窗体将Qt::WA_TransparentForMouseEvents设置为true,在本窗体单击鼠标左键
        // 依然能进入本窗体的mousePressEvent函数。
        setAttribute(Qt::WA_TransparentForMouseEvents, true);
     
        // 设置本窗体上的一个按钮的Qt::WA_TransparentForMouseEvents为true,则
        // 单击该按钮,不能进入按钮的单击信号响应槽函数btnClicked。
        ui.pushButton->setAttribute(Qt::WA_TransparentForMouseEvents, true);
       
        connect(ui.pushButton, &QPushButton::clicked, this,    &QtWidgetsApplication1::btnClicked);
    }
     
    QtWidgetsApplication1::~QtWidgetsApplication1()
    {
        
    }
     
    // 当按钮的Qt::WA_TransparentForMouseEvents为true,单击按钮,该函数不能响应
    void QtWidgetsApplication1::btnClicked()
    {
        
        qDebug() << "btnClicked" << "\r\n";
    }
     
    // 即使设置了本窗体的Qt::WA_TransparentForMouseEvents为true,该函数依然能进入
    void QtWidgetsApplication1::mousePressEvent(QMouseEvent* event)
    {
        qDebug() << "mousePressEvent" << "\r\n";
    }

QtTestWidget.cpp如下:

    #include "QtTestWidget.h"
    #include<QDebug>
     
    QtTestWidget::QtTestWidget(QWidget *parent)
        : QWidget(parent)
    {
        ui.setupUi(this);
        
    }
     
    QtTestWidget::~QtTestWidget()
    {
    }
     
    void QtTestWidget::btnClicked()
    {
     
    }
     
     
    void QtTestWidget::mousePressEvent(QMouseEvent* event)
    {
        
        qDebug() << "5555" << "\r\n";
        QWidget::mousePressEvent(event);
    }

在QtWidgetsApplication1的非pushButton占据区域即子窗体QtTestWidget占据的区域上单击鼠标右键,结果如下:

    mousePressEvent
     
    mousePressEvent

可见QtTestWidget::mousePressEvent没响应,单击pushButton,输出结果依然是上面的,可见pushButton槽函数没响应。QtWidgetsApplication1窗体即本窗体设置了setAttribute(Qt::WA_TransparentForMouseEvents, true), 但本窗体的mousePressEvent依然响应了,可见Qt::WA_TransparentForMouseEvents只对本窗体内的子窗体有效,对本窗体无效,跟Qt助手说的还是有些不同。

Qt::WA_TransparentForMouseEvents的一个应用场景如下:

有个需求:在业务开始时,线程自动向每个按钮发送clicked()信号,按钮接收到该信号后,执行该信号,从而模拟人单击按钮,

但整个业务过程中,按钮不能接收键盘鼠标事件,防止人干扰线程自动模拟按钮的执行。

首先想到的是调用按钮的setEnable(false)函数,这样确实可以使按钮不接收键盘鼠标消息,但按钮也不响应 clicked()信号了,也就是达不到用线程模拟人工手动按按钮的功能。

正确的做法是利用如下代码:

pBtn->setAttribute(Qt::WA_TransparentForMouseEvents, true);

即将按钮的Qt::WA_TransparentForMouseEvents设置为true。
————————————————
版权声明:本文为CSDN博主「荆楚闲人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/danshiming/article/details/121589114

Qt鼠标事件触发不了(**)

1.如果只是mouseMoveEvent事件无法触发的话,那么很可能是缺少了“this->setMouseTracking(true);”,因为其特别消耗计算机的资源,默认关闭了。


2.如果其他事件(如mouseReleaseEvent和mousePressEvent)也不行,那么很可能是因为鼠标放在了控件上,比如你修改了QtWidget的鼠标按压事件,那么你在上面控件上按压鼠标是不会触发的。
————————————————
版权声明:本文为CSDN博主「Mr.Qin_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qinqinxiansheng/article/details/104401560

Qt事件穿透,解决QMouseEvent无效的问题

问题:父窗口的QMouseEvent无法捕获子窗口的鼠标移动事件
原因:

1、即使父窗口设置了 this->setMouseTracking(true); 还是无法捕获子窗口的鼠标移动事件,这时候只需要将子窗口也进行同样设置 ui->subWidget->setMouseTracking(true);

2、子窗口内实现了 void mouseMoveEvent(QMouseEvent *); ,因此,事件在被子窗口的事件处理器接收后就不会发给父窗口了,解决办法是自己发送一个事件给父窗口。
方法:

    QMouseEvent *mEvent = new QMouseEvent(QEvent::MouseMove, event->pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
    QApplication::postEvent(this->parentWidget(), mEvent);

自己创建信号,填入需要的参数(事件类型、事件发生坐标、鼠标点击、鼠标点击状态、组合键状态),可以自行参考文档。
相当于将信号继续传递下去,且指定接收控件,加入到接收控件的事件队列里。
————————————————
版权声明:本文为CSDN博主「风语者和波波娃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41997274/article/details/116309270

Qt中 mouseMoveEvent 无效

最近用Qt软件界面,需要用到mouseMoveEvent,研究了下,发现些问题,分享一下。

在Qt中要捕捉鼠标移动事件需要重写MouseMoveEvent,但是MouseMoveEvent为了不太耗资源在默认状态下是要鼠标按下才能捕捉到。要想鼠标不按下时的移动也能捕捉到,需要setMouseTracking(true)

bool mouseTracking

这个属性保存的是窗口部件跟踪鼠标是否生效

如果鼠标跟踪失效(默认),当鼠标被移动的时候只有在至少一个鼠标按键被按下时,这个窗口部件才会接收鼠标移动事件

如果鼠标跟踪生效,如果没有按键被按下,这个窗口部件也会接收鼠标移动事件。

QWidget中使用是没有问题的,但是,对于QMainWindow即使使用了setMouseTracking(true)依然无法捕捉到鼠标没有按下的移动,只有在鼠标按下是才能捕捉。

解决办法:要先把QMainWindow的CentrolWidget使用setMouseTracking(true)开启移动监视。然后再把QMainWindow的setMouseTracking(true)开启监视。之后就一切正常了。

原因:CentrolWidget是QMainWindow的子类,你如果在子类上响应鼠标事件,只会触发子类的mouseMoveEvent,根据C++继承和重载的原理,所以子类也要setMouseTracking(true); 所以如果你想响应鼠标事件的控件被某个父控件包含,则该控件及其父控件或容器也需要setMouseTracking(true);

转载地址:Qt中mouseMoveEvent在MainWindow中使用_齐北的博客-CSDN博客

QTableWidget 安装事件过滤器无法监听到鼠标按下事件

https://www.jianshu.com/p/0e601d52dee5

Qt 实现控件不响应鼠标点击事件

https://blog.51cto.com/u_15127653/3411929

QT中很多控件都有鼠标点击的事件响应,比如QPushButton,QRadioButton。有时候我们想要实现的是:当鼠标点击控件时,不会产生响应事件。其中的一种方法是使用Qt::WA_TransparentForMouseEvents。

官方对Qt::WA_TransparentForMouseEvents的说明为

When enabled, this attribute disables the delivery of mouse events to the widget and its children. Mouse events are delivered to other widgets as if the widget and its children were not present in the widget hierarchy; mouse clicks and other events effectively "pass through" them. This attribute is disabled by default.

大概的意思是当使能Qt::WA_TransparentForMouseEvents时,鼠标事件就不会传送到该控件及子控件,而是会传到其他的不包含该控件的widget上,这样的话其实就是实现了鼠标穿透的功能。

实现代码

ui->radioButton->setAttribute(Qt::WA_TransparentForMouseEvents, true);

使radioButton控件不响应鼠标点击事件。
-----------------------------------
Qt 实现控件不响应鼠标点击事件
https://blog.51cto.com/u_15127653/3411929

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值