如何从 Qt 插件中使用宿主应用程序的类?
Posted
技术标签:
【中文标题】如何从 Qt 插件中使用宿主应用程序的类?【英文标题】:How to use the classes of the host application from a Qt plugin? 【发布时间】:2016-08-24 00:53:43 【问题描述】:我通过创建 Qt C++ 插件来扩展我的应用程序的功能时遇到了链接问题。代码可以编译并且一切正常,但只要我使用 Qt 库类,例如 QString。当我为插件的类提供对主机应用程序中定义的类中的对象的引用时,该项目不再链接。创建插件 我遵循 Qt 文档中的过程并考虑给定的示例 - echo 和 plug&paint。但是,这种情况不在此列。
更新
这是错误:
myPlugin.obj:-1: error: LNK2019: unresolved external symbol "public: class QString __cdecl myClass::answer(void)const" (?answer@myClass@@QEBA?AVQString@@XZ) 在函数中引用public: 虚拟类 QString __cdecl myPlugin::echo(class myClass *)" (?echo@myPlugin@@UEAA?AVQString@@PEAVmyClass@@@Z)
这是导致它的项目:
plugtest.pro
TEMPLATE = subdirs
SUBDIRS += \
host \
plugin
host.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = host
TEMPLATE = app
SOURCES += main.cpp\
MainWindow.cpp \
myClass.cpp
HEADERS += MainWindow.h \
myClass.h \
plugInterface.h
FORMS += MainWindow.ui
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMessageBox>
#include <QPluginLoader>
#include <QDir>
#include "myClass.h"
#include "plugInterface.h"
namespace Ui
class MainWindow;
class MainWindow : public QMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_button_clicked();
private:
bool loadPlugin();
Ui::MainWindow *ui;
plugInterface *m_interface;
myClass *m_class;
;
#endif // MAINWINDOW_H
myClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
class myClass : public QObject
Q_OBJECT
public:
explicit myClass(QObject *parent = 0);
QString answer() const;
void setAnswer(const QString &str);
private:
QString m_answer;
;
#endif // MYCLASS_H
plugInterface.h
#ifndef PLUGINTERFACE_H
#define PLUGINTERFACE_H
#include <QString>
#include "myClass.h"
class plugInterface
public:
virtual ~plugInterface()
virtual QString echo(myClass *value) = 0;
;
#define PlugInterface_iid "example.suite.app.PluginInterface"
Q_DECLARE_INTERFACE(plugInterface, PlugInterface_iid)
#endif // PLUGINTERFACE_H
MainWindow.cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
ui->setupUi(this);
if (!loadPlugin())
QMessageBox::information(this, "Error", "Could not load the plugin");
m_class = new myClass(this);
m_class->setAnswer("Good!");
MainWindow::~MainWindow()
delete ui;
bool MainWindow::loadPlugin()
QDir pluginsDir(qApp->applicationDirPath());
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
pluginsDir.cd("plugins");
foreach (QString fileName, pluginsDir.entryList(QDir::Files))
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
QObject *plugin = pluginLoader.instance();
if (plugin)
m_interface = qobject_cast<plugInterface *>(plugin);
if (m_interface)
return true;
return false;
void MainWindow::on_button_clicked()
ui->lineResult->setText(m_interface->echo(m_class));
myClass.cpp
#include "myClass.h"
myClass::myClass(QObject *parent) : QObject(parent)
QString myClass::answer() const
return m_answer;
void myClass::setAnswer(const QString &str)
m_answer = str;
plugin.pro
TEMPLATE = lib
CONFIG += plugin
QT += widgets
INCLUDEPATH += ../host
HEADERS = myPlugin.h
SOURCES = myPlugin.cpp
TARGET = $$qtLibraryTarget(myPlugin)
DESTDIR = ../plugins
myPlugin.h
#ifndef MYPLUGIN_H
#define MYPLUGIN_H
#include <QObject>
#include "plugInterface.h"
class myPlugin : public QObject, plugInterface
Q_OBJECT
Q_PLUGIN_METADATA(IID "example.suite.app.PluginInterface")
Q_INTERFACES(plugInterface)
public:
QString echo(myClass *value) Q_DECL_OVERRIDE;
;
#endif // MYPLUGIN_H
myPlugin.cpp
#include "myPlugin.h"
QString myPlugin::echo(myClass *value)
return value->answer();
【问题讨论】:
您不认为错误消息可能相关吗? 当然。我将使用代码和错误更新问题。 【参考方案1】:对我有用的解决方案是使 myClass 成为库的一部分,并将其动态包含在插件和主机中。但是,我很好奇这是否可以在不创建库的情况下完成。
【讨论】:
以上是关于如何从 Qt 插件中使用宿主应用程序的类?的主要内容,如果未能解决你的问题,请参考以下文章
如何从基于 QObject 的类方法返回 QList<double> 以在 Qt 脚本中使用
Qt或通用c++如何在c++中获取或检测<a href="file.html" >的宿主