feat: Repaint the skin of a custom control, and the painting is complete
MyStyle has completed, QStylePainter's inheritance rewrite has not yet started
This commit is contained in:
parent
158deb7c80
commit
77115da29d
@ -24,7 +24,8 @@
|
|||||||
#
|
#
|
||||||
#-------------------------------------------------
|
#-------------------------------------------------
|
||||||
|
|
||||||
QT += core gui
|
#xxxPrivate 继承 Q-xxxx-Private的话,是需要的添加 core-private(有一些核心方法? 类 可能不开放)
|
||||||
|
QT += core gui core-private # 若是需要继承 widgets相关,需要添加 widgets-private
|
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
@ -47,11 +48,14 @@ CONFIG += c++11
|
|||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
widget.cpp \
|
widget.cpp \
|
||||||
mystyle.cpp
|
mystyle.cpp \
|
||||||
|
myswitchbutton.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
widget.h \
|
widget.h \
|
||||||
mystyle.h
|
mystyle.h \
|
||||||
|
myswitchbutton.h \
|
||||||
|
myswitchbutton_p.h
|
||||||
|
|
||||||
# Default rules for deployment.
|
# Default rules for deployment.
|
||||||
qnx: target.path = /tmp/$${TARGET}/bin
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
@ -30,6 +30,46 @@ MyStyle::MyStyle()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyStyle::drawPrimitive(MyStyle::PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const
|
||||||
|
{
|
||||||
|
proxy()->drawPrimitive(static_cast<QStyle::PrimitiveElement>(pe), opt, p, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyStyle::drawControl(MyStyle::ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w) const
|
||||||
|
{
|
||||||
|
proxy()->drawControl(static_cast<QStyle::ControlElement>(element), opt, p, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect MyStyle::subElementRect(MyStyle::SubElement subElement, const QStyleOption *option, const QWidget *widget) const
|
||||||
|
{
|
||||||
|
return proxy()->subElementRect(static_cast<QStyle::SubElement>(subElement), option, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void MyStyle::drawComplexControl(MyStyle::ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget) const
|
||||||
|
//{
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
//QRect MyStyle::subControlRect(MyStyle::ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const
|
||||||
|
//{
|
||||||
|
// return QRect();
|
||||||
|
//}
|
||||||
|
|
||||||
|
int MyStyle::pixelMetric(MyStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
|
||||||
|
{
|
||||||
|
return proxy()->pixelMetric(static_cast<QStyle::PixelMetric>(metric), option, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
//QSize MyStyle::sizeFromContents(MyStyle::ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w) const
|
||||||
|
//{
|
||||||
|
// return QSize();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//int MyStyle::styleHint(MyStyle::StyleHint stylehint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *returnData) const
|
||||||
|
//{
|
||||||
|
// return 0;
|
||||||
|
//}
|
||||||
|
|
||||||
void MyStyle::polish(QWidget *widget)
|
void MyStyle::polish(QWidget *widget)
|
||||||
{
|
{
|
||||||
QCommonStyle::polish(widget);
|
QCommonStyle::polish(widget);
|
||||||
@ -40,8 +80,24 @@ void MyStyle::unpolish(QWidget *widget)
|
|||||||
QCommonStyle::unpolish(widget);
|
QCommonStyle::unpolish(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MyStyle::drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const
|
void MyStyle::drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const
|
||||||
{
|
{
|
||||||
|
switch (pe) {
|
||||||
|
case PE_SwitchButtonGroove: {
|
||||||
|
if (const QStyleOptionButton* swtchBtn = qstyleoption_cast<const QStyleOptionButton*>(opt)) {
|
||||||
|
p->setBrush(Qt::red);
|
||||||
|
p->drawRoundedRect(swtchBtn->rect, 8, 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PE_SwitchButtonHandle: {
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
QCommonStyle::drawPrimitive(pe, opt, p, w);
|
QCommonStyle::drawPrimitive(pe, opt, p, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +126,19 @@ void MyStyle::drawControl(QStyle::ControlElement element, const QStyleOption *op
|
|||||||
p->fillRect(opt->rect, QColor("#de6161"));
|
p->fillRect(opt->rect, QColor("#de6161"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case CE_SwitchButton: {
|
||||||
|
if (const QStyleOptionButton *switchBtn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
|
||||||
|
QStyleOptionButton option = *switchBtn;
|
||||||
|
option.palette = switchBtn->palette;
|
||||||
|
|
||||||
|
option.rect = subElementRect(SE_SwitchButtonGroove, opt, w);
|
||||||
|
drawPrimitive(PE_SwitchButtonGroove, &option, p, w);
|
||||||
|
|
||||||
|
option.rect = subElementRect(SE_SwitchButtonHandle, opt, w);
|
||||||
|
drawPrimitive(PE_SwitchButtonHandle, &option, p, w);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -79,6 +148,37 @@ void MyStyle::drawControl(QStyle::ControlElement element, const QStyleOption *op
|
|||||||
|
|
||||||
QRect MyStyle::subElementRect(QStyle::SubElement subElement, const QStyleOption *option, const QWidget *widget) const
|
QRect MyStyle::subElementRect(QStyle::SubElement subElement, const QStyleOption *option, const QWidget *widget) const
|
||||||
{
|
{
|
||||||
|
switch (subElement) {
|
||||||
|
case SE_SwitchButtonGroove: {
|
||||||
|
if (const QStyleOptionButton* switchBtn = qstyleoption_cast<const QStyleOptionButton*>(option))
|
||||||
|
return switchBtn->rect;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SE_SwitchButtonHandle: {
|
||||||
|
if (const QStyleOptionButton* switchBtn = qstyleoption_cast<const QStyleOptionButton*>(option)) {
|
||||||
|
int handleWidth = pixelMetric(PM_SwitchButtonHandleWidth, option, widget);
|
||||||
|
//pixelMetric(PM_SwitchButtonHandleWidth, option, widget);
|
||||||
|
QRect rectHandle(0, 0, 0, 0);
|
||||||
|
rectHandle.setHeight(switchBtn->rect.height());
|
||||||
|
|
||||||
|
if (switchBtn->rect.width() / 2.0 <= handleWidth)
|
||||||
|
rectHandle.setWidth(switchBtn->rect.width() / 2.0);
|
||||||
|
else
|
||||||
|
rectHandle.setWidth(handleWidth);
|
||||||
|
|
||||||
|
if (switchBtn->state & QStyle::State_On)
|
||||||
|
rectHandle.moveRight(switchBtn->rect.right());
|
||||||
|
else
|
||||||
|
rectHandle.moveLeft(switchBtn->rect.left());
|
||||||
|
|
||||||
|
return rectHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return QCommonStyle::subElementRect(subElement, option, widget);
|
return QCommonStyle::subElementRect(subElement, option, widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +194,15 @@ QRect MyStyle::subControlRect(QStyle::ComplexControl cc, const QStyleOptionCompl
|
|||||||
|
|
||||||
int MyStyle::pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
|
int MyStyle::pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
|
||||||
{
|
{
|
||||||
|
switch (metric) {
|
||||||
|
case PM_SwitchButtonHandleWidth:
|
||||||
|
return 30;
|
||||||
|
case PM_SwithcButtonHandleHeight:
|
||||||
|
return 12;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return QCommonStyle::pixelMetric(metric, option, widget);
|
return QCommonStyle::pixelMetric(metric, option, widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,21 +26,73 @@
|
|||||||
|
|
||||||
class MyStyle : public QCommonStyle
|
class MyStyle : public QCommonStyle
|
||||||
{
|
{
|
||||||
|
// Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
//这里新增加的枚举,是属于 MyStyle:: , 而非 QStyle:: 范围
|
||||||
|
enum ControlElement {
|
||||||
|
CE_SwitchButton = QStyle::CE_CustomBase + 1, //switchButton 控件
|
||||||
|
CE_CustomBase = QStyle::CE_CustomBase + 0xf00000
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SubElement {
|
||||||
|
SE_SwitchButtonGroove = QStyle::SE_CustomBase + 1, //滑槽矩形大小
|
||||||
|
SE_SwitchButtonHandle, //滑块矩形大小
|
||||||
|
SE_CustomBase = QStyle::SE_CustomBase + 0xf00000
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PixelMetric {
|
||||||
|
PM_SwitchButtonHandleWidth = QStyle::PM_CustomBase + 1, //switch Handle width
|
||||||
|
PM_SwithcButtonHandleHeight, //switch Handle height
|
||||||
|
PM_CustomBase = QStyle::PM_CustomBase + 0xf00000
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PrimitiveElement {
|
||||||
|
PE_SwitchButtonGroove = QStyle::PE_CustomBase + 1, //滑槽
|
||||||
|
PE_SwitchButtonHandle, //滑块
|
||||||
|
PE_CustomBase = QStyle::PE_CustomBase + 0xf00000
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MyStyle();
|
MyStyle();
|
||||||
|
|
||||||
// QStyle interface
|
// QStyle interface
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
//新增加的枚举属 MyStyle:: , 之能够在此内敛函数里面调用
|
||||||
|
inline void drawPrimitive(MyStyle::PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w = nullptr) const;
|
||||||
|
inline void drawControl(MyStyle::ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w) const;
|
||||||
|
inline QRect subElementRect(MyStyle::SubElement subElement, const QStyleOption *option, const QWidget *widget) const;
|
||||||
|
// inline void drawComplexControl(MyStyle::ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget) const;
|
||||||
|
// inline QRect subControlRect(MyStyle::ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const;
|
||||||
|
inline int pixelMetric(MyStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const;
|
||||||
|
// inline QSize sizeFromContents(MyStyle::ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w) const;
|
||||||
|
// inline int styleHint(MyStyle::StyleHint stylehint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *returnData) const;
|
||||||
|
|
||||||
|
//这里的快捷方式创建的枚举,都是不带QStyle:: ; 但是快捷方式的定义是带是QStyle:: , 此处声明的地方必须加上 QStyle:: /*后面改写更复杂的得写上MyStyle:: 因添加自定义的枚举*/
|
||||||
|
//这里 override 的虚函数,只能够调用旧有的 QStyle:: 的函数
|
||||||
|
virtual void drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const override;
|
||||||
|
virtual void drawControl(QStyle::ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w) const override;
|
||||||
|
virtual QRect subElementRect(QStyle::SubElement subElement, const QStyleOption *option, const QWidget *widget) const override;
|
||||||
|
virtual void drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget) const override;
|
||||||
|
virtual QRect subControlRect(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const override;
|
||||||
|
virtual int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const override;
|
||||||
|
virtual QSize sizeFromContents(QStyle::ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w) const override;
|
||||||
|
virtual int styleHint(QStyle::StyleHint stylehint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *returnData) const override;
|
||||||
virtual void polish(QWidget *widget) override;
|
virtual void polish(QWidget *widget) override;
|
||||||
virtual void unpolish(QWidget *widget) override;
|
virtual void unpolish(QWidget *widget) override;
|
||||||
virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const override;
|
|
||||||
virtual void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w) const override;
|
//重实现,使得父类的多个同名 函数 (不同参数) 任然可以在本类里面使用
|
||||||
virtual QRect subElementRect(SubElement subElement, const QStyleOption *option, const QWidget *widget) const override;
|
using QCommonStyle::polish;
|
||||||
virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget) const override;
|
using QCommonStyle::unpolish;
|
||||||
virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const override;
|
using QCommonStyle::drawPrimitive;
|
||||||
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const override;
|
using QCommonStyle::drawControl;
|
||||||
virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w) const override;
|
using QCommonStyle::subElementRect;
|
||||||
virtual int styleHint(StyleHint stylehint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *returnData) const override;
|
using QCommonStyle::drawComplexControl;
|
||||||
|
using QCommonStyle::subControlRect;
|
||||||
|
using QCommonStyle::pixelMetric;
|
||||||
|
using QCommonStyle::sizeFromContents;
|
||||||
|
using QCommonStyle::styleHint;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
69
QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.cpp
Normal file
69
QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#include "myswitchbutton.h"
|
||||||
|
#include "myswitchbutton_p.h"
|
||||||
|
#include "mystyle.h"
|
||||||
|
|
||||||
|
#include <QStylePainter>
|
||||||
|
#include <QStyleOptionButton>
|
||||||
|
|
||||||
|
MySwitchButton::MySwitchButton(QWidget *parent)
|
||||||
|
: QAbstractButton(parent)
|
||||||
|
{
|
||||||
|
Q_D(MySwitchButton);
|
||||||
|
|
||||||
|
d->init();
|
||||||
|
}
|
||||||
|
|
||||||
|
MySwitchButton::~MySwitchButton()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize MySwitchButton::sizeHint() const
|
||||||
|
{
|
||||||
|
return QSize(100, 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MySwitchButton::paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(event)
|
||||||
|
|
||||||
|
QStyleOptionButton opt;
|
||||||
|
initStyleOption(&opt);
|
||||||
|
|
||||||
|
QStylePainter pa(this);
|
||||||
|
// pa.drawControl(MyStyle::CE_SwitchButton, opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MySwitchButton::initStyleOption(QStyleOptionButton *opt) const
|
||||||
|
{
|
||||||
|
if (!opt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
opt->init(this);
|
||||||
|
opt->initFrom(this);
|
||||||
|
|
||||||
|
if (isChecked())
|
||||||
|
opt->state |= QStyle::State_On;
|
||||||
|
else
|
||||||
|
opt->state |= QStyle::State_Off;
|
||||||
|
}
|
||||||
|
|
||||||
|
MySwitchButtonPrivate::MySwitchButtonPrivate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MySwitchButtonPrivate::~MySwitchButtonPrivate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MySwitchButtonPrivate::init()
|
||||||
|
{
|
||||||
|
Q_Q(MySwitchButton);
|
||||||
|
|
||||||
|
checked = false;
|
||||||
|
animationStart = 0;
|
||||||
|
animationEnd = 1;
|
||||||
|
q->setObjectName("MySwitchButton");
|
||||||
|
// q->connect(q, &MySwitchButton::toggled, q, &MySwitchButton::checkedChanged);
|
||||||
|
}
|
29
QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.h
Normal file
29
QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef MYSWITCHBUTTON_H
|
||||||
|
#define MYSWITCHBUTTON_H
|
||||||
|
|
||||||
|
#include <QAbstractButton>
|
||||||
|
class QStyleOptionButton;
|
||||||
|
|
||||||
|
class MySwitchButtonPrivate;
|
||||||
|
class MySwitchButton : public QAbstractButton//bianxinagjicengle QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit MySwitchButton(QWidget* parent = nullptr);
|
||||||
|
~MySwitchButton();
|
||||||
|
|
||||||
|
// QWidget interface
|
||||||
|
public:
|
||||||
|
virtual QSize sizeHint() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void paintEvent(QPaintEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initStyleOption(QStyleOptionButton *opt) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DECLARE_PRIVATE(MySwitchButton)
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MYSWITCHBUTTON_H
|
29
QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton_p.h
Normal file
29
QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton_p.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef MYSWITCHBUTTON_P_H
|
||||||
|
#define MYSWITCHBUTTON_P_H
|
||||||
|
|
||||||
|
#include <private/qobject_p.h>
|
||||||
|
/*!
|
||||||
|
* \~chinese \class MySwitchButtonPrivate
|
||||||
|
* \~chinese \brief MySwitchButton 类的数据类, 便于实现源码/二进制兼容, 通常继承于 “自定义_Private” 的类
|
||||||
|
* 若是自定义控件,没有继承于 QObjectPrivate 之类的, 使用 Q_Q Q_D 时候,会报错,需要自己定义 q_fun() 函数
|
||||||
|
* \~chinese \sa Qt 自带的 QPushButtonPrivate, QPushButton 实现
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MySwitchButtonPrivate : public QObjectPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit MySwitchButtonPrivate();
|
||||||
|
~MySwitchButtonPrivate();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool checked;
|
||||||
|
double animationStart;
|
||||||
|
double animationEnd;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Q_DECLARE_PUBLIC(MySwitchButton) //要加上宏
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MYSWITCHBUTTON_P_H
|
Loading…
Reference in New Issue
Block a user