QT中Qbutton内的鼠标按下事件

mouse press event inside Qpushbutton in QT

本文关键字:事件 鼠标 Qbutton QT      更新时间:2023-10-16

我正在使用qt创建者制作一个计算器。有一个默认的主窗口窗体具有gui。在mainwindow.cpp中,我设置了setMouseTracking(true),以便在单击时获得鼠标坐标。但我只有在主窗口窗体中的任何按钮外单击时才能获得鼠标坐标。我想这与这样一个事实有关,即当单击按钮时,已经生成了某种鼠标事件来处理该单击。我需要在点击按钮时获得坐标。我该怎么做?

首先:这是个坏主意:)

您要做的是捕获发送给子对象的事件。一种方法是重新实现子对象的事件处理程序。但是当你使用设计器来构建你的界面时,这会变得有点困难。您必须将所有小部件升级为它们的重新实现版本。

另一种方法是使用Qt的"偶数滤波器"功能。您实现了一个基于QObject的类,该类实现了通用事件处理程序函数。然后将此对象作为"事件过滤器"安装在目标对象上。一个简单的偶数筛选器类如下所示;

class Filter : public QObject
{
protected:
    bool eventFilter(QObject *obj, QEvent *ev)
    {
        // obj : original receiver of the event
        // ev : any event that is sent to 'obj'
        QObject::event(obj, ev);
    }
};

及其用途:

Filter filterObject;
targetObject.installEventFilter(filterObject);

通常,您必须将此事件过滤器安装到用户界面中的所有对象(小部件)。但是,如果将此筛选器安装到QApplication实例,它将捕获应用程序中的所有事件,而不是逐个执行。捕获后,您可以根据事件的类型和发起人对其进行筛选。

下面是一个更完整的示例,它将捕获应用程序中的所有鼠标按下事件;

class ClickFilter : public QObject
{
protected:
    bool eventFilter(QObject *obj, QEvent *ev)
    {
        if (ev->type() == QEvent::MouseButtonPress && obj->inherits("QWidgetWindow"))
        {
            QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(ev);
            qDebug() << "clicked:" << mouseEvent->pos();
        }
        return QObject::eventFilter(obj, ev);
    }
};

您应该在QApplication实例上安装这个事件过滤器对象,大概是在main函数中;

QApplication a(argc, argv);
ClickFilter cf;
a.installEventFilter(&cf);

这将捕获应用程序中的所有事件(包括所有窗口-如果应用程序有多个主窗口),然后按类型和原始对象类型进行筛选。

但是这个代码有一个问题。我已经使用了QWidgetWindow类型来检查事件发起者。这是因为如果一个事件没有被一个子窗口小部件处理,它就会传播到它的父窗口小部件。因此,在某些情况下,ClickFilter::eventFilter会为同一点击事件调用多次。我选择QWidgetWindow是因为它看起来很简单;QWidgetWindow是一种内部Qt类型。在应用程序中使用它不是一个好主意。我相信还有另一种防止重复的方法。

更重要的是,在QApplication实例上安装事件过滤器不是一个好主意,这可能会导致性能问题。但另一方面,在我的应用程序中,我使用这种方法可以在整个应用程序中轻松地将工具栏按钮的键盘快捷键添加到工具提示中。你可以在这里看到。

时间有点晚了,但解决方案就是解决方案。有人占了便宜。

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMouseEvent> // important!!!
#include <QEvent> // important!!!
//..... bla bla
//..... bla bla
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
//..... bla bla
protected:
    bool eventFilter(QObject *watched, QEvent *event); // important!!!
//..... bla bla

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
//..... bla bla
    
MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
       qApp->installEventFilter(this); // important!!!
    
 //..... bla bla
    
    bool MainWindow::eventFilter(QObject *watched, QEvent *event){
        
        if(  event->type() == QEvent::MouseButtonPress){
            qDebug() << watched->objectName() << event->type();
            QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
            qDebug() << "clicked:" << mouseEvent->pos();
            return true;
        }
        return false;
    }

就是这样!