UI
设计器提供的界面组件不满足实际设计需求时,
可从QWidget
继承自定义界面组件
两种方法使用自定义界面组件
- 提升法
提升法用于界面可视化设计时不够直观
不能在界面上即刻显示自定义组件的效果
- 为UI
设计器设计自定义界面组件的Widget
插件
直接安装到UI
设计器的组件面板里
如图Qt
自带的界面设计组件一样使用
在设计时就可看到组件的实际显示效果
编译和运行时需要使用到插件的动态链接库
自定义Widget组件
自定义Widget子类QmyBattery
所有界面组件的基类是QWidget
要设计自定义的界面组件,可从QWidget
继承一个自定义的类,重定义其paintEvent()
事件,利用Qt
绘图功能绘制组件外观,实现需要的其他功能
设计一个从QWidget
继承的类QmyBattery
创建C++
类
QWidget
类的paintEvent()
事件用于界面绘制,
在此事件里,可使用QPainter
的各种绘图功能绘制自己需要的界面
对QPainter
:
void setViewport(...)
void setWindow(...)
void setRenderHint(...)
void setPen(...)
void setBrush(...)
void drawRect(...)
void drawText(...)
如:QFontMetrics,QBrush,QPen,QRect
自定义Widget组件的使用
实现了QmyBattery
类后,若用代码创建QmyBattery
类对象,其使用与一般的组件类是一样的
若是在UI
设计器中使用QmyBattery
,则需要采用提升法
界面上放置的QWidget
组件可被提升为QmyBattery
,但这个组件的"Go to slot"
对话框里并没有QmyBattery
类的powerLevelChanged(int)
信号.无法采用可视化方法生成信号的槽函数
在主窗口上放置一个QSlider
组件和一个QLabel
组件
滑动标尺改变数值时,设置为battery
的当前电量值
自定义Qt Designer插件
创建Qt Designer Widget插件项目
Qt
提供两种设计插件的API
,可用于扩展Qt
的功能
高级API
用于设计插件以扩展Qt的功能
如:定制数据库驱动,图像格式,文本编码,定制样式等
Qt Creator
里大量采用了插件,单击Qt Creator
的主菜单栏的"Help"->"About Plugins"
会显示Qt Creator
已经安装的各种插件
低级API
用于创建插件以扩展自己编写应用程序的功能
常见的就是将自定义Widget
组件安装到UI
设计器里,用于窗口界面设计
本节采用创建Qt Designer
插件的方式来创建这个类,并将其安装到UI
设计器的组件面板里
要创建UI
设计器插件类
单机Qt Creator
的"File"-->"New File or Project"
菜单
在出现的对话框里选择"Other Project"
分组的"Qt Custom Designer Widget"
项目,
出现一个向导对话框,完成项目创建
第一步是设置插件项目的名称和保存路径
第二步是选择项目编译器,可选择多个编译器,编译时再选择具体的编译器
编译插件的编译器版本需和编译Qt Creator
的版本一致
第三步是设置自定义QWidget
类的名称,
只需在左侧的Widget classes
列表里设置类名,右侧就会自动设置缺省的文件名,还可选择一个图标文件作为自定义组件在UI设计器组件面板里的显示图标
在Description
页还可设置Group, Tooltip, What's this
等信息
Group
是自定义组件在组件面板里的分组名称,这里设置为"My Widget"
第四步是显示和设置插件,资源文件名称
本实例缺省插件名称是qwbatteryplugin
资源文件名称为icons.qrc
,一般用缺省的即可
第五步,完成设置,生成项目
文件包括:
- 如QwBatteryPlugin.pro
插件项目的项目文件,用于实现插件接口
- qwbatteryplugin.h
和qwbatteryplugin.cpp
是插件的头文件和实现文件
- icons.qrc
是插件项目的资源文件,存储了图标
- qwbattery.pri
是包含在QwBatteryPlugin.pro
项目中的一个项目文件
用于管理自定义组件类
- qwbattery.h
和qwbattery.cpp
是自定义类QwBattery
的头文件和实现文件
插件项目各文件的功能实现
1.QwBatteryPlugin
类
QwBatteryPlugin
类实现了QDesignerCustomWidgetInterface
接口,
这是专门为Qt Designer
设计自定义Widget
组件的接口
在这个类定义里,用Q_INTERFACES
宏声明了实现的接口,用Q_PLUGIN_METADATA
声明了元数据名称
2.QwBatteryPlugin.pro
的内容
// plugin表示项目要作为插件
// 编译后会产生lib和dll/.so文件
// debug_and_release表示项目可以用debug和release模式编译
CONFIG += plugin debug_and_release
TARGET = $$qtLibraryTarget(qwbatteryplugin)
// 表示项目是一个库,一般的应用程序模板类型是app
TEMPLATE = lib
HEADERS = qwbatteryplugin.h
SOURCES = qwbatteryplugin.cpp
RESOURCES = icons.qrc
LIBS += -L.
greaterThan(Qt_MAJOR_VERSION, 4)
{
Qt += designer
}
else
{
CONFIG += designer
}
target.path = $$[Qt_INSTALL_PLUGINS]/designer
INSTALLS += target
// 是内置于QwBatteryPlugin.pro中的项目
// qwbattery.pri项目配置文件只有两行,也就是这个内置项目中包含的头文件和源文件名称
include(qwbattery.pri)
3.组件类QwBattery
的定义
QwBattery
类的定义与QmBattery
的定义基本一样,
只是在声明类的时候需要加一个宏QDESIGNER_WIDGET_EXPORT
且用Q_PROPERTY
宏定义了一个属性powerLevel
QwBattery
类的完整定义如下
QDESIGNER_WIDGET_EXPORT
宏用于将自定义组件类从插件导出给Qt Designer
使用,必须在类名称前使用此宏
Q_PROPERTY
宏用于定义属性,这里定义了一个int
类型的属性powerLevel
READ
宏声明了属性的读取函数是powerLevel()
WRITE
宏声明了设置属性值的函数是setPowerLevel()
NOTIFY
宏声明了其值变化时发射的信号是powerLevelChanged()
DESIGNABLE
宏定义属性在UI
设计器里是否可见,缺省为true
从QWidget
继承的子类QwBattery
作为插件安装到UI
设计器的组件面板里,则在设计期间就可以从属性编辑器里看到这个powerLevel
属性并设置
插件的编译与安装
用编译器,将插件项目在release
模式下编译,
编译后会生成qwbatteryplugin.dll
和qwbatteryplugin.lib
两个文件
qwbatteryplugin.dll
是插件的动态链接库文件,需将此文件复制到Qt Creator
的插件目录和Qt
的插件目录下.
如,要把Qt
安装到D:\Qt|Qt5.9.1
目录下,就需将qwbatteryplugin.dll
复制到如下两个目录下
(1). D:\Qt\Qt5.9.1\Tools\QtCreator\bin\plugins\designer
(2). D:\Qt\Qt5.9.1\5.9.1\msvc2015\plugins\designer
重启Qt Creator
,使用UI
设计器设计窗口时,
在左侧的组件面板里会看到增加了一个"My Widget"
分组
里面有一个组件QwBattery
编译和安装Widget
插件必须注意以下事项
- 要让插件在Qt creator
的UI
设计器里正常显示
编译插件项目的编译器必须与编译Qt Creator
的编译器一致
Qt Creator
的"Help"-->"About Qt Creator"
菜单项可看到这些信息
- 用debug
和release
模式编译的插件也分别只适用于debug
和release
模式编译的应用
在debug
模式下编译的插件项目生成的Lib
和DLL
文件会在文件名最后自动增加一个字母"d"
使用自定义插件
在Qt Creator
的UI
设计器的组件面板能正常显示自定义的QwBattery
组件后,就可在窗体设计时使用QwBattery
组件了
创建一个基于QWidget
的实例应用BatteryUser
设计窗体时,从组件面板上拖放一个QwBattery
到窗体上
在设计窗体时,能直接看到QwBattery
绘制的电池图形,
在属性编辑器里可以编辑QwBattery
组件的powerLevel
属性
在其"Go to slot"
对话框里会出现自定义的信号powerLevelChanged(int)
可为此信号设计槽函数
要正常编译项目BatteryUser
,还需做以下设置
- 在项目的源文件目录下创建一个include
子目录[名称随个人喜好设置]
将QwBattery
类定义的头文件qwbattery.h
插件的debug
和release
两种模式编译生成的库文件qwbatteryplugin.lib
及qwbatteryplugind.lib
复制到此目录,项目在编译链接时需要使用此头文件和库文件
- 项目管理器中,
选中BatteryUser
项目节点并单机右键,在快捷菜单中单击"Add Library..."
在出现的向导对话框第一步中,选择库类型时,将外部库"External Library"
选中,因为本项目需使用的是已经编译好的库文件
- 在向导的第二步
单击"Library file"
编辑框后面的按钮
选择include
目录下的库文件qwbatteryplugin.lib
会自动填充"Include path"
编辑框
选择平台,选择链接方式,
完成"Add Library"
对话框的设置后
Qt Creator
会自动修改项目文件BatteryUser.pro
的内容
在其中添加了以下几行
win32:CONFIG(release, debug|release):LIBS += -L$$PWD/include/ -lqwbatteryplugin
else: win32:CONFIG(debug, debug|release):LIBS += -L$$PWD/include/ -lqwbatteryplugind INCLUDEPATH += $$PWD/include
DEPENDPATH += $$PWD/include
LIBS
用于设置添加的库文件
会判断当前项目是以debug
还是release
模式编译
自动加入qwbatteryplugin.lib
或qwbatteryplugind.lib
库文件
INCLUDEPATH
和DEPENDPATH
用于设置头文件目录和项目依赖项目录,都指向项目路径下的include
目录
这样设置后,就可在release
或debug
模式下编译了
使用MSVC编译器输出中文的问题
在Qt Creator
中使用MSVC
编译器编译项目时,若处理不当容易出现中文字符乱码问题
因为Qt Creator
保存的文件使用的是UTF-8
编码
MSVC
编译器虽然可正常编译带BOM
的UTF-8
编码的源文件
但生成的可执行文件的编码是Windows
本地字符集
也就是在可执行文件中,字符串"当前电量"是以GB2313
编码的
可执行程序执行到这条语句时,对这个字符串却是以UTF-8
解码的.故出现乱码.
强制MSVC
编译器采用UTF-8
编码
创建和使用静态链接库
创建静态链接库
如xxx.lib/xxx.a,xxx.h