Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ QT中Qpushbutton内的鼠标按下事件_C++_Qt_Qpushbutton - Fatal编程技术网

C++ QT中Qpushbutton内的鼠标按下事件

C++ QT中Qpushbutton内的鼠标按下事件,c++,qt,qpushbutton,C++,Qt,Qpushbutton,我正在使用qt creator制作一个计算器。有一个带有gui的默认主窗口窗体。在mainwindow.cpp中,我设置了setMouseTracking(true),以在单击时获取鼠标坐标。但是我只有在主窗口窗体中的任何按钮外单击时才能获得鼠标坐标。我想这与一个事实有关,当点击一个按钮时,已经生成了某种鼠标事件来处理该点击。 我需要在按钮内单击时获取坐标。我该怎么做呢?第一件事:这是个坏主意:) 您试图做的是捕获发送到子对象的事件。一种方法是重新实现子对象的事件处理程序。但是,当您使用设计器构

我正在使用qt creator制作一个计算器。有一个带有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);
    }
};
这将捕获应用程序中的所有事件(包括所有窗口-如果应用程序有多个主窗口),然后按类型和发起人对象类型筛选它们

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


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

为什么需要坐标?请粘贴代码的相关部分。看起来您使用的是主窗口的setMouseTracking()函数,而不是QPushButton小部件中的一个
QAbstractButton::clicked
信号适合您。获取鼠标单击的坐标不需要鼠标跟踪。您总是在单击事件中获得这些坐标。唉,这些坐标有什么用?可能您正试图将来自多个按钮的
单击的
信号连接到同一插槽,并希望使用坐标来区分按钮。不过,这完全没有必要。
QApplication a(argc, argv);
ClickFilter cf;
a.installEventFilter(&cf);