问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何在MeeGo Qt应用程序中加载插件

发布网友 发布时间:2022-04-21 21:44

我来回答

2个回答

懂视网 时间:2022-04-22 02:05

热心网友 时间:2022-04-21 23:13

一、创建一个基于QWidget的窗体程序

1
演示示例创建的是一个基于QWidget类的窗体程序,当然你要使用其他窗体类也是可以的。
项目名称为EchoWindow,窗体类名采用的是默认的widget。项目位于明为MyPlugin的目录下。
整个的目录结构如下:

2
具体程序界面如下。点击发送后,将文本框的内容经过插件的简单处理后在黑色框线的标签控件中显示出来。

END
二、建立接口类

1
首先了解下什么是接口。
接口类就是,由纯虚函数构成的类。它是不能够被实例化的。
在Assistant中有简短的说明。如果类中没有虚函数会被编译器报错的。

2
下面我们来建立接口类。
在EchoWindow项目上右键,添加新文件。

3
在弹出的 新建文件 对话框中,我们选择C++,中间窗口选择 C++ Header File。然后点击choose。

4
输入名称 EchoInterface。当然,也可以是任何你喜欢的名字。点击下一步,然后点击完成。

5
我们来看看,EchoWindow项目的目录情况。

6
在EchoInterface.h中输入以下内容:
#ifndef ECHOINTERFACE
#define ECHOINTERFACE#include <QString>class EchoInterface{
public:
virtual ~EchoInterface() {}
virtual QString echo(const QString &message) = 0;
};
#define EchoInterface_iid "Examples.Plugin.EchoInterface"
Q_DECLARE_INTERFACE(EchoInterface, EchoInterface_iid)
#endif // ECHOINTERFACE

7
可以看到类中只有一个纯虚函数。
Q_DECLARE_INTERFACE宏是为了让Qt的元对象系统知道这是一个接口。
同时还要注意那个iid,我们的是 "Examples.Plugin.EchoInterface",待会会用到。
好的,到此,我们的接口类编写完毕。
END
三、创建插件项目

1
点击文件菜单,新建文件或项目。

2
在弹出的 New File or Project 窗口中,我们选择,其他项目,Empty qmake project,然后choose。

3
在弹出的Empty qmake project窗口中,名称我们输入Plugin,路径我们按照第一步第一个图来存放,也就是与EchoWindow在同级目录下即可。然后,一直下一步,直到完成。

4
我们再来看看当前的整个项目结构。Plugin确实是个空项目,什么都没有。

5
我们在Plugin项目上右键,选择添加新文件,这个与添加那个接口类是一样的。在弹出的 新建文件 窗口中,我们选择C++,中间选择C++ class。然后点击Choose。

6
在弹出的C++ class窗口中,我们按图中输入。然后下一步。再点击完成。

7
首先来编辑下plugin.pro文件。输入如下内容:
TEMPLATE = lib
CONFIG += plugin
QT += widgets
INCLUDEPATH += ../echowindow
HEADERS = echoplugin.h
SOURCES = echoplugin.cpp
TARGET = $$qtLibraryTarget(echoplugin)
DESTDIR = ../plugins
然后保存。
第一行:生成的是一个库文件。
第二行:这是一个插件
第四行:因为我们要用到刚才定义的接口类,而该类的位置在echowindow中。
第七行:生成的库的名称,后缀名qt会根据系统自动添加。
第八行:生成文件的存放位置。

8
在echoplugin.h中输入:
#include <QObject>
#include <QtPlugin>
#include "echointerface.h"

class EchoPlugin : public QObject, EchoInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "Examples.Plugin.EchoInterface")
Q_INTERFACES(EchoInterface)

public:
EchoPlugin();
QString echo(const QString &message) Q_DECL_OVERRIDE;
};
Q_INTERFACES告诉Qt类实现的是哪个接口,它的参数可以有多个。
Q_PLUGIN_METADATA包含了我们刚才定义的IID。

同时可以看到,我们的EchoPlugin继承自QObject和EchoInterface。并且下面也有一个echo函数,这是我们要具体实现的纯虚函数。

9
现在来实现echoplugin.cpp文件。很简单:
#include "echoplugin.h"
#include <QtWidgets>

EchoPlugin::EchoPlugin()
{
}

QString EchoPlugin::echo(const QString &message)
{
return QString("process:")+message;
}
echo函数只是在参数前面加上了process然后直接返回了。

END
四、编写窗体程序的代码

1
widget.h的代码如下:
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "echointerface.h"
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
Q_OBJECT

public:
explicit Widget(QWidget *parent = 0);
~Widget();

private slots:
void on_pushButton_send_clicked();

private:
Ui::Widget *ui;

EchoInterface *echoInterface;
bool loadPlugin();
};

#endif // WIDGET_H
我们定义了一个接口类的指针。以及一个loadPlugin函数。

2
widget.cpp代码:
#include "widget.h"
#include "ui_widget.h"
#include <QDir>
#include <QMessageBox>
#include <QtWidgets>

Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);

if (!loadPlugin())
{
QMessageBox::information(this, "Error", "Could not load the plugin");
ui->lineEdit_origin_msg->setEnabled(false);
ui->pushButton_send->setEnabled(false);
}
}

Widget::~Widget()
{
delete ui;
}

bool Widget::loadPlugin()
{
QDir pluginsDir(qApp->applicationDirPath());
pluginsDir.cd("plugins");
foreach (QString fileName, pluginsDir.entryList(QDir::Files))
{
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
QObject *plugin = pluginLoader.instance();
if (plugin)
{
echoInterface = qobject_cast<EchoInterface *>(plugin);
if (echoInterface)
return true;
}
}

return false;
}

void Widget::on_pushButton_send_clicked()
{
QString ans=echoInterface->echo(ui->lineEdit_origin_msg->text());
ui->label_answer->setText(ans);
}
注意我们的载入插件函数,我们在窗口的初始化过程中调用了该函数。该函数找到插件文件后,通过QPluginLoader 对象进行载入,然后调用函数instance实例化类并返回一个QObject对象指针,然后通过一个静态强制转换为我们的接口类指针。
然后我们点击按钮时,就可以使用该指针调用echo函数处理文本框的字符串,并返回处理后的字符串。之后,在标签控件中显示出来。

END
五、构建项目,运行程序

我们分别在两个项目上右键,选择 构建 菜单。

构建完毕后,可以看到,我们的插件生成了。我们的窗体程序也生成了。

将生成的插件拷贝到生成的窗体程序的目录。

可以运行程序了。因为我们生成的是debug程序,所以我们在IDE中运行它。
右键将 EchoWindow设置为活跃项目。

然后点击运行,如果设为活跃后运行按钮时灰色,你可以先将项目套件设置为release,然后再换回来。
来看看运行的情况。看来我们的插件起作用了。

至于为什么插件是放在plugins文件夹中,是因为我们在编写plugin插件时pro文件的设置,更重要的是我们的loadPlugin函数是在可执行文件同级目录下的plugins文件夹中寻找,这才是根本。当然你可以修改该函数代码,把插件放在任何你想放置的地方。
好了,整个插件的编写过程到此结束。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
获取oracle中表的表结构、约束和索引信息 若3的x次方等于二十七分之一,则3的负x次方 若x的2x-1次方=1,则x=多少。若3的x次方=27分之1,则x=多少 3的x次方=1/81,x=? ...为什么?。。。若3的x次方等于81分之一,则x等于什么??急 语文句子成分分析详解 初三英语,关于被动语态 级品飞车lo如何下载? 极品飞车全球在线(nfsol)现在可以在大陆玩么?内测完毕了?听说要个登... ...一个星期不理我了怎么办,电话也不接信息也不回,问她是不是有男人了... 威仕特t1电子狗怎么升级 威仕特d910开不了机 威仕特行车记录仪用usb连接电脑为啥不显视 威仕特d521升级也提示主机与电脑连接成功为什么电脑提示没有连接 已有,怎么开微店 被自己家狗挠出血了要打针吗 w什么up中文意思起来 人打过疫苗被猫抓伤出血要打针吗 被猫抓伤流血要不要打针 被猫抓伤出血需要打针吗? 拍日落延时要不要锁定曝光 《一只鸟仔哮啾啾》免费在线观看完整版高清,求百度网盘资源 黑色的毛衣裙搭配什么外套 最实用的脱毛方法 黑色毛衣裙怎么搭配 脱毛简单有效的方法? 怎样在家彻底脱毛 简单方法值得一试 QQ问问里的Q币是一周中那一天更新的 嘛的电脑qq怎么几天更新一次啊 QQ key多久更新一次 威仕特蓝牙耳机怎么连接联想手机 威仕特蓝牙耳机如何连接联想手机 威仕特电子狗上的usb是干嘛的? 威仕特还hx一体机电子狗在私人电脑上怎么升级 威仕特电子狗如何升级 威仕特灵锐VI电子狗怎么升级?求助 威仕特v3电子狗的说明书 威仕特行车记录仪售后在哪里? 关于三户联保 清明节怎样来源的? 谁有ITIL V3 那5本书的 中文版,英文版太难懂了。有下载地址也行。 请帮忙也发一份给我yclxf@yeah.net 用手机号注册的,手机号不用了,还可以用吗? 如果手机号码注销了,还可以继续使用吗? 用手机号注册的,手机号不用了,还可以用吗 绑定的手机号注销了微信还能用吗 手机号注销了 还能用吗 手机号注册的微信,手机号注销了,微信还能用吗 推荐平板电脑 详细说明 比较操作系统优缺点 关于 工会经费 职工教育经费 年初年末有余额时 如何纳税调整? 车辆购置税、工会经费、职工教育经费纳税调整的分录怎么做?