1. 程式人生 > >QT外掛開發方式

QT外掛開發方式

建立一個QT的庫專案,刪除自動生成的.h和.cpp檔案,新增一個介面定義.h檔案和一個介面實現類(一個.h一個.cpp).程式碼如下:

1.介面檔案原始碼

#ifndef PLUGININTERFACE_H
#define PLUGININTERFACE_H

#include <QString>


class EchoInterface
{
public:
 virtual ~EchoInterface() {}
 virtual QString echo(const QString &message) = 0;
};

QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(EchoInterface, "com.hollysys.plugin.EchoIntrface/1.0");
QT_END_NAMESPACE


#endif

2.介面實現類標頭檔案

#ifndef PLUGIN_H
#define PLUGIN_H

//#include "plugin_global.h"
#include <QObject>
#include "plugininterface.h"

class Plugin : public QObject, EchoInterface
{
 Q_OBJECT
 Q_INTERFACES(EchoInterface)
public:
 Plugin();
 ~Plugin();
public:
 QString echo(const QString &message);


};

#endif // PLUGIN_H

3.介面實現類cpp檔案

#include "plugin.h"
#include <QtGui>


Plugin::Plugin()
{

}

Plugin::~Plugin()
{

}

QString Plugin::echo(const QString &message)
{
 return message;
}

Q_EXPORT_PLUGIN2("echoPlugin", Plugin);

編譯生成dll格式的外掛.這裡可能會遇到LNK2001錯誤,因為外掛介面定義依賴於QT的元資料,而在程式碼中手動新增Q_OBJECT巨集後,編譯器不會自動為我們生成moc_XXXX.cpp檔案,因此需要使用命令列生成moc元資料檔案:cmd-->cd 原始碼所在命令 -->moc -o moc_XXXX.cpp XXXX.h.這樣就可以手動創建出moc元資料檔案,解決LNK2001編譯錯誤.

建立一個GUI測試專案,程式碼如下:

#include "test.h"
#include <QtGui>
#include <QMessageBox>
#include <QDir>

Test::Test(QWidget *parent, Qt::WFlags flags)
 : QMainWindow(parent, flags)
{
 ui.setupUi(this);
 QObject::connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(ButtonClicked()));
 loadPlugin();
}

Test::~Test()
{

}

bool Test::loadPlugin()
{
 QDir pluginsDir(qApp->applicationDirPath());
 foreach (QString filename, pluginsDir.entryList(QDir::Files))
 {
  QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(filename));
  QObject *plugin = pluginLoader.instance();
  if(plugin)
  {
   echoInterface = qobject_cast<EchoInterface *>(plugin);//echoInterface是成員變數
   if(echoInterface)
    return true;
  }
 }
}

void Test::ButtonClicked()
{
 QString plugin = ui.lineEdit->text();
 QMessageBox::information(NULL, "", echoInterface->echo(plugin));
}

分析程式碼可見,這裡對所有與exe檔案同目錄的檔案嘗試載入外掛,如果載入成功則返回.程式碼實現非常簡潔.在正式開發中可將已載入的外掛介面存放在列表中,在需要的時候依次呼叫即可.

另外如果想獲取外掛中類定義的元資料,可以使外掛介面類從QObject繼承,並使用Q_CLASSINFO巨集新增鍵值對,如Q_CLASSINFO("Author**", "Henreash**").並從主程式中使用外掛物件元資料獲取這些鍵值對:

 const QMetaObject *mo = echoInterface->metaObject();
 for(int i = 0; i < mo->classInfoCount(); i++)
 {
  qDebug() << mo->classInfo(i).name() << mo->classInfo(i).value();
 }

使用這個機制可以在定義外掛類的時候向主程式傳遞一些特殊資訊.

測試發現,如果在外掛介面類中定義一個靜態變數,那麼這個靜態變數在外掛中的地址和在主程式中的地址是不相同的.


FROM: http://blog.csdn.net/henreash/article/details/7264489