我有一个使用QPluginLoader工具加载插件(.dll / .so)的C ++ / Qt应用程序。这个插件基本上是一个嵌入式的python解释器,它允许通过PyQt4模块检查主应用程序中的Qt对象。问题是即使从C ++应用程序创建了QCoreApplication实例,从插入的python解释器执行的命令PyQt4.QtCore.QCoreApplication.instance()仍返回None。仅在调试模式下的Windows上。在linux上或在Windows上的发布模式下,命令PyQt4.QtCore.QCoreApplication.instance()正确返回由C ++应用程序创建的QCoreApplication实例。以下是一些显示问题的极简代码。在发布模式下编译时:$ ./a.out1+12import PyQt4import PyQt4.QtCorePyQt4.QtCore.QCoreApplication.instance()<PyQt4.QtCore.QCoreApplication object at 0x00C69198>=>好吧在调试模式下编译时:$ ./a.outimport PyQt4import PyQt4.QtCorePyQt4.QtCore.QCoreApplication.instance()=>不好(未返回)文件main.cpp#include <QCoreApplication>#include <QPluginLoader>#include <QDebug>int main(int argc, char **argv){ QCoreApplication app(argc, argv); QPluginLoader loader("plugin.dll"); loader.setLoadHints(QLibrary::ResolveAllSymbolsHint | QLibrary::ExportExternalSymbolsHint); loader.load(); if(!loader.isLoaded()) { qDebug() << loader.errorString(); return 1; } (void)loader.instance(); return app.exec();}文件plugin.h#ifndef PLUGIN_H#define PLUGIN_H#include <QObject>#include <Python.h>class Plugin : public QObject{public: Plugin(); ~Plugin();private: PyThreadState *m_ts;};class InterpInput : public QObject{ Q_OBJECTpublic: InterpInput(QObject *parent = 0) : QObject(parent) { }public slots: void monitorInput();signals: void done(); void inputReady();};class InterpOutput : public QObject{ Q_OBJECTpublic: InterpOutput(QObject *parent = 0) : QObject(parent) { }public slots: void processLine();public: PyThreadState *m_ts;};#endif文件plugin.cpp#include "plugin.h"#include <QCoreApplication>#include <QThread>#include <QtPlugin>#include <QPluginLoader>Q_EXPORT_PLUGIN2(Plugin, Plugin)
2 回答
回首忆惘然
TA贡献1847条经验 获得超11个赞
解释如下。
在调试版本中,C ++应用程序和插件链接到调试Qt库(QtCored4.dll等),而已安装的PyQt4模块(QtCore.pyd等)链接到发行Qt库(QtCore4.dll等)。
因此,C ++应用程序和PyQt4模块每个都看到一个QCoreApplication实例,但是每个都看到一个不同的实例,该实例位于一个不同的库中(分别是Qt库的调试版本和发行版)。
随之而来的是,初始化C ++应用程序时,未初始化PyQt4模块中存在的实例,因此该实例为null。
通过编译PyQt4模块并指定它们应链接到调试Qt库来验证这一点:然后该问题消失,因为调试模式C ++应用程序和PyQt4模块链接到同一个Qt库。
有只小跳蛙
TA贡献1824条经验 获得超8个赞
或多或少。确实有变通方法来获取QCoreApplication实例。但是,潜在的问题(我还没有提到)是,如果需要QApplication的某些操作本身无法查看QApplication实例,则无法通过PyQt执行某些操作(例如QPixmap创建)。这些操作可以在自定义模块中从C ++封装到python,但这将重复PyQt应该执行的操作。
添加回答
举报
0/150
提交
取消