qt--自定义部件的外观
有 3 种方法可实现自定义界面外观:重新实现 paintEvent()函数,使用 QStyle 类的绘制函数,子类化 QStyle
方法一:Q通过 QWidget::paintEvent()
b.h文件
#ifndef B_H #define B_H #include <QPushButton> #include <QPainter> class B : public QPushButton //自定义按钮 { Q_OBJECT public: B(QString s,QWidget *p1=0); bool b; //用于存储鼠标光标进入或离开按钮的状态 bool press; //用于存储按钮是否被按下的状态 void mousePressEvent(QMouseEvent *e); //重写鼠标按下事件 void mouseReleaseEvent(QMouseEvent *e);//重写鼠标释放事件 void enterEvent(QEvent *event); //重写鼠标进入事件 void leaveEvent(QEvent *event); //重写鼠标离开事件 void paintEvent(QPaintEvent *e); //重写绘图事件 }; #endif // B_H
b.cpp
#include "b.h" B::B(QString s, QWidget *p1):QPushButton(s,p1) { b=0; press=0; } void B::mousePressEvent(QMouseEvent *e) { press=1; //保存按钮被按下的状态 update(); //更新按钮,此步不可缺少,否则按钮外观不会即时更新 //执行paintEvent函数 QPushButton::mousePressEvent(e); } void B::mouseReleaseEvent(QMouseEvent *e) { press=0; //按钮未被按下 update(); QPushButton::mouseReleaseEvent(e); } void B::enterEvent(QEvent *event) { b=1; //保存鼠标进入按钮的状态 update(); QPushButton::enterEvent(event); } void B::leaveEvent(QEvent *event) { b=0; //鼠标离开按钮的状态 update(); QPushButton::leaveEvent(event); } void B::paintEvent(QPaintEvent *e) { //自定义绘制按钮的外观 QPainter pr(this); QBrush bs(QColor(111,111,111)); //蓝色 QPen pn(Qt::DotLine); //此画笔主要用于绘制焦点框 //画笔风格:虚线 pn.setColor(QColor(255,0,0)); pn.setWidth(4); QRect r=rect(); //获取设置的按钮的大小 if(b==0){ //若鼠标离开按钮 pr.fillRect(r,bs); //使用画刷 bs(灰色)填充按钮的背景,其大小为 r pr.drawText(r,Qt::AlignCenter,text());//绘制按钮上的文本,使用 text()函数获取设置的按钮的文本。 } if(b==1){ pr.fillRect(r,QColor(111,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)); } //绘制一个矩形边框 QPushButton::paintEvent(e); }
win.h
#ifndef WIN_H #define WIN_H #include <QWidget> #include "b.h" class Win : public QWidget { Q_OBJECT public: Win(QWidget *parent = nullptr); ~Win(); }; #endif // WIN_H
win.cpp
#include "win.h" Win::Win(QWidget *parent) : QWidget(parent) { B *pb=new B("AAA",this); pb->move(10,10); } Win::~Win() { }
上面工程下载:链接:https://pan.baidu.com/s/1oD-ONNlaErmHNPq9Ab2l0A 提取码:6666
方法二:使用 QStyle 类
通常 QStyle 类的绘制函数需要如下 4 个参数:
①、一个 QStyle 枚举值:用于指定需要绘制什么类型的图形元素
②、一个 QStyleOption 或其子类对象(样式选项),样式选项包含了需要绘制的图形元素的所有信息,比如包含了图形元素的文本、调色板等。根据绘制的内容,样式需要不同的样式选项类,比如 QStyle::CE_PushButton 元素,需要一个 QStyleOptionButton 类型的参数。
③、一个用于绘制图形的 QPainter
④、执行绘制的 QWidget(可选),通常是需要绘制的元素的部件。
⑤、可使用 QStylePainter 类中的绘制函数代替 QStyle 类的相应绘制函数,其主要好处是可减少调用函数时的实参个数
QStyleOption子类有:
QStyleOptionButton, QStyleOptionComplex, QStyleOptionDockWidget, QStyleOptionFocusRect, QStyleOptionFrame, QStyleOptionGraphicsItem, QStyleOptionHeader, QStyleOptionMenuItem, QStyleOptionProgressBar, QStyleOptionRubberBand, QStyleOptionTab, QStyleOptionTabBarBase, QStyleOptionTabWidgetFrame, QStyleOptionToolBar, QStyleOptionToolBox, QStyleOptionViewItem
b.h
#ifndef B_H #define B_H #include <QPushButton> #include <QPainter> #include <QStyleOptionButton> class B : public QPushButton //创建控件的子类 { Q_OBJECT public: B(QString s,QWidget *p1=0); void paintEvent(QPaintEvent *e); //需要重新实现该函数以绘制自定义的按钮样式 }; #endif // B_H
b.cpp
#include "b.h" B::B(QString s, QWidget *p1):QPushButton(s,p1) { } void B::paintEvent(QPaintEvent *e) { QPainter pr(this); QStyleOptionButton psb; //创建一个按钮样式选项 //需要 #include <QStyleOptionButton> psb.rect=rect(); //设置绘制的按钮的大小,此步不可省略,否则绘制的按钮将不可见 //psb.text="FFF"; //设置按钮上显示的文本 psb.text=this->text(); //要使按钮被设置为用户创建按钮时的文本,可使用 psb.text=text()代替此语句 psb.features=QStyleOptionButton::HasMenu; //设置按钮的样式为带有下拉菜单的按钮 /* QStyleOptionButton::None 正常按钮 QStyleOptionButton::Flat 扁平按钮 QStyleOptionButton::HasMenu 具有下拉菜单 QStyleOptionButton::DefaultButton 默认按钮 QStyleOptionButton::AutoDefaultButton 自动默认按钮 QStyleOptionButton::CommandLinkButton 该按钮是Windows Vista类型的命令链接 */ style()->drawControl(QStyle::CE_PushButton, &psb, &pr, this);//绘制控件 //参数1:可以通过帮助文档搜索QStyle::ControlElement查看 //参数2:样式选项 //参数3:画家 //也可使用如下代码绘制 //QStylePainter sp; //sp.drawControl(QStyle::CE_PushButton,&psb); }
win.cpp
#include "win.h" Win::Win(QWidget *parent) : QWidget(parent) { this->resize(444,333); B *pb1=new B("AAA",this); pb1->move(22,22); pb1->resize(221,22); B *pb2=new B("BBB",this); pb2->move(22,88); } Win::~Win() { }
上面工程下载:链接:https://pan.baidu.com/s/1o9RF8ARYkojaYMd3iXIEHA 提取码:6666