【问题标题】:How to enumerate all QObject classes in Qt?如何枚举 Qt 中的所有 QObject 类?
【发布时间】:2011-10-06 15:25:12
【问题描述】:

有没有办法枚举在应用程序或 DLL 中声明的所有 QObject 类?我正在尝试创建一个加载 DLL 并列出 DLL 中的所有 QObject 类的应用程序。

更新:实际上我正在尝试创建一个单元测试 GUI。它将加载 DLL,在其中实例化 QObject,并针对它们调用 QTest::qExec。

【问题讨论】:

  • 你可以试试玩弄 moc
  • 您是要枚举 DLL 中使用的所有 QObject 的子类还是所有实例?
  • @AndréPuel 仅所有 QObject 子类,而不是它们的实例。

标签: c++ qt qobject


【解决方案1】:

如果程序代码没有被剥离,你可以通过阅读二进制文件来进行一些自省: objdump -demangle=C++ -t SomeQtLibrary.so |grep qt_static_metacall 它大致显示了 QObject 派生类。我认为他们都实现了这个符号。当然,因为您使用的是 Windows,所以您必须使用 Windows 工具,例如 nm(如果我错了,请纠正我)。自然地处理代码中的符号也是可能的,但这是一个单独的主题。

我提到的命令返回这个例子:

0000000000470c00 l     F .text  0000000000000014              QxtBoundFunction::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
00000000004392ea l     F .text  0000000000000158              MainWindow::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000000453b5c l     F .text  0000000000000091              QtLocalPeer::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000000438508 l     F .text  0000000000000014              MyApplication::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000000442cd0 l     F .text  0000000000000080              MessagePoll::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000000442ea2 l     F .text  0000000000000091              RFBClient::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000000467c3c l     F .text  000000000000436a              QxtRPCService::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000000439114 l     F .text  000000000000008f              MemoryPolling::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)

如果您对运行时自省感兴趣,则必须在每个对象上使用 QMetaObject 类。

对于注册为 QMetaType 的对象(并且只有那些!),您可以做一些额外的魔法来使它们栩栩如生。不是很容易,也不是开箱即用的——但这种静态语言仍然有很多东西。这是来自 Qt 文档的 sn-p(将 if(id == 0) 更改为 if(id))。

 int id = QMetaType::type("MyClass");
 if (id) {
     void *myClassPtr = QMetaType::construct(id);
     ...
     QMetaType::destroy(id, myClassPtr);
     myClassPtr = 0;
 }

【讨论】:

  • 不错的收获。但是,您不能总是从类名中看出它继承了哪些其他类,对吧?因此,例如,如果我将继承自 QObject 的类放入没有任何插槽的类中,您将永远无法告诉它。
  • 谢谢,但是如何实例化使用这种方式找到的类?很抱歉在最初的问题中没有提到实例化。
  • 更新了,但肯定是过头了。
  • 再次感谢,不应该是“if (id) {”吗?无论如何,QMetaType::type 应该有注册的类列表。我会追踪它。那应该可以解决问题。抱歉,由于我的声誉低,无法投票 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 1970-01-01
相关资源
最近更新 更多