Qt高級——Qt插件開發(fā)

Qt高級——Qt插件開發(fā)

本文討論Qt4.8的插件機制

創(chuàng)新互聯是專業(yè)的天臺網站建設公司,天臺接單;提供網站設計、成都做網站,網頁設計,網站設計,建網站,PHP網站建設等專業(yè)做網站服務;采用PHP框架,可快速的進行天臺網站開發(fā)網頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網站,專業(yè)的做網站團隊,希望更多企業(yè)前來合作!

一、Qt插件機制

1、Qt插件簡介

插件是一種遵循一定規(guī)范的應用程序接口編寫出來的程序,定位于開發(fā)實現應用軟件平臺不具備的功能的程序。

2、Qt插件API

Qt提供了兩種API用于創(chuàng)建插件:一種是高階API,用于擴展Qt本身的功能,如自定義數據庫驅動,圖像格式,文本編碼,自定義樣式等;一種是低階API,用于擴展Qt應用程序。

3、通過插件擴展應用程序功能

A、定義一個接口集(只有純虛函數的類),用來與插件交流。
B、用宏Q_DECLARE_INTERFACE()將該接口告訴Qt元對象系統(tǒng)。
C、應用程序中用QPluginLoader來加載插件。
D、用宏qobject_cast()來判斷一個插件是否實現了接口。

4、創(chuàng)建插件

創(chuàng)建一個插件的步驟如下:
A、聲明插件類,插件類繼承自QObject和插件實現的接口。
B、用宏Q_INTERFACES()將插件接口告訴Qt元對象系統(tǒng)。
C、用宏Q_EXPORT_PLUGIN2()導出插件類。
D、用適當的.pro文件構建插件。
在加載插件前,?QCoreApplication對象必須被初始化。

二、插件開發(fā)實例

1、創(chuàng)建工程

創(chuàng)建工程,選擇“Other Project”->“Subdirs Project”,填寫工程名稱為PluginApp,選擇保存目錄。
Qt高級——Qt插件開發(fā)

2、創(chuàng)建應用工程

在PluginApp工程上右鍵選擇“New Subproject”菜單項,選擇創(chuàng)建一個GUI應用,工程名稱為MainWindow。
Qt高級——Qt插件開發(fā)
填寫工程應用名稱
Qt高級——Qt插件開發(fā)
填寫主界面類的名稱:
Qt高級——Qt插件開發(fā)
在MainWindow應用增加一個接口Echonterface.h。

#ifndef ECHOINTERFACE_H
#define ECHOINTERFACE_H

#include <QString>

//定義接口
class EchoInterface
{
public:
    virtual ~EchoInterface() {}
    virtual QString echo(const QString &message) = 0;
};

#define EchoInterface_iid "Examples.Plugin.EchoInterface"

QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(EchoInterface, EchoInterface_iid)
QT_END_NAMESPACE

#endif // ECHOINTERFACE_H

3、創(chuàng)建插件子工程

在PluginApp工程上右鍵選擇“New Subproject”菜單項,選擇創(chuàng)建一個空的Qt工程,名稱為EchoPlugin。
Qt高級——Qt插件開發(fā)
EchoPlugin.pro工程文件內容如下:

TEMPLATE        = lib
CONFIG         += plugin
QT             += widgets
INCLUDEPATH    += ../MainWindow
TARGET          = $$qtLibraryTarget(echoplugin)
DESTDIR         = ../plugins

在插件子工程中添加一個插件類EchoPlugin,實現如下:
EchoPlugin.h文件:

#ifndef ECHOPLUGIN_H
#define ECHOPLUGIN_H

#include <QObject>
#include <QtPlugin>
#include "EchoInterface.h"

class EchoPlugin : public QObject, public EchoInterface
{
    Q_OBJECT
    Q_INTERFACES(EchoInterface)
public:
    explicit EchoPlugin(QObject *parent = 0);
    QString echo(const QString &message);
};

#endif // ECHOPLUGIN_H

EchoPlugin.cpp文件:

#include "EchoPlugin.h"

EchoPlugin::EchoPlugin(QObject *parent) :
    QObject(parent)
{
}

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

Q_EXPORT_PLUGIN2(EchoPlugin, EchoPlugin);

4、應用的實現

實現MainWindow主界面
Widget.h文件:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "EchoInterface.h"

QT_BEGIN_NAMESPACE
class QString;
class QLineEdit;
class QLabel;
class QPushButton;
class QGridLayout;
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    void sendEcho();

private:
    void createGUI();
    //加載插件
    bool loadPlugin();

    EchoInterface *echoInterface;
    QLineEdit *lineEdit;
    QLabel *label;
    QPushButton *button;
    QGridLayout *layout;
};

#endif // WIDGET_H

Widget.cpp文件:

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

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    createGUI();
    setLayout(layout);
    setWindowTitle("Echo Plugin Example");

    if (!loadPlugin())
    {
        QMessageBox::information(this, "Error", "Could not load the plugin");
        lineEdit->setEnabled(false);
        button->setEnabled(false);
    }
}
void Widget::sendEcho()
{
    QString text = echoInterface->echo(lineEdit->text());
    label->setText(text);
}

void Widget::createGUI()
{
    lineEdit = new QLineEdit;
    label = new QLabel;
    label->setFrameStyle(QFrame::Box | QFrame::Plain);
    button = new QPushButton(tr("Send Message"));

    connect(lineEdit, SIGNAL(editingFinished()),
            this, SLOT(sendEcho()));
    connect(button, SIGNAL(clicked()),
            this, SLOT(sendEcho()));

    layout = new QGridLayout;
    layout->addWidget(new QLabel(tr("Message:")), 0, 0);
    layout->addWidget(lineEdit, 0, 1);
    layout->addWidget(new QLabel(tr("Answer:")), 1, 0);
    layout->addWidget(label, 1, 1);
    layout->addWidget(button, 2, 1, Qt::AlignRight);
    layout->setSizeConstraint(QLayout::SetFixedSize);
}

bool Widget::loadPlugin()
{
    bool ret = true;
    //獲取當前應用程序所在路徑
    QDir pluginsDir(qApp->applicationDirPath());
#if defined(Q_OS_WIN)
    if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
        pluginsDir.cdUp();
#elif defined(Q_OS_MAC)
    if (pluginsDir.dirName() == "MacOS")
    {
        pluginsDir.cdUp();
        pluginsDir.cdUp();
        pluginsDir.cdUp();
    }
#elif defined(Q_OS_LINUX)
    pluginsDir.cdUp();
#endif
    //切換到插件目錄
    pluginsDir.cd("plugins");
    //遍歷plugins目錄下所有文件
    foreach (QString fileName, pluginsDir.entryList(QDir::Files))
    {
        QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));

        QObject *plugin = pluginLoader.instance();
        if (plugin)
        {
            //插件名稱
            QString pluginName = plugin->metaObject()->className();
            //對插件初始化
            if(pluginName == "EchoPlugin")
            {
                echoInterface = qobject_cast<EchoInterface *>(plugin);
                if (echoInterface)
                    ret =  true;
                break;
            }
            else
            {
                ret = false;
            }
        }
    }
    return ret;
}

Widget::~Widget()
{

}

Main.cpp文件:

#include "Widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

程序運行結果如下:
Qt高級——Qt插件開發(fā)
查看構建目錄,生成的插件文件存放在plugins目錄下:
Qt高級——Qt插件開發(fā)

三、定位插件

Qt應用程序將會自動感知可用的插件,因為插件都被存儲在標準的子目錄當中。因此應用程序不需要任何查找或者加載插件的代碼。
在開發(fā)過程中,插件的目錄是QTDIR/plugins(QTDIR是Qt的安裝目錄),每個類型的插件放在相應類型的目錄下面。如果想要應用程序使用插件,但不想用標準的插件存放路徑,可以在應用程序的安裝過程中指定要使用的插件的路徑,可以使用QSettings,保存插件路徑,在應用程序運行時讀取配置文件。應用程序可以通過QCoreApplication::addLibraryPath()函數將指定的插件路徑加載到應用程序中。
使插件可加載的一種方法是在應用程序所在目錄創(chuàng)建一個子目錄,用于存放插件。如果要發(fā)布和Qt一起發(fā)布的插件(存放在plugins目錄)中的任何插件,必須拷貝plugins目錄下的插件子目錄到應用程序的根目錄下。

四、靜態(tài)插件

1、靜態(tài)插件簡介

將一個插件與一個應用程序一起使用的通常和最靈活的方法是將插件編譯成一個動態(tài)庫,動態(tài)庫可以獨立轉移,并在運行時被檢測和加載。
插件可以靜態(tài)鏈接到應用程序。構建Qt的靜態(tài)版本是包含Qt的預定義插件的唯一選項。使用靜態(tài)插件使部署不易出錯,但缺點是插件中沒有的功能不能在應用程序的完全重編譯和重發(fā)布的情況下添加。
Qt提供了如下靜態(tài)插件:
Qt高級——Qt插件開發(fā)

2、靜態(tài)插件使用

要靜態(tài)鏈接靜態(tài)插件,必須在應用程序中使用Q_IMPORT_PLUGIN宏,同時需要使用QTPLUGIN增加相應的插件到工程中。如:

#include <QtPlugin>

Q_IMPORT_PLUGIN(qjpeg)
Q_IMPORT_PLUGIN(qgif)

在.pro工程文件中,

QTPLUGIN     += qjpeg \
                qgif

3、創(chuàng)建靜態(tài)插件

使用如下步驟可以創(chuàng)建一個靜態(tài)插件:
A、在.pro工程文件中增加CONFIG += static?
B、在應用程序中使用?Q_IMPORT_PLUGIN()宏導入靜態(tài)插件
C、在應用程序.pro工程文件中使用?LIBS鏈接應用程序和靜態(tài)插件。

名稱欄目:Qt高級——Qt插件開發(fā)
地址分享:http://muchs.cn/article42/ihipec.html

成都網站建設公司_創(chuàng)新互聯,為您提供建站公司、做網站品牌網站建設、營銷型網站建設網頁設計公司、網站設計公司

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯

h5響應式網站建設