diff --git a/QtMyStyleEx/QtExample03/QtStyleEx/QtStyleEx.pro b/QtMyStyleEx/QtExample03/QtStyleEx/QtStyleEx.pro index c9dad30..fd965a5 100644 --- a/QtMyStyleEx/QtExample03/QtStyleEx/QtStyleEx.pro +++ b/QtMyStyleEx/QtExample03/QtStyleEx/QtStyleEx.pro @@ -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 diff --git a/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.cpp b/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.cpp index d0378df..22b0123 100644 --- a/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.cpp +++ b/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.cpp @@ -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(pe), opt, p, w); +} + +void MyStyle::drawControl(MyStyle::ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w) const +{ + proxy()->drawControl(static_cast(element), opt, p, w); +} + +QRect MyStyle::subElementRect(MyStyle::SubElement subElement, const QStyleOption *option, const QWidget *widget) const +{ + return proxy()->subElementRect(static_cast(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(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(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(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(option)) + return switchBtn->rect; + } + break; + case SE_SwitchButtonHandle: { + if (const QStyleOptionButton* switchBtn = qstyleoption_cast(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); } diff --git a/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.h b/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.h index acf8031..87921e6 100644 --- a/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.h +++ b/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.h @@ -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; }; diff --git a/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.cpp b/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.cpp new file mode 100644 index 0000000..ddb444f --- /dev/null +++ b/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.cpp @@ -0,0 +1,69 @@ +#include "myswitchbutton.h" +#include "myswitchbutton_p.h" +#include "mystyle.h" + +#include +#include + +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); +} diff --git a/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.h b/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.h new file mode 100644 index 0000000..a72f9e1 --- /dev/null +++ b/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.h @@ -0,0 +1,29 @@ +#ifndef MYSWITCHBUTTON_H +#define MYSWITCHBUTTON_H + +#include +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 diff --git a/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton_p.h b/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton_p.h new file mode 100644 index 0000000..bc96f24 --- /dev/null +++ b/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton_p.h @@ -0,0 +1,29 @@ +#ifndef MYSWITCHBUTTON_P_H +#define MYSWITCHBUTTON_P_H + +#include +/*! + * \~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