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

发布于 2024-11-07 16:41:43 字数 2187 浏览 4 评论 0 原文

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

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

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

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

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

首先是主要功能:

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 人工鼠标点击无法正常工作 并发送将我的鼠标事件直接发送到 QPushButton。但这没有帮助。 我还尝试将鼠标事件发送到“this”或主应用程序。

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

感谢您的想法。

I try to design a gui for an augmented reality application using the kinect. The idea is, to use the hands detected by the kinect skeleton tracking to control an application via gestures.

This question is not about gestures, as this part of my appilcation works fine.

In my application i want to simulate a mouse click whenever a click gesture is performed. To do this, i am sending two events one, mousebuttonpressed, and one mousebuttonreleased, as a normal click is also a series of press and release.

The whole thing works fine on a QWebView. In the browser window, i can "click" on links.

But for some reason i cannot "click" on a QPushButton. The clicked() signal is not emitted.
I have a short example to illustrate my problem:

First the main function:

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();
}

This is my own widget:

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 ) );
}

I followed the suggestion here:
Qt Artificial mouse clicks doesnt work properly
and send to send my mouse events directly to the QPushButton. But that didn't help.
I also tried to send the mouse events to "this", or the main app.

Now I am running out of ideas.
What I want to have is, that the buttonClicked() slot is called if i press any key. But i only is called if i click the button with my mouse.
How can i accomplish this? Or is my basic idea completely false?

Thanks for your ideas.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

佞臣 2024-11-14 16:41:43

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

QWebViewButtons 到底是什么?用户做出手势的区域?

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

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

也许您应该看看这个线程,其中推荐使用 QTestEventList: 使用 Qt 模仿/伪造鼠标点击和鼠标滚轮。但我可以想象你不希望测试函数起到作用;)

So, do I get that right? When doing your "click-gesture" you come into keyPressEvent? If so, you can check whether the "click" has been done above the button and explicitly call the button's clicked() signal. But that's not what you want?

And what exactly is QWebViewButtons? The area the user does his gestures in?

Have you debugged into the keyPressEvent to see if your sendEvent has the correct widget (w)? I can't see why the widget should not recieve the event...

And remember that when new'ing a QMouseEvent and sending it via sendEvent is is never deleted. When using sendEvent you should create your event on the stack.

Maybe you should have a look at this thread, where a QTestEventList is recommended: Mimicking/faking a Mouse Click and Mouse Wheel using Qt. But I can imagine that you don't want test functions do the trick ;)

嗳卜坏 2024-11-14 16:41:43

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

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

这对我来说很有效。 :-)

Ok, the trick was to really send the click to the EXACT widget at the desired click position. In my application i had some trouble because of semi transparent widgets lying over each other.

So the widgetAt(global) command wouldnt help me.
But you can use childAt(global) instead. Of course you need to know from which widget you want to find the child.

That did the trick for me. :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文