欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

QT編寫窗口插件實(shí)現(xiàn)調(diào)用窗口的自適應(yīng)

 更新時(shí)間:2021年06月22日 10:53:40   作者:zebra_zzh  
這篇文章主要為大家詳細(xì)介紹了QT編寫窗口插件實(shí)現(xiàn)調(diào)用窗口的自適應(yīng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前言

最近項(xiàng)目中遇到插件架構(gòu),將幾個(gè)功能模塊分別寫成了dll供主程序調(diào)用。本文主要在QT下實(shí)現(xiàn)這樣一個(gè)功能:

編寫一個(gè)dll,里面包含一個(gè)QDialog對話框作為主窗口。該dll提供四個(gè)接口,它們的作用分別是

1 打開主窗口

2 關(guān)閉主窗口

3 更新插件數(shù)據(jù)(暫不討論)

4 調(diào)用插件中的函數(shù)并獲取返回值(暫不討論)

然后由主程序調(diào)用dll,并將dll中的窗口嵌入自己的對話框中,并實(shí)現(xiàn)自適應(yīng)。

效果 

編寫dll

 1  創(chuàng)建一個(gè)Qt Library工程名為test,然后再插入一個(gè)QDialog名為testwidget。

此時(shí)工程中目錄有以下文件:

2 編輯ui,利用布局讓他能夠隨著窗口大小改變自適應(yīng)。注意對象查看器里布局變化,具體方法如下:

3 編寫接口

在test.h編寫接口函數(shù)定義,在test.cpp中實(shí)現(xiàn)。

其中全局變量g_pTestWidget是為了防止重復(fù)打開或者關(guān)閉。

代碼如下:

#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;
}

至此插件部分的任務(wù)完成了。

編寫主程序

主程序?yàn)橐粋€(gè)QWidget窗口,我們要將加載的QDialog窗口放進(jìn)Widget控件里,并使他相對于Widget實(shí)現(xiàn)自適應(yīng)。因此我們需要

子類化Widget控件(QWidget),重寫他的resizeEvent。

QResizingWidget繼承自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)
{
 /*
 發(fā)現(xiàn) 繼承自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如下:

也以同樣的布局方式設(shè)置自適應(yīng)。

下面編寫加載函數(shù),用QLibrary顯示加載dll,首先定義四個(gè)與dll中接口一致的函數(shù)指針。

代碼如下:

#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();
 }
}

至此主程序編寫完畢。

總結(jié)

如果主程序需要集成多個(gè)插件呢?那就要設(shè)計(jì)一個(gè)插件管理工具,下次再講。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論