利用插件扩展Qt本身
来源:互联网 发布:淘宝下架宝贝在哪里 编辑:程序博客网 时间:2024/06/05 11:51
简述
Qt 提供了两套用于创建插件的 API:
- High-Level API:用于扩展 Qt 本身(例如:自定义数据库驱动、图像格式、文本编解码、自定义样式等)
- Low-Level API:用于扩展 Qt 应用程序
例如,如果要编写自定义的 QStyle
子类,并且动态地加载 Qt 应用程序,则可以使用更高级别的 API。
由于较高级别的 API 构建在较低级别的 API 之上,所以某些问题对两者来说是共同的。
- 简述
- 编写 Qt 扩展
- 吐槽 Qt
- 一个简单的样式插件
- 样式插件
- 加载插件
- 源码地址
版权所有:一去丶二三里,转载请注明出处:http://blog.csdn.net/liang19890820
编写 Qt 扩展
要编写扩展 Qt 本身的插件,需要对适当的插件基类进行子类化,实现一些功能并添加一个宏。
下表总结了一些插件基类:
QAccessibleBridgePlugin
accessiblebridge Qt GUI 区分大小写 QImageIOPlugin
imageformats Qt GUI 区分大小写 QPictureFormatPlugin (obsolete)
pictureformats Qt GUI 区分大小写 QAudioSystemPlugin
audio Qt Multimedia 区分大小写 QDeclarativeVideoBackendFactoryInterface
video/declarativevideobackend Qt Multimedia 区分大小写 QGstBufferPoolPlugin
video/bufferpool Qt Multimedia 区分大小写 QMediaPlaylistIOPlugin
playlistformats Qt Multimedia 区分大小写 QMediaResourcePolicyPlugin
resourcepolicy Qt Multimedia 区分大小写 QMediaServiceProviderPlugin
mediaservice Qt Multimedia 区分大小写 QSGVideoNodeFactoryPlugin
video/videonode Qt Multimedia 区分大小写 QBearerEnginePlugin
bearer Qt Network 区分大小写 QPlatformInputContextPlugin
platforminputcontexts Qt Platform Abstraction 区分大小写 QPlatformIntegrationPlugin
platforms Qt Platform Abstraction 区分大小写 QPlatformThemePlugin
platformthemes Qt Platform Abstraction 区分大小写 QGeoPositionInfoSourceFactory
position Qt Positioning 区分大小写 QPlatformPrinterSupportPlugin
printsupport Qt Print Support 区分大小写 QSGContextPlugin
scenegraph Qt Quick 区分大小写 QScriptExtensionPlugin
script Qt Script 区分大小写 QSensorGesturePluginInterface
sensorgestures Qt Sensors 区分大小写 QSensorPluginInterface
sensors Qt Sensors 区分大小写 QSqlDriverPlugin
sqldrivers Qt SQL 区分大小写 QIconEnginePlugin
iconengines Qt SVG 区分大小写 QAccessiblePlugin
accessible Qt Widgets 区分大小写 QStylePlugin
styles Qt Widgets 区分大小写注意: 派生的插件默认存储在标准插件目录的子目录中,如果没有被存储在相应的目录中,Qt 将不会找到插件。
吐槽 Qt
你没看错,正在进行时 - 吐槽、吐槽、吐槽。。。
Qt 中有很多示例,其中有一个样式插件 - Style Plugin,可以正常运行,但无法显示实际效果(说好的红色按钮呢?)一脸懵逼!
除此之外,项目还包含了一些冗余的代码,并且助手里有些描述也有问题(过时了)。例如:
keys() returns a list of style names that this plugin can create, while create() takes such a string and returns the QStyle corresponding to the key. Both functions are pure virtual functions reimplemented from QStylePlugin.
查看 QStylePlugin
文档:
...class Q_WIDGETS_EXPORT QStylePlugin : public QObject{ Q_OBJECTpublic: explicit QStylePlugin(QObject *parent = Q_NULLPTR); ~QStylePlugin(); virtual QStyle *create(const QString &key) = 0;};...
What?纯虚函数 keys()
呢?。。。如果没记错的话,在 Qt 4.8 版本是有这个纯虚函数的,但是 5.x 已经去掉了。
所以,尽信书不如无书!即使是助手等一些官方教程也有过时的时候。。。遇到问题不要心存侥幸,抱着似是而非的心态,有疑惑一定要搞明白!
好吧,那就以此为例,顺便解决所有遇到的问题。
一个简单的样式插件
编写样式插件,涉及以下步骤:
- 实现一个
QStyle
,为 GUI 提供样式和外观。 - 编写样式插件 - 子类化
QStylePlugin
:- 重新实现纯虚函数
create()
- 使用
Q_PLUGIN_METADATA()
宏导出该类
- 重新实现纯虚函数
- 使用合适的
.pro
文件构建插件
在插件创建完成之后,使用以下方式加载:
- 使用
QStyleFactory::create()
创建并返回一个 QStyle 对象 - 使用
QApplication::setStyle()
设置程序的样式 - 样式插件必须被放置在
styles
目录中,该目录与可执行程序处于同一位置。
下面,来实现一个带有蓝色文本的按钮样式插件,效果如下:
样式插件
工程文件 -
.pro
由于我们正在构建的是一个共享库,而不是可执行文件。所以在 .pro
中,需要将 TEMPLATE
设置为 lib
,同时还必须将 CONFIG
设置为 plugin
。
plugin.pro
内容如下:
QT += widgetsTEMPLATE = libCONFIG += pluginTARGET = stylePluginHEADERS += \ simple_style.h \ style_plugin.hOTHER_FILES += simple_style.jsonwin32 { CONFIG(debug, release|debug):DESTDIR = ../debug/styles/ CONFIG(release, release|debug):DESTDIR = ../release/styles/} else { DESTDIR = ../styles/}
注意: 根据 QStylePlugin
的要求,插件需要被存储在 styles
文件夹中,因为这是 Qt 搜索样式插件的路径。
自定义样式 - QStyle
QProxyStyle
是一个很方便的类,包装了一个 QStyle
,用于动态覆盖特定的样式行为。所以,自定义的样式可以用它来实现。
simple_style.h
内容如下:
#ifndef SIMPLE_STYLE_H#define SIMPLE_STYLE_H#include <QProxyStyle>class SimpleStyle : public QProxyStyle{ Q_OBJECTpublic: SimpleStyle() {} void polish(QPalette &palette) override { palette.setBrush(QPalette::ButtonText, Qt::blue); }};#endif // SIMPLE_STYLE_H
插件类 -
StylePlugin
StylePlugin
继承了 QStylePlugin
,是插件类。
style_plugin.h
内容如下:
#ifndef STYLE_PLUGIN_H#define STYLE_PLUGIN_H#include <QStylePlugin>#include "simple_style.h"class StylePlugin : public QStylePlugin{ Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "simple_style.json")public: StylePlugin() {} QStyle *create(const QString &key) override { if (key.toLower() == "simplestyle") return new SimpleStyle(); return Q_NULLPTR; }};#endif // STYLE_PLUGIN_H
create()
用于创建并返回给定样式 key
的 QStyle
对象,如果插件无法创建样式,则应该返回 Q_NULLPTR
。
注意: 样式 key
通常是所需样式的类名,这些 key 不区分大小写。区分大小写因插件而异,所以在实现新插件时需要检查。
插件的元数据 - Json 文件
Json 元数据文件 simple_style.json
需要包含插件支持的样式名称:
{ "Keys": [ "simplestyle" ]}
注意: 这个文件非常关键,在插件生成之后,可以通过 QStyleFactory::keys()
来检测有效的 keys。也就是说,Json 文件中设置的值会由这个静态函数返回。
加载插件
一切准备就绪,来实现一个简单的应用程序,以动态加载插件。
工程文件 - .pro
由于这里需要的是一个可执行程序,所以需要将 TARGET 设置为 app。
app.pro
内容如下:
QT += widgetsSOURCES += main.cppTARGET = appwin32 { debug:DESTDIR = ../debug/ release:DESTDIR = ../release/} else { DESTDIR = ../}
main() 函数
当 QApplication
对象初始化完成后,使用 QStyleFactory::keys()
来检测所有有效的 keys,并使用 create()
(它是所有样式插件的包装器)来使用自定义的样式插件。
main.cpp
内容如下:
#include <QApplication>#include <QPushButton>#include <QStyleFactory>#include <qDebug>int main(int argv, char *args[]){ QApplication app(argv, args); // 设置样式 qDebug() << QStyleFactory::keys(); QApplication::setStyle(QStyleFactory::create("simplestyle")); QPushButton button("Blue Button"); button.resize(300, 100); button.show(); return app.exec();}
有效的 keys:
(“simplestyle”, “Windows”, “WindowsXP”, “WindowsVista”, “Fusion”)
可以看出,simplestyle
已经被包含进去了!
源码地址
GitHub 源码地址:StylePlugin
- 利用插件扩展Qt本身
- 利用插件扩展Qt应用程序
- 【转】Qt 扩展插件
- Qt 扩展-扩展部件和插件
- 如何利用jQuery扩展自己的插件
- 利用QT_DEBUG_PLUGINS检查Qt的插件问题
- 利用QT_DEBUG_PLUGINS检查Qt的插件问题
- 利用QT_DEBUG_PLUGINS检查Qt的插件问题
- Qt中扩展插件 命名空间的问题
- 利用jQuery无插件创建可扩展目录树
- jQuery.extend( object ); 扩展jQuery对象本身
- 插件扩展
- Qt 插件
- Qt 插件
- Qt插件
- QT-插件
- [QT]qt plugin插件
- ViewGroup其本身就是View的扩展---理解
- HDU1166:敌兵布阵(CDQ分治)
- 线性模型学习笔记
- 移动端前端页面实现学习笔记
- ArcGIS属性表操作
- Spring回顾(一)IoC & DI
- 利用插件扩展Qt本身
- Java JVM——基础概念介绍
- Robot Framework + Appium测试Android设备
- c++ 构造没完成 别的对象不能访问 析构时基类不要调用虚函数
- logstash 条件判断语句
- 温故而知新(五)java基础:String、StringBuffer 、StringBuilder
- 代码结构中Dao,Service,Controller,Util,Model是什么意思,为什么划分?
- ES-Hadoop学习之ES和HDFS数据交换
- int、short、char 类型超出范围赋值