QT作成ウィンドウプラグインは起動ウィンドウの適応を実現します。


前言
最近のプロジェクトではプラグインアーキテクチャに遭遇し、いくつかの機能モジュールをそれぞれdllと書いてメインプログラムで起動します。本論文は主にQTの下でこのような機能を実現する。
dllを作成します。QDialogダイアログがメインウィンドウとして含まれています。dllは4つのインターフェースを提供します。それぞれの役割は?
1メインウィンドウを開く
2メインウィンドウを閉じます
3プラグインのデータを更新します。
4プラグインの関数を呼び出して、返却値を取得します。
メインプログラムからdllを呼び出して、dllのウィンドウを自分のダイアログに埋め込み、適応を実現します。
効果 

dllを作成
 1  Qt Libraryプロジェクト名をtestとして作成し、QDialog名をtestwidgetとして挿入します。
プロジェクトのディレクトリには以下のファイルがあります。

2はイを編集して、レイアウトを利用して彼にウィンドウの大きさに従って適応することができます。注意対象ビューアでのレイアウトの変化について、具体的な方法は以下の通りです。

3作成インターフェース
test.h作成インターフェース関数定義で、test.cppで実現します。
そのうちグローバル変数g_pTest Widgetは重複して開いたり閉じたりしないようにするためです。
コードは以下の通りです

#ifndef TEST_H
#define TEST_H
 
#include "test_global.h"
#include "testwidget.h"
 
class TEST_EXPORT test
{
public:
 test(); 
 ~test();
 
private:
 
};
 
 
#ifdef __cplusplus
extern "C" {          // we need to export the C interface
#endif
 void TEST_EXPORT PluginStart(void *lParentWidget);
 void TEST_EXPORT PluginClose(bool bCompleteClose);
 void TEST_EXPORT PluginUpdate(void *upDate);
 TEST_EXPORT const char*  PluginFunction(const char* input);
 
 
#ifdef __cplusplus
}
#endif
 
#endif // TEST_H

#include "test.h"
 
testWidget *g_pTestWidget = NULL;
test::test()
{
 
}
 
test::~test()
{
 
}
 
void TEST_EXPORT PluginStart(void *lParentWidget)
{
 if (NULL == g_pTestWidget)
 {
  g_pTestWidget = new testWidget();
 }
 
 if (NULL != lParentWidget)
 {
  g_pTestWidget->setParent((QDialog *)lParentWidget);
  g_pTestWidget->raise();
  g_pTestWidget->setGeometry(0, 0, ((QDialog *)lParentWidget)->width(), ((QDialog *)lParentWidget)->height());
 }
 g_pTestWidget->show();
}
 
void TEST_EXPORT PluginClose(bool bCompleteClose)
{
 if (g_pTestWidget != NULL)
 {
  if (bCompleteClose)
  {
   g_pTestWidget->hide();
  }
  else
  {
   g_pTestWidget->close();
   delete g_pTestWidget;
   g_pTestWidget = NULL;
  }
 }
}
 
void TEST_EXPORT PluginUpdate(void *upDate)
{
 
}
 
TEST_EXPORT const char* PluginFunction(const char* input)
{
 return input;
}
このプラグイン部分のタスクが完了しました。
メインプログラムを作成
メインプログラムはQWidgetウィンドウです。私たちはロードされたQDialogウィンドウをWidgetコントロールに入れて、Widgetに対して彼を適応させます。だから私たちは必要です
サブクラス化Widgetコントロール(QWidget)は、彼のresizeventを書き換えます。
QResizing WidgetはQWidgetから継承されています。

#ifndef QRESIZINGWIDGET_H
#define QRESIZINGWIDGET_H
 
#pragma once
 
#include <QWidget>
 
class QResizingWidget : public QWidget
{
    Q_OBJECT
public:
    explicit QResizingWidget(QWidget *parent = 0);
    virtual ~QResizingWidget();
 
protected:
    virtual void paintEvent(QPaintEvent *sEvent);
 
    virtual void resizeEvent(QResizeEvent* sEvent);
 
};
 
#endif

#include "qresizingwidget.h"
#include <QResizeEvent>
#include <QStyleOption>
#include <QPainter>
 
QResizingWidget::QResizingWidget(QWidget *parent /*= 0*/)
    : QWidget(parent)
{
}
 
QResizingWidget::~QResizingWidget()
{
}
 
void QResizingWidget::resizeEvent(QResizeEvent* sEvent)
{
 QWidget::resizeEvent(sEvent);
 
 foreach(auto itr, children())
 {
  if (itr->isWidgetType())
  {
   itr->setProperty("geometry", QRectF(0, 0, geometry().width(), geometry().height()));
  }
 }
}
 
void QResizingWidget::paintEvent(QPaintEvent *sEvent)
{
 /*
       QWidget      ,  setStyleSheet  ,
           Q_OBJECT,setStyleSheet  ,
    OBJECT       signal and slot,
         ,   QWidget      ,   paintEvent  ,
        :
 */
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
 QWidget::paintEvent(sEvent);
}
メインプログラムQWidgetは以下の通りです。

同様のレイアウトでも適応を設定します。
下記ではローディング関数を作成し、QLibraryでローディングdllを表示します。まず4つの関数ポインタを規定します。
コードは以下の通りです

#include "testdll.h"
#include <QLibrary>
#include <QDebug>
 
 
 
typedef void (*fun_start)(void *lparentWidget);
typedef void (*fun_close)(bool bCompleteClose);
typedef void (*fun_update)(const char *upDate);
typedef const char* (*fun_callback)(void *input);
 
fun_start g_Start = NULL;
fun_close g_End = NULL;
 
QLibrary myDll;
 
testDll::testDll(QWidget *parent)
 : QWidget(parent)
{
 ui.setupUi(this);
 
 connect(ui.load, SIGNAL(clicked()), this, SLOT(load()));
 connect(ui.unload, SIGNAL(clicked()), this, SLOT(unload()));
}
 
testDll::~testDll()
{
 
}
 
void testDll::load()
{
 myDll.setFileName("test.dll");
 if (myDll.load())
 {
  if (!myDll.isLoaded())
  {
   qDebug() << "load error!";
  }
  else
  {
   g_Start = (fun_start)myDll.resolve("PluginStart"); 
   qDebug() << g_Start;
   qDebug() << "load success!";
   g_Start(ui.widget);
  }
 }
}
 
void testDll::unload()
{
 if (myDll.isLoaded())
 {
  g_End = (fun_close)myDll.resolve("PluginClose"); 
  g_End(false);
  myDll.unload();
 }
}
これでメインプログラムを作成しました。
締め括りをつける
メインプログラムは複数のプラグインを統合する必要がありますか?プラグイン管理ツールを設計して、また今度話します。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。