gpt4 book ai didi

qt - QMetaCallEvent 的用途是什么以及如何访问其详细信息?

转载 作者:行者123 更新时间:2023-12-02 15:32:39 26 4
gpt4 key购买 nike

我有一个事件过滤器,我注意到当我单击展开/折叠 Twig 时我得到QEvent::MetaCall。我正在考虑使用它来滚动我自己的展开/折叠代码,但我不知道如何获取任何信息,例如项目的索引。

此 MetaCall 事件类型有什么可用的吗?

我发现有人在另一个网站上问过同样的问题,但没有答案,在这里: http://www.qtcentre.org/threads/37525-How-to-filter-QEvent-MetaCall

此事件通常用于什么?

最佳答案

最大的问题是:您到底想做什么?接收这些事件的 Qt 类是什么? 就我而言,您正在尝试以困难的方式做事,那为什么还要麻烦呢?

QMetaCallEvent是每当使用排队连接调用槽时表示槽调用的事件。这可能是由于连接到插槽的信号触发,或者由于使用 QMetaObject::invokeQMetaObject::invokeMethod 。排队连接位是重要的部分!默认情况下,排队连接用于同一线程中的对象之间的调用,因为它们具有事件队列管理开销,除非满足以下两个条件之一:

  1. 您提供Qt::QueuedConnection QObject::connect 的参数或QMetaObject::invoke[Method]

  2. 接收对象的thread()与发起调用的线程不同 - 在调用时。

QMetaCallEvent 事件类携带调用槽所需的信息。它包含发件人 QObject及其信号 ID(如果调用来自信号槽连接)、目标槽标识符以及需要传递到槽中的参数。

因此,您可以检查被调用的槽是否是您想要拦截的槽,以及传递给它的参数。例如,如果您使用单个 int 调用插槽参数,则*reinterpret_cast<int*>(metaCallEvent->args()[1])会给你该整数的值。第零个参数用于返回值(如果有),因此参数以基数 1 为索引。

免责声明QMetaCallEvent类是 Qt 实现的内部类,您将应用程序的二进制文件与完整的特定 Qt 版本(整个主要版本.次要版本)相关联,并且您将失去 Qt 在主要版本中提供的二进制兼容性的好处。当您切换到 Qt 的另一个次要版本时,您的代码可能仍然可以编译,但无法正常工作!

以下适用于Qt 5.2.0,其他版本我没有看过!

所以,假设您想拦截对 QLabel::setNum 的调用。您将捕获此类事件,如下所示:

#include <private/qobject_p.h> // Declaration of QMetaCallEvent

bool Object::eventFilter(QObject * watched, QEvent * event) {
QLabel * label = qobject_cast<QLabel*>(watched);
if (! label || event->type() != QEvent::MetaCall) return false;
QMetaCallEvent * mev = static_cast<QMetaCallEvent*>(event);
static int setNumIdx = QLabel::staticMetaObject.indexOfSlot("setNum(int)");
if (mev->id() != setNumIdx) return false;
int num = *reinterpret_cast<int*>(mev->args()[1]);
// At this point, we can invoke setNum ourselves and discard the event
label->setNum(num);
return true;
}

如果您想在全局范围内查看使用元调用系统调用的所有插槽,您也可以这样做。基类的模板参数化允许灵活地使用任何应用程序类 - 例如 QCoreApplication , QGuiApplication , QApplication ,或用户派生的类型。

template <class Base> class MetaCallWatcher : public Base {
MetaCallWatcher(int& argc, char** argv) : Base(argc, argv) {}
bool notify(QObject * receiver, QEvent * event) {
if (event->type() == QEvent::MetaCall) {
QMetaCallEvent * mev = static_cast<QMetaCallEvent*>(event);
QMetaMethod slot = receiver->metaObject()->method(mev->id());
qDebug() << "Metacall:" << receiver << slot.methodSignature();
}
return Base::notify(receiver, event);
}
}

int main(int argc, char ** argv) {
MetaCallWatcher<QApplication> app(argc, argv);
...
}

关于qt - QMetaCallEvent 的用途是什么以及如何访问其详细信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10887157/

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