本文为原创文章,转载请注明出处,或注明转载自“黄邦勇帅(原名:黄勇)
本文出自本人原创著作《Qt5.10 GUI完全参考手册》网盘地址:
https://pan.baidu.com/s/1iqagt4SEC8PUYx6t3ku39Q
《C++语法详解》网盘地址:https://pan.baidu.com/s/1dIxLMN5b91zpJN2sZv1MNg
若对C++语法不熟悉,建议参阅本人所著《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解,可确保读者彻底弄懂C++的原理,彻底解惑C++,使其知其然更知其所以然。此书是一本全面了解C++不可多得的案头必备图书。
13.1 简单的使用QStyle类(风格也称为样式)
13.1.1 样式基础
QStyle类继承自QObject,该类是一个抽像类。QStyle类描述了GUI的界面外观,Qt的内置部件使用该类执行几乎所有的绘制,以确保使这些部件看起来与本地部件完全相同。
Qt内置了一系列样式,windows样式和fusion样式默认是可用的,而有些样式需在特定平台上才有用,比如windowsxp样式、windowsvisata样式、gtk样式、macintosh样式等。
使用QStyle的步骤如下
①、使用QStyleFactory::create()静态函数创建一个QStyle对象。
②、然后使用以下函数把样式设置到部件或程序中
使用QWidget::setStyle()函数为某个单个的部件设置样式。
使用QApplication::setStyle()静态函数来设置整个程序的样式。
还可由应用程序的用户使用-style命令行选项指定样式,比如
xxx -style windows //使用windows样式。
若未指定样式,则Qt将选择与用户的平台或桌面环境最合适的样式。
示例13.1:QStyle使用示例(效果见图13-2)
#include
int main(int argc, char *argv[]){ QApplication aa(argc,argv);
QWidget w;
QPushButton *pb1=new QPushButton("AAA",&w); pb1->move(22,22);
QPushButton *pb2=new QPushButton("BBB",&w); pb2->move(111,22);
QPushButton *pb3=new QPushButton("CCC",&w); pb2->move(222,22);
pb1->setStyle(QStyleFactory::create("fusion")); //仅按钮pb1使用系统内置的fusion样式
aa.setStyle(QStyleFactory::create("windows")); //整个程序使用系统内置的windows样式
w.resize(444,333); w.show(); return aa.exec(); }
13.1.2 QStyleFactory类及其函数
QStyleFactory类是一个独立的类,该类主要用于创建一个QStyle对象。
QStyleFactory类的成员函数如下
1)、static QStyle *create(const QString &key); //静态的
创建并返回与键key匹配的QStyle对象,若没有匹配的QStyle,则返回0。来自样式插件的样式和内置样式都会被匹配。注意:key不区分大小写。
2)、static QStringList keys(); //静态的
返回QStyleFactory类可以创建的QStyle的键。在创建样式之前,可以使用qDebug()<
13.3 自定义部件的外观
13.3.1 自定义部件外观基础
有3种方法可实现自定义界面外观:重新实现paintEvent()函数、使用QStyle类的绘制函数、子类化QStyle,本小节仅介绍方法1和2的使用方式,方法3见下一节。
1、方法一:重新实现QWidget::paintEvent()函数实现界面外观的绘制
使用此方法工作量比较大,下面举一简单示例对此原理作一说明,以便对后续内容的理解
示例13.3:重新实现paintEvent()函数绘制部件的自定义外观(效果见图13-4)
//m.h文件的内容
#ifndef M_H
#define M_H
#include
class B:public QPushButton{ Q_OBJECT //子类化QPushButton
public:
bool b; //用于存储鼠标光标进入或离开按钮的状态
bool press; //用于存储按钮是否被按下的状态
B(QString s,QWidget *p1=0):QPushButton(s,p1){ b=0; press=0;}
void mousePressEvent(QMouseEvent *e){
press=1; //保存按钮被按下的状态
update(); //更新按钮,此步不可缺少,否则按钮外观不会即时更新。
QPushButton::mousePressEvent(e);};
void mouseReleaseEvent(QMouseEvent *e){ press=0; //按钮未被按下
update(); QPushButton::mouseReleaseEvent(e); };
void enterEvent(QEvent *event){ b=1; //保存鼠标进入按钮的状态
update(); QPushButton::enterEvent(event); }
void leaveEvent(QEvent *event){ b=0; //鼠标离开按钮的状态
update(); QPushButton::leaveEvent(event); }
void paintEvent(QPaintEvent *e){ //自定义绘制按钮的外观
QPainter pr(this);
QBrush bs(QColor(111,111,111)); //灰色
QPen pn(Qt::DotLine); //此画笔主要用于绘制焦点框(绿色)
pn.setColor(QColor(1,111,1)); pn.setWidth(4);
QRect r=rect(); //获取设置的按钮的大小。
if(b==0){ //若鼠标离开按钮
pr.fillRect(r,bs); //使用画刷bs(灰色)填充按钮的背景,其大小为r
pr.drawText(r,Qt::AlignCenter,text());} //绘制按钮上的文本
if(b==1){ pr.fillRect(r,QColor(255,1,1)); //若鼠标进入按钮,则填充红色背景
pr.drawText(r,Qt::AlignCenter,text()); } //绘制按钮上的文本
if(b==1&&press==1){ //鼠标进入按钮且按钮被按下
pr.fillRect(r,QColor(222,222,222)); pr.drawText(r,Qt::AlignCenter,text());}
if(b==0&&press==0){ //鼠标离开按钮且按钮未被按下
pr.fillRect(r,bs); pr.drawText(r,Qt::AlignCenter,text());}
if(hasFocus()) { //按钮获得焦点
pr.setPen(pn);pr.drawRect(r.adjusted(1,1,-2,-2)); } }}; //绘制一个矩形边框(绿色)
#endif // M_H
//m.cpp文件的内容
#include "m.h"
int main(int argc, char *argv[]){ QApplication aa(argc,argv);
QWidget w;
//使用自定义外观的按钮
B *pb1=new B("AAA",&w); pb1->move(22,22); pb1->resize(221,22);
B *pb2=new B("BBB",&w); pb2->move(22,88);
w.resize(444,333); w.show(); return aa.exec(); }
2、方法二:使用QStyle类的绘制函数实现界面外观的绘制
通常QStyle类的绘制函数需要如下4个参数:
①、一个QStyle枚举值:用于指定需要绘制什么类型的图形元素,比如QStyle::CE_PushButton表示绘制按钮。
②、一个QStyleOption或其子类对象(样式选项)。样式选项包含了需要绘制的图形元素的所有信息,比如包含了图形元素的文本、调色板等。根据绘制的内容,样式需要不同的样式选项类,比如QStyle::CE_PushButton元素,需要一个QStyleOptionButton类型的参数。
③、一个用于绘制图形的QPainter
④、执行绘制的QWidget(可选),通常是需要绘制的元素的部件。
⑤、可使用QStylePainter类中的绘制函数代替QStyle类的相应绘制函数,其主要好处是可减少调用函数时的实参个数。
示例13.4:使用QStyle类的绘制函数自定义部件样式(效果见图13-5)
//m.h文件的内容
#ifndef M_H
#define M_H
#include
class B:public QPushButton{ Q_OBJECT //子类化QPushButton
public: B(QString s,QWidget *p1=0):QPushButton(s,p1){}
void paintEvent(QPaintEvent *e){ //需要重新实现该函数以绘制自定义的按钮样式
QPainter pr(this);
QStyleOptionButton psb; //创建一个按钮样式选项
psb.rect=rect(); //设置绘制的按钮的大小,此步不可省略,否则绘制的按钮将不可见
psb.text="FFF"; //设置按钮上显示的文本,要使按钮被设置为用户创建按钮时的文本
//可使用psb.text=text();代替此语句。
psb.features=QStyleOptionButton::HasMenu; //设置按钮的样式为带有下拉菜单的按钮
//获取该按钮的样式对象,并使用该样式的drawControl()函数绘制按钮。
style()->drawControl(QStyle::CE_PushButton, &psb, &pr, this);
//也可使用如下代码绘制,使用实参个数更少
//QStylePainter sp; sp.drawControl(QStyle::CE_PushButton,&psb);
} };
//m.cpp文件的内容
#include "m.h"
int main(int argc, char *argv[]){ QApplication aa(argc,argv);
QWidget w;
B *pb1=new B("AAA",&w); pb1->move(22,22); pb1->resize(221,22);
B *pb2=new B("BBB",&w); pb2->move(22,88);
w.resize(444,333); w.show(); return aa.exec(); }
本文作者:黄邦勇帅(原名:黄勇)