当我在 QPushbutton 的位置发送或发布 QMouseEvent 时,不会发出其 clicked() 信号

Posted

技术标签:

【中文标题】当我在 QPushbutton 的位置发送或发布 QMouseEvent 时,不会发出其 clicked() 信号【英文标题】:When I send or post a QMouseEvent, at the position of a QPushbutton, its clicked() signal is not emitted 【发布时间】:2011-05-16 14:14:51 【问题描述】:

我尝试使用 kinect 为增强现实应用程序设计 gui。这个想法是,使用 kinect 骨架跟踪检测到的手通过手势控制应用程序。

这个问题与手势无关,因为我应用的这一部分工作正常。

在我的应用程序中,我想在执行单击手势时模拟鼠标单击。为此,我发送了两个事件,一个是mousebuttonpressed,一个是mousebuttonreleased,因为正常的点击也是一系列的按下和释放。

整个事情在 QWebView 上运行良好。在浏览器窗口中,我可以“单击”链接。

但由于某种原因,我无法“单击”QPushButton。不发出 clicked() 信号。 我有一个简短的例子来说明我的问题:

首先是main函数:

int main(int argc, char **argv)
    QApplication app( argc, argv );
    QWebViewButtons mainapp( 0, Qt::Window );
    app.setActiveWindow( &mainapp );
    mainapp.show();
    mainapp.setApplication( &app ); //this is a setter to also get access to the main application in the widget
    return app.exec();

这是我自己的小部件:

QWebViewButtons::QWebViewButtons(QWidget* parent, Qt::WindowFlags flags ): QWidget(parent, flags )
    this->m_ui.setupUi( this );
    QObject::connect( this->m_ui.pushButton, SIGNAL(clicked(bool)), this, SLOT( buttonClicked(bool) ) );


void QWebViewButtons::mousePressEvent( QMouseEvent* event )
    printf("mouse click, %d, %d\n", event->pos().x(), event->pos().y() );


void QWebViewButtons::buttonClicked( bool clicked )
    printf("slot button clicked\n");    


void QWebViewButtons::keyPressEvent( QKeyEvent* event )
    printf("Key pressed\n"); 
    QPoint pos( this->width()/2, this->height()/2 );
    QPoint global = this->mapToGlobal(pos);
    QWidget *w = this->m_app->widgetAt(global);
    //printf("widget under point of click: %s", w);
    QApplication::sendEvent( w, new QMouseEvent( QEvent::MouseButtonPress, pos, Qt::MouseButton::LeftButton, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier ) );
    QApplication::sendEvent( w, new QMouseEvent( QEvent::MouseButtonRelease, pos, Qt::MouseButton::LeftButton, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier ) );

我在这里遵循了建议: Qt Artificial mouse clicks doesnt work properly 并发送以将我的鼠标事件直接发送到 QPushButton。但这没有帮助。 我还尝试将鼠标事件发送到“this”或主应用程序。

现在我的想法已经不多了。 我想要的是,如果我按下任何键,就会调用 buttonClicked() 插槽。但是只有当我用鼠标单击按钮时才会调用我。 我怎样才能做到这一点?还是我的基本想法完全错误?

感谢您的想法。

【问题讨论】:

so by QWidget *w = this->m_app->widgetAt(global);你知道哪个按钮被激活了吗?但不能告诉应用它被点击了? 我知道哪个小部件在那个位置,然后我可以检查它是否是一个按钮,并调用按钮的 click() 函数。但这不是我想要的,因为那样我就不需要发送鼠标事件了。我想要的是获得与单击鼠标左键相同的行为,并让 Qt 完成其余的工作,无论是否有按钮或其他任何东西。 【参考方案1】:

那么,我说对了吗?当你做你的“点击手势”时,你会进入 keyPressEvent 吗?如果是这样,您可以检查按钮上方是否已完成“单击”并显式调用按钮的 clicked() 信号。但这不是你想要的?

QWebViewButtons 到底是什么?用户在哪个区域做手势?

您是否已调试到 keyPressEvent 以查看您的 sendEvent 是否具有正确的小部件 (w)?我不明白为什么小部件不应该收到事件...

请记住,当新建一个 QMouseEvent 并通过 sendEvent 发送它时,它永远不会被删除。使用 sendEvent 时,您应该在堆栈上创建事件。

也许你应该看看这个线程,推荐使用 QTestEventList:Mimicking/faking a Mouse Click and Mouse Wheel using Qt。但我可以想象你不希望测试函数来解决问题;)

【讨论】:

我认为问题在于,我不知道应该将点击事件发送到哪个小部件/对象。在我的真实应用程序中,我不知道按钮在哪里,因为它们是通过布局定位的,甚至更糟。有几个小部件相互重叠,其中一些是透明的。在这个应用程序中,当我调用 widgetAt 函数时,即使单击它,我也没有得到按钮。它返回其他小部件之一。如果我将鼠标事件发送到该小部件,其中一些会到达我的按钮。但不是所有的。不幸的是我不能在这里发布代码,因为那太多了 在我上面评论中提到的应用程序中,我可以通过手势“单击”一个按钮。但是当我尝试点击另一个时,总是第一个得到 mouseclickevent。无论我第一次点击哪个按钮,所有后续点击都指向那个按钮。我怎么会导致这样的行为?【参考方案2】:

好的,诀窍是真正将点击发送到所需点击位置的 EXACT 小部件。在我的应用程序中,由于半透明的小部件彼此重叠,我遇到了一些麻烦。

所以 widgetAt(global) 命令对我没有帮助。 但是您可以改用 childAt(global) 。当然,您需要知道要从哪个小部件中找到孩子。

这对我有用。 :-)

【讨论】:

以上是关于当我在 QPushbutton 的位置发送或发布 QMouseEvent 时,不会发出其 clicked() 信号的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5:QPushButton 上的 setParent 不会将其添加到父级

如何通过单击 QPushButton 打印 QTableWidget

具体的 QPushButton 样式

应用样式表时 QPushButton 尺寸发生变化

Qt python如何知道QPushButton发送了哪些信号?

MousePressEvent 在 QPushbutton 上不起作用