gpt4 book ai didi

qt - 将自定义 QEvent 传播到 Qt/PyQt 中的父窗口小部件

转载 作者:行者123 更新时间:2023-12-02 00:52:57 24 4
gpt4 key购买 nike

首先,对于问题的长度表示歉意。

我正在尝试将自定义 Qt 事件从子窗口小部件传播到顶级父窗口小部件,以便根据事件类型而不是链接信号触发某些操作。

Qt 文档建议使用具有 accept()ignore() 方法的 postEvent() 发布的每个事件都可以传播(这意味着每个 QEvent 子类)。

我尝试重写 customEvents 方法而不是 events 但无济于事。

Python

我已经使用 PyQt4 在 Python 中尝试过此操作(Qt 版本是 4.6)。

from PyQt4.QtGui import *
from PyQt4.QtCore import *

class Foo(QWidget):
def doEvent(self):
QApplication.postEvent(self, QEvent(12345))

def event(self, event):
event.ignore()
return False

class Bar(QWidget):
def __init__(self, *args, **kwargs):
super(Bar, self).__init__(*args, **kwargs)
self.foo = Foo(self)
layout = QHBoxLayout()
layout.addWidget(self.foo)
self.setLayout(layout)

def event(self, event):
if event.type() == 12345:
self.someEventHandler()
return True

def someEventHandler(self):
print 'Handler in {0}'.format(self.__class__.__name__)

if __name__=='__main__':
app = QApplication([''])
bar = Bar()
bar.show()
bar.foo.doEvent()
app.exec_()

在此示例中,Bar.someEventHandler() 仅当使用 self.parent() 作为第一个参数发布事件时才会触发,如下所示:

def doEvent(self):
QApplication.postEvent(self.parent(), QEvent(12345))

这是可以理解的,因为事件直接传递给接收对象。

C++

C++ 中的类似示例:

foobar.h

#ifndef FOOBAR_H
#define FOOBAR_H

#include <QtGui>

class Foo : public QWidget
{
Q_OBJECT

public:
Foo(QWidget *parent = 0);
void doEvent();
bool event(QEvent *);
};


class Bar : public QWidget
{
Q_OBJECT

public:
Bar(QWidget *parent = 0);
Foo *foo;
bool event(QEvent *);
};

#endif // FOOBAR_H

foobar.cpp

#include "foobar.h"

Foo::Foo(QWidget *parent)
: QWidget(parent) {}

void Foo::doEvent() {
QEvent *event = new QEvent(QEvent::User);
QApplication::postEvent(this, event);
}

bool Foo::event(QEvent *event)
{
event->ignore();
return QWidget::event(event);
}

Bar::Bar(QWidget *parent)
: QWidget(parent)
{
foo = new Foo(this);
}

bool Bar::event(QEvent *event)
{
if (event->type() == QEvent::User) {
qDebug() << "Handler triggered";
return true;
}
return QWidget::event(event);
}

ma​​in.cpp

#include <QtGui>
#include "foobar.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Bar bar(0);
bar.show();
bar.foo->doEvent();
return app.exec();
}

与 python 中相同,只有当事件直接传递给对象时才有效。

void Foo::doEvent() {
QEvent *event = new QEvent(QEvent::User);
QApplication::postEvent(this->parentWidget(), event);
}

也许我没有捕获重点,是否有可能只有按键和鼠标事件向上传播?

最佳答案

我花了一些时间浏览 Qt 源代码来回答你的问题,我最终想到的是:事件到父窗口小部件的传播是由 QApplication::notify 执行的,基本上是一个包含各种事件的长 switch 语句。例如,QEvent::WhatsThisClicked 的实现方式如下:

...
case QEvent::WhatsThisClicked:
{
QWidget *w = static_cast<QWidget *>(receiver);
while (w) {
res = d->notify_helper(w, e);
if ((res && e->isAccepted()) || w->isWindow())
break;
w = w->parentWidget();
}
}
...

现在,重点是:这不会对用户定义的事件(以及许多其他显式处理的标准 Qt 事件)执行,因为 default 子句是:

 default:
res = d->notify_helper(receiver, e);
break;

并且 notify_helper 不会传播事件。所以,我的答案是:显然,用户定义的事件不会传播到父小部件,您必须自己执行此操作(或者更好:覆盖 QApplication::notify (它是虚拟公共(public)成员)并添加您的事件的事件传播)。

希望对您有所帮助。

关于qt - 将自定义 QEvent 传播到 Qt/PyQt 中的父窗口小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3180506/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com