QT自定义控件插件学习笔记
本文主要阐述的是自定义控件插件的创建与调用方法和注意事项点。
目录
一、创建自定义控件插件
1、Qt Designer专用接口
2、插件的自定义控件类接口
二、调用自定义控件插件
1、动态调用插件
2、静态调用插件
三、结语
一、创建自定义控件插件
1、Qt Designer专用接口
1.1、控件收集器接口
基类:QDesignerCustomWidgetCollectionInterface
用途:将所有自定义控件类装载到一个QList里面
#pragma once
#include <QtDesigner>
#include <qplugin.h>
class WidgetCollectionInterface : public QObject, public QDesignerCustomWidgetCollectionInterface
{Q_OBJECTQ_INTERFACES(QDesignerCustomWidgetCollectionInterface)
#if QT_VERSION >= 0x050000Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetCollectionInterface")
#endif // QT_VERSION >= 0x050000
public:WidgetCollectionInterface(QObject* parent = 0);
QList<QDesignerCustomWidgetInterface*> customWidgets() const override;
private:QList<QDesignerCustomWidgetInterface*> widgets;
};
关键点:
两个宏,声明唯一接口
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetCollectionInterface")
构造函数中装载所有自定义控件类
WidgetCollectionInterface::WidgetCollectionInterface(QObject* parent): QObject(parent)
{widgets.append(new MyProgressBar1Interface(this));//widgets.append(new CustomWidgetTwoInterface(this));//widgets.append(new CustomWidgetThreeInterface(this));
}
1.2、单个自定义控件接口
基类:QDesignerCustomWidgetInterface
用途:通过重写虚函数完成单个自定义控件信息的定义,使得Qt Designer可以通过dll动态调用方式加载到自定义控件的信息,
其信息包括控件图标、控件名字、控件头文件、控件所在组名、控件类名、Qt Designer拖拽自动生成的对象实例默认名称等
#pragma once
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
#include <QtDesigner/QtDesigner>
class MyProgressBar1Interface : public QObject, public QDesignerCustomWidgetInterface
{Q_OBJECTQ_INTERFACES(QDesignerCustomWidgetInterface)
public:MyProgressBar1Interface(QObject *parent = Q_NULLPTR);
bool isContainer() const;bool isInitialized() const;QIcon icon() const;QString domXml() const;QString group() const;QString includeFile() const;QString name() const;QString toolTip() const;QString whatsThis() const;QWidget *createWidget(QWidget *parent);void initialize(QDesignerFormEditorInterface *core);
private:bool initialized;
};
关键点:
基类QDesignerCustomWidgetInterface的虚函数重写
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
#include <QtDesigner/QtDesigner>
class MyProgressBar1Interface : public QObject, public QDesignerCustomWidgetInterface
{Q_OBJECTQ_INTERFACES(QDesignerCustomWidgetInterface)... ......
}
2、插件的自定义控件类接口
2.1、自定义控件实现
控件继承的基类、控件属性、控件绘制、信号/槽、事件等常规的自定义控件实现,具体参考QPainter的使用
#pragma once
#include <QProgressBar>
#include <QFont>
#include <QColor>
#include <QBrush>
#include <QPen>
#include <QtDesigner/QtDesigner>
class QDESIGNER_WIDGET_EXPORT MyProgressBar1 :public QProgressBar
{Q_OBJECTQ_PROPERTY(QFont textFont READ getTextFont WRITE setTextFont)Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor)Q_PROPERTY(QPen circleLinePen READ getCircleLinePen WRITE setCircleLinePen)Q_PROPERTY(QBrush barBackgroundBrush READ getBarBackgroundBrush WRITE setBarBackgroundBrush)Q_PROPERTY(QBrush barForegroundBrush READ getBarForegroundBrush WRITE setBarForegroundBrush)
public:explicit MyProgressBar1(QWidget* parent = nullptr);virtual ~MyProgressBar1();
protected:virtual void paintEvent(QPaintEvent* event);
public:QFont getTextFont() const;void setTextFont(const QFont& font);QColor getTextColor() const;void setTextColor(const QColor& color);QPen getCircleLinePen() const;void setCircleLinePen(const QPen& pen);QBrush getBarBackgroundBrush() const;void setBarBackgroundBrush(const QBrush& brush);QBrush getBarForegroundBrush() const;void setBarForegroundBrush(const QBrush& brush);
private:QFont textFont; //字体格式QColor textColor; //字体颜色QPen circleLinePen; //圆轮廓画笔QBrush barBackgroundBrush; //进度条底色画刷QBrush barForegroundBrush; //进度条画刷
private:void InitUi();void TestPainter();
};
2.2、类接口导出
- 使用QDESIGNER_WIDGET_EXPORT声明类,这个宏所在头文件是#include <QtDesigner/QtDesigner>
#include <QtDesigner/QtDesigner>
class QDESIGNER_WIDGET_EXPORT MyProgressBar1 : public QProgressBar
预定义宏QDESIGNER_EXPORT_WIDGETS
这个宏定义如下,所以一定要预定义宏QDESIGNER_EXPORT_WIDGETS,使其能导出接口,不然.dll是编译不过的。
#if defined(QDESIGNER_EXPORT_WIDGETS)
# define QDESIGNER_WIDGET_EXPORT __declspec(dllexport)
#else
# define QDESIGNER_WIDGET_EXPORT __declspec(dllimport)
#endif
二、调用自定义控件插件
1、动态调用插件
实现原理:主要通过.dll工程中的WidgetCollectionInterface、MyProgressBar1Interface等类来实现。先将所有自定义控件类装载到WidgetCollection,调用时再通过name()索引出自定义类,然后createWidget()。
用途:为了Qt Designer设计器能够一次性加载自定义控件插件中的所有控件,使用户可以通过拖拽等方式直接使用控件
特别注意:这种调用方式是不可以直接new自定义控件类的,只能通过下面的方式(LoadInterface、CreateCustomWidget)来调用自定义控件类的成员函数
bool CustomWidgetTestDemo::LoadInterface(QString pluginName)
{QFileInfo pluginFile( QString("%1/%2").arg(QCoreApplication::applicationDirPath()).arg(pluginName));QString pluginFilePath = pluginFile.absoluteFilePath();QPluginLoader load(pluginFilePath);QObject* obj = load.instance(); //加载dllif (obj != nullptr){m_interface = qobject_cast<CustomWidgetCollectionInterface*>(obj); //加载接口if (m_interface != nullptr){return true;}else{QMessageBox::critical(this, "ERROR", QString::fromStdWString(L"CustomWidgetCollectionInterface加载失败!"));}}else{QMessageBox::critical(this, "ERROR", QString::fromStdWString(L"<%1>加载失败!").arg(pluginFilePath));}return false;
}
template<class T>
T* CustomWidgetTestDemo::CreateCustomWidget(QString name, QWidget* parent)
{QList<QDesignerCustomWidgetInterface*> widgets = m_interface->customWidgets();for each (QDesignerCustomWidgetInterface * var in widgets){if (var->name() == name){T* widget;widget = static_cast<T*>(var->createWidget(parent));if (widget != nullptr){return widget;}break;}}QMessageBox::critical(this, "ERROR", QString::fromStdWString(L"自定义控件<%1>加载失败!").arg(name));return nullptr;
}
LoadInterface("QtCustomYihPlugin.dll");
MyProgressBar1* myProgressBar1 = CreateCustomWidget<MyProgressBar1>("MyProgressBar1", this);
myProgressBar1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2、静态调用插件
实现原理:主要通过.dll工程中的自定义控件类前面添加QDESIGNER_WIDGET_EXPORT来实现。实际上就是给.dll定义类接口
用途:为了能够实例化自定义控件类,即new自定义控件对象。.ui文件生成的源码,也是通过new来实例化自定义控件的,即类似下面的代码。
特别注意:与静态调用.dll方法一样,需要设置.lib依赖及其所在路径
MyProgressBar1* myProgressBar1_666;
myProgressBar1_666 = new MyProgressBar1(this);
myProgressBar1_666->setObjectName(QString::fromUtf8("myProgressBar1_1"));
myProgressBar1_666->setGeometry(QRect(320, 60, 271, 191));
myProgressBar1_666->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
m_Layout->addWidget(myProgressBar1_666);
三、结语
关于自定义控件的制作、控件插件的调用完整步骤等信息,可以参考以下资料:
互联网博客:<Qt编写自定义控件插件路过的坑及注意事项>
互联网博客:<Qt之自定义插件(for Qt Designer)>
书籍:<Qt Creator快速入门_第三版>
Demo源码(JaneYih PC):
解决方案名:CustomWidgetProject
创建插件工程名:QtCustomYihPlugin
调用插件工程名:CustomWidgetTestDemo
转载请注明出处!!
如有错误之处,请各路大神指点指点~
QT自定义控件插件学习笔记相关推荐
- Qt 5.12学习笔记--QML性能策略
Qt 5.12学习笔记--QML性能策略 1 简介 2 时间因素 2 性能分析 3 JavaScript 部分 4 绑定 5 类型转换 6 解析属性 6 属性绑定 7 序列提示(Sequence ti ...
- Gradle插件学习笔记(二)
之前介绍了Gradle插件的开发,这次会对功能进行一部分拓展,建议没有读过第一篇文章的朋友,先看一下Gradle插件学习笔记(一) Extension 之前的文章提到过,如何编写一个插件,但是并不能通 ...
- Qt 快速入门学习笔记
Qt 快速入门学习笔记 环境安装 环境配置以及安装 安装包下载地址 1.windows安装 msvc编译器模块需要安装Windows软件开发工具包. MinGW是Windows平台使用GNU工具导入库 ...
- QT 5.9学习笔记
QT 5.9学习笔记 写在前面 S1:初识QT:QT简介 S2:QT在Windows和Linux平台下的安装 Qt调出模态与非模态对话框 写在前面 本文章为我在学习QT5.9时的记录文章,里面会涉及所 ...
- Unity Cinemachine插件学习笔记,实现单目标和多目标之间切换
Unity Cinemachine插件学习笔记,实现单目标和多目标之间切换 *版本要求Unity2017.1及以上. 参考资料: [官方] Unity 2017.1正式版发布 Cinemachine插 ...
- Unity Cinemachine插件学习笔记
以下都是转载内容,能够比较直观的学习一些基础内容.现在的Cinemachine更新了许多新的功能,但是Cinemachine插件都ExamplesScences,去看一下官方例子和文档来学习更佳 *版 ...
- Unity Cinemachine插件学习笔记,结合Timeline实现简单场景动画
Unity Cinemachine插件学习笔记,结合Timeline实现简单场景动画 *版本要求Unity2017.1及以上. 参考资料: [官方] Unity 2017.1正式版发布 [Unity] ...
- Qt武林秘籍学习笔记摘要
1 原文链接 Qt开发经验: 自己总结的这十多年来做Qt开发以来的经验,以及Qt相关武林秘籍电子书,会一直持续更新增加,欢迎各位留言增加内容或者提出建议,谢谢! (gitee.com) 编程语录: 自 ...
- JavaScript 封装插件学习笔记(一)
此篇只是笔记,在借鉴.参考.模仿的过程,可能不完整,请多指教! 定义插件名称要注意命名冲突,防止全局污染. 1.第一种Javascript对象命名:(Javascript语言是"先解析,后运 ...
最新文章
- python脚本如何监听终止进程行为,如何通过脚本名获取pid
- ReactiveCocoa基础
- HDU1846 - Brave Game【巴什博弈】
- Java中String类型的概述
- 人人网,微博,QQ空间,朋友圈,常用API调用实现方法
- 19 矩阵——矩阵的相抵、相抵标准形、秩1矩阵、矩阵的满秩分解
- 数据持久化,序列化,反序列化,文件读写1
- php实现先序、中序、后序遍历二叉树
- 撰写商业计划书的一些误区和建议
- 超星尔雅python_超星尔雅Python金融数据分析答案公众号
- js 计算时间差 函数
- 腾讯云数据库CDB介绍及数据库与应用数据库分析
- 【C语言学习】sscanf的简单使用.
- 远程桌面连接只有2个会话活动
- 无线网卡无信号无服务器,无线网卡不能连接网络是什么原因?
- 删了手机里的一个html文件,手机操作篇:手机上怎么删除pdf其中一页
- 刷脸自助登记 访客管理不再潦草应对!
- 想通过手机刷视频赚钱?这篇文章你有必要了解一下
- 友盟推送 php,laravel5.4+umeng(友盟)集成app消息推送功能
- 求斐波那契数列c++实现