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
|
||||
|
||||
@ -47,11 +48,14 @@ CONFIG += c++11
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
widget.cpp \
|
||||
mystyle.cpp
|
||||
mystyle.cpp \
|
||||
myswitchbutton.cpp
|
||||
|
||||
HEADERS += \
|
||||
widget.h \
|
||||
mystyle.h
|
||||
mystyle.h \
|
||||
myswitchbutton.h \
|
||||
myswitchbutton_p.h
|
||||
|
||||
# Default rules for deployment.
|
||||
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)
|
||||
{
|
||||
QCommonStyle::polish(widget);
|
||||
@ -40,8 +80,24 @@ void MyStyle::unpolish(QWidget *widget)
|
||||
QCommonStyle::unpolish(widget);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -70,6 +126,19 @@ void MyStyle::drawControl(QStyle::ControlElement element, const QStyleOption *op
|
||||
p->fillRect(opt->rect, QColor("#de6161"));
|
||||
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:
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
{
|
||||
switch (metric) {
|
||||
case PM_SwitchButtonHandleWidth:
|
||||
return 30;
|
||||
case PM_SwithcButtonHandleHeight:
|
||||
return 12;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return QCommonStyle::pixelMetric(metric, option, widget);
|
||||
}
|
||||
|
||||
|
@ -26,21 +26,73 @@
|
||||
|
||||
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:
|
||||
MyStyle();
|
||||
|
||||
// QStyle interface
|
||||
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 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;
|
||||
virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget) const override;
|
||||
virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const override;
|
||||
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const override;
|
||||
virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w) const override;
|
||||
virtual int styleHint(StyleHint stylehint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *returnData) const override;
|
||||
|
||||
//重实现,使得父类的多个同名 函数 (不同参数) 任然可以在本类里面使用
|
||||
using QCommonStyle::polish;
|
||||
using QCommonStyle::unpolish;
|
||||
using QCommonStyle::drawPrimitive;
|
||||
using QCommonStyle::drawControl;
|
||||
using QCommonStyle::subElementRect;
|
||||
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