From 1de27374cc5c07ee1cd1ce4b6dd0f38613acc7ab Mon Sep 17 00:00:00 2001 From: muli Date: Sun, 23 Feb 2020 13:14:55 +0800 Subject: [PATCH] feat: The custom control MySwitchButton has been implemented --- QtMyStyleEx/QtExample03/QtStyleEx/mystyle.cpp | 51 +++++++++++++---- QtMyStyleEx/QtExample03/QtStyleEx/mystyle.h | 12 ++-- .../QtExample03/QtStyleEx/myswitchbutton.cpp | 27 +++++---- .../QtExample03/QtStyleEx/myswitchbutton.h | 22 +++++++- .../QtExample03/QtStyleEx/myswitchbutton_p.h | 29 ++++++++-- QtMyStyleEx/QtExample03/QtStyleEx/widget.cpp | 7 +++ README.md | 55 ++++++++++++++----- 7 files changed, 155 insertions(+), 48 deletions(-) diff --git a/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.cpp b/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.cpp index 58d3d96..c5c77ae 100644 --- a/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.cpp +++ b/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.cpp @@ -21,7 +21,6 @@ #include "mystyle.h" -#include #include #include @@ -38,7 +37,6 @@ void MyStyle::drawPrimitive(const QStyle *style, MyStyle::PrimitiveElement pe, c void MyStyle::drawControl(const QStyle *style, MyStyle::ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w) { - } QRect MyStyle::subElementRect(const QStyle *style, MyStyle::SubElement subElement, const QStyleOption *option, const QWidget *widget) @@ -102,19 +100,37 @@ 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); + if (const QStyleOptionButton* switchBtn = qstyleoption_cast(opt)) { + p->setPen(Qt::NoPen); + if (switchBtn->state & State_On) + p->setBrush(QColor("#77d472")); + + if (switchBtn->state & State_Off) { + p->setPen(QPen(QColor("#e5e5e5"), 2)); + p->setBrush(QColor("#fdfefd")); + } + + p->drawRoundedRect(switchBtn->rect.adjusted(1, 1, -1, -1), switchBtn->rect.height() / 2.0, switchBtn->rect.height() / 2.0); } } break; case PE_SwitchButtonHandle: { + if (const QStyleOptionButton* switchBtn = qstyleoption_cast(opt)) { + p->setPen(Qt::NoPen); + if (switchBtn->state & State_On) + p->setBrush(QColor("#fefffe")); + if (switchBtn->state & State_Off) + p->setPen(QPen(QColor("#e5e5e5"), 2)); + + QRect rectHandle = switchBtn->rect.adjusted(1, 1, -1, -1); + int r = qMin(rectHandle.width() / 2.0, rectHandle.height() / 2.0); + p->drawEllipse(rectHandle.center(), r, r); + } } break; default: @@ -185,7 +201,6 @@ QRect MyStyle::subElementRect(QStyle::SubElement subElement, const QStyleOption 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()); @@ -194,10 +209,10 @@ QRect MyStyle::subElementRect(QStyle::SubElement subElement, const QStyleOption else rectHandle.setWidth(handleWidth); + if (switchBtn->state & QStyle::State_Off) + rectHandle.moveLeft(switchBtn->rect.left() + 5); if (switchBtn->state & QStyle::State_On) - rectHandle.moveRight(switchBtn->rect.right()); - else - rectHandle.moveLeft(switchBtn->rect.left()); + rectHandle.moveRight(switchBtn->rect.right() - 5); return rectHandle; } @@ -296,6 +311,21 @@ void MyStylePainter::drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOpti m_qStyle->drawPrimitive(pe, opt, this, m_widget); } +MyStylePainter::MyStylePainter() + : QPainter() +{ + m_widget = nullptr; + m_myStyleHelp = nullptr; +} + +MyStylePainter::MyStylePainter(QWidget* w) +{ + m_widget = w; + m_qStyle = w->style(); + m_myStyleHelp.setStyle(m_qStyle); + QPainter::begin(w); //是调用父类的 begin(), 调试半天才发现 +} + void MyStylePainter::drawPrimitive(MyStyle::PrimitiveElement pe, const QStyleOption *opt) { m_myStyleHelp.drawPrimitive(pe, opt, this, m_widget); @@ -310,4 +340,3 @@ void MyStylePainter::drawControl(MyStyle::ControlElement element, const QStyleOp { m_myStyleHelp.drawControl(element, opt, this, m_widget); } - diff --git a/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.h b/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.h index 62eef32..53b8312 100644 --- a/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.h +++ b/QtMyStyleEx/QtExample03/QtStyleEx/mystyle.h @@ -106,7 +106,6 @@ public: using QCommonStyle::pixelMetric; using QCommonStyle::sizeFromContents; using QCommonStyle::styleHint; - }; class MyStyleHelp @@ -132,13 +131,14 @@ private: class MyStylePainter : public QPainter { public: - MyStylePainter() {} + MyStylePainter(); + MyStylePainter(QWidget* w); ~MyStylePainter() {} - inline void drawPrimitive(MyStyle::PrimitiveElement pe, const QStyleOption *opt); - inline void drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption *opt); - inline void drawControl(MyStyle::ControlElement element, const QStyleOption *opt); - inline void drawControl(QStyle::ControlElement element, const QStyleOption *opt); + /*inline*/ void drawPrimitive(MyStyle::PrimitiveElement pe, const QStyleOption *opt); + /*inline*/ void drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption *opt); + /*inline*/ void drawControl(MyStyle::ControlElement element, const QStyleOption *opt); + /*inline*/ void drawControl(QStyle::ControlElement element, const QStyleOption *opt); private: QWidget* m_widget; diff --git a/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.cpp b/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.cpp index 38ae95b..158b369 100644 --- a/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.cpp +++ b/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.cpp @@ -4,6 +4,9 @@ #include #include +#include + +class MyStylePainter; MySwitchButton::MySwitchButton(QWidget *parent) : QAbstractButton(parent) @@ -20,7 +23,7 @@ MySwitchButton::~MySwitchButton() QSize MySwitchButton::sizeHint() const { - return QSize(100, 40); + return QSize(60, 40); } void MySwitchButton::paintEvent(QPaintEvent *event) @@ -30,11 +33,9 @@ void MySwitchButton::paintEvent(QPaintEvent *event) QStyleOptionButton opt; initStyleOption(&opt); -// MyStylePainter painter(this); -// MyStylePainter painter; -// painter.drawControl(MyStyle::CE_SwitchButton, &opt);//static_cast(opt)); - -// pa.drawControl(MyStyle::CE_SwitchButton, opt); + MyStylePainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.drawControl(MyStyle::CE_SwitchButton, &opt); } void MySwitchButton::initStyleOption(QStyleOptionButton *opt) const @@ -57,16 +58,20 @@ MySwitchButtonPrivate::MySwitchButtonPrivate() MySwitchButtonPrivate::~MySwitchButtonPrivate() { - } void MySwitchButtonPrivate::init() { Q_Q(MySwitchButton); - checked = false; - animationStart = 0; - animationEnd = 1; + check = false; q->setObjectName("MySwitchButton"); -// q->connect(q, &MySwitchButton::toggled, q, &MySwitchButton::checkedChanged); + q->setChecked(true); + q->setCheckable(true); //clicked toggled douxuyaokauqi + q->connect(q, SIGNAL(clicked(bool)), q, SLOT(setChecked(bool))); +} + +bool MySwitchButtonPrivate::switchCheck() +{ + return check; } diff --git a/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.h b/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.h index 6c4576a..785c60e 100644 --- a/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.h +++ b/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton.h @@ -1,3 +1,24 @@ +/* + * + * Gmail: touwoyimuli@gmai.com + * blogs: https://blog.csdn.net/qq_33154343 + * + * ------------------------------------------------- + * Copyright 2019~2020 touwoyimuli + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef MYSWITCHBUTTON_H #define MYSWITCHBUTTON_H @@ -23,7 +44,6 @@ protected: private: void initStyleOption(QStyleOptionButton *opt) const; -private: Q_DECLARE_PRIVATE(MySwitchButton) }; diff --git a/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton_p.h b/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton_p.h index bc96f24..86da73d 100644 --- a/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton_p.h +++ b/QtMyStyleEx/QtExample03/QtStyleEx/myswitchbutton_p.h @@ -1,3 +1,24 @@ +/* + * + * Gmail: touwoyimuli@gmai.com + * blogs: https://blog.csdn.net/qq_33154343 + * + * ------------------------------------------------- + * Copyright 2019~2020 touwoyimuli + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef MYSWITCHBUTTON_P_H #define MYSWITCHBUTTON_P_H @@ -16,11 +37,11 @@ public: ~MySwitchButtonPrivate(); void init(); + bool setSwitchCheck(bool check); + bool switchCheck(); -public: - bool checked; - double animationStart; - double animationEnd; +private: + bool check; public: Q_DECLARE_PUBLIC(MySwitchButton) //要加上宏 diff --git a/QtMyStyleEx/QtExample03/QtStyleEx/widget.cpp b/QtMyStyleEx/QtExample03/QtStyleEx/widget.cpp index 0bf5349..4ee72cc 100644 --- a/QtMyStyleEx/QtExample03/QtStyleEx/widget.cpp +++ b/QtMyStyleEx/QtExample03/QtStyleEx/widget.cpp @@ -21,6 +21,7 @@ #include "widget.h" #include "mystyle.h" +#include "myswitchbutton.h" #include #include @@ -75,6 +76,11 @@ void Widget::init() progreV->setValue(67); progreV->setOrientation(Qt::Vertical); + //自定义的控件 + MySwitchButton* switchBtn = new MySwitchButton(this); + switchBtn->resize(80, 40); + switchBtn->move(200 ,300); + int i = 0; QStringList listStyle = QStyleFactory::keys(); @@ -95,4 +101,5 @@ void Widget::init() qApp->setStyle(new MyStyle()); }); + qApp->setStyle(new MyStyle()); } diff --git a/README.md b/README.md index b9764c6..3d9f906 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,15 @@ ## 项目介绍: -  `Qt5` 各个控件使用的一个例子、以及一些底层原理或者技巧性的理解,即是自己所学记录,亦可以互相交流共享学习,**有朋自远方互联网而来,不亦悦乎?** +  ✅ `Qt` 的 `GUI` 基础控件用法,网络; + +  ✅ `dtk` 重绘控件方式的框架架构解析; + +  ✅ `QtCrator` 使用和一些小技巧; + +  ✅ `Qt` 原理/运行机制理解 + +  自己所学记录,亦可以互相交流共享学习,**有朋自远方互联网而来,不亦悦乎?**
@@ -48,7 +56,7 @@ **开发系统:** `MacOS 10.14.6 (18G103)` | `win10 x64 专业版 1803` | `UOS 20 x64 专业版 ` -**编码软件:** `Qt 5.9.8` | `Qt Creator 4.8.2 (Enterprise)` +**编码软件:** `Qt 5.9.8+` | `Qt Creator 4.8.2 (Enterprise)` **编码语言:**![](https://img.shields.io/badge/language-c++-orange.svg) @@ -59,24 +67,22 @@ ## 第一部分:预备知识 - **windows 系统:** - - [`windows10`环境下安装`Qt Creator5.9.8`作为`c++`的**IDE**开发工具,学习和使用**qt** (最佳推荐)](https://blog.csdn.net/qq_33154343/article/details/103674579) - - [Qt Creator 安装SDK,在MSVC编译模式下使用CDB调试器](https://blog.csdn.net/qq_33154343/article/details/98779698) - [`windows`环境下安装`Qt Creator` + `Visual Studio 2015`作为`c++`的`IDE`开发工具,学习和使用**qt** (备选)](https://blog.csdn.net/qq_33154343/article/details/103755569) - [`windows`环境下安装`Qt Creator 5.9` + `Visual Studio 2017专业版 ` 参考此文 (备选)](https://blog.csdn.net/qq_33154343/article/details/78587699) -- **MacOS 系统:** + +- **MacOS 系统:** - [`MacOS10.14.6`环境下安装`QtCreator5.9.8`作为`c++`的**IDE**开发工具,学习和使用**qt**(推荐)](https://blog.csdn.net/qq_33154343/article/details/103231202) -- **Linux 系统:** - **此处 Linux 以 uos20 为例(即: deepin )** - - [在win10里面的VMware安装UOS20,在uos20里面安装QtCreator,配置dtk开发环境](https://blog.csdn.net/qq_33154343/article/details/103733327) +- **Linux(uos20/deepin) 系统:** +- [在win10里面的VMware安装UOS20,在uos20里面安装QtCreator,配置dtk开发环境](https://blog.csdn.net/qq_33154343/article/details/103733327) - [MacOS10.14安装虚拟机Parallels_Desktop,安装UOS20和 QtCreaor,搭建dtk开发环境](https://blog.csdn.net/qq_33154343/article/details/104180794) - - [在macOS 10.14的虚拟机VMware Fusionlimian里面安装deepin15.11(Linux)](https://blog.csdn.net/qq_33154343/article/details/102789047) +- [在macOS 10.14的虚拟机VMware Fusionlimian里面安装deepin15.11(Linux)](https://blog.csdn.net/qq_33154343/article/details/102789047) @@ -88,10 +94,11 @@ ## 第二部分:qt生成原理/运行机制 - [`make` `makefile` `cmake` `qmake`都是什么,有什么区别?](https://blog.csdn.net/qq_33154343/article/details/98170236) +- [Qt 编程中 namespace Ui { class Widget; } 解析](https://blog.csdn.net/qq_33154343/article/details/98122981)
-## 第三部分:常用控件 +## 第三部分:常用 GUI 控件 - 一个默认的`Qt Widget`项目 【空】 - 元对象系统`moc`(**Meat-Object System**)的对象`MetaObject`和(含动态)属性`Propert`的用法【QtMeatObjectEx】 @@ -137,11 +144,28 @@
-## 扩展部分:自定义风格样式QStyle +## 第五部分:dtk 重绘控件原理解析(自定义样式 QStyle ) + +- **预备知识:** + - QStyle 与系统界面外观的关系 +- `QStyle`、`QCommonStyle`、`QPainter`等讲解 + - [QStyle设置界面的外观和QCommonStyle继承关系图讲解和使用](https://blog.csdn.net/qq_33154343/article/details/104367878) 【👩‍💻👩‍💻👩‍💻】 + - [qt之proxy()代理探究](https://blog.csdn.net/qq_33154343/article/details/101571843) + +- **QStyle 感性理解👀:** + - [应用软件在「ous20和 MaOS10.14下」显示应用不同的QStyle「即:所有控件的样式换肤」](https://blog.csdn.net/qq_33154343/article/details/104305154) 【QtMyStyleEx/QtExample01】 + - [应用软件在「windows10 和 deepin10.15下」显示应用不同的`QStyle`「即:所有控件的样式换肤」](https://blog.csdn.net/qq_33154343/article/details/100148552) 【QtMyStyleEx/QtExample01】 + + + +- **QStyle 重绘 GUI 控件,DTK 的源码解析架构🤔:** + - QStyle/DTK 重绘 GUI 已有的控件 QScrollBar + - 【QtMyStyleEx/QtExample02】 + - QStyle/DTK 重绘自定义控件 MySwitchButton + - 【QtMyStyleEx/QtExample03】 - 自定义`QStyle`界面所有控件的风格,换肤效果的教程,自定义继承`QCommonStyle`的风格类【QtCustomStyleEx】 -- 前期预备知识:`QStyle`、`QCommonStyle`等讲解 -- [更换`Qt`应用程序的界面`UI`,实现换肤,改用自带其他默认`QStyle`风格样式](https://mp.csdn.net/mdeditor/100148539#) +- [更换`Qt`应用程序的界面`UI`,实现换肤,改用自带其他默认`QStyle`风格样式](https://blog.csdn.net/qq_33154343/article/details/100148552) - [`QStyle`自定义重绘滑动条`QSlider`控件](https://blog.csdn.net/qq_33154343/article/details/100545769) - [`QStyle`自定义重绘`QRubberBand`控件](https://blog.csdn.net/qq_33154343/article/details/100588428) - [重绘的`QStyle`中`sizeFromContents`()没有被调用](https://blog.csdn.net/qq_33154343/article/details/100941134) @@ -151,7 +175,7 @@
-## 补充部分:补充较杂的知识点 +## 补充部分:较杂的知识点 ### 使用Qt Creator的小技巧: @@ -219,4 +243,5 @@ -**touwoyimuli:** 所含文章使用以下协议进行保护:[署名-非商业性使用-禁止演绎](http://creativecommons.org/licenses/by-nc-nd/3.0/cn/)。 \ No newline at end of file +**touwoyimuli:** 所含文章使用以下协议进行保护:[署名-非商业性使用-禁止演绎](http://creativecommons.org/licenses/by-nc-nd/3.0/cn/)。 +