Qt5利用自绘QPainter实现旋转按钮MySpinButton

相关资料:

原作者地址忘记写上了,想写时不记得了,多多原凉。

https://download.csdn.net/download/zhujianqiangqq/16650883       实例一CSDN下载

https://download.csdn.net/download/zhujianqiangqq/74304499       实例二CSDN下载

 

实例一:

.pro

 1 QT       += core gui
 2 
 3 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 4 
 5 CONFIG += c++11
 6 
 7 # The following define makes your compiler emit warnings if you use
 8 # any Qt feature that has been marked deprecated (the exact warnings
 9 # depend on your compiler). Please consult the documentation of the
10 # deprecated API in order to know how to port your code away from it.
11 DEFINES += QT_DEPRECATED_WARNINGS
12 
13 # You can also make your code fail to compile if it uses deprecated APIs.
14 # In order to do so, uncomment the following line.
15 # You can also select to disable deprecated APIs only up to a certain version of Qt.
16 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
17 
18 SOURCES += \
19     MySpinButton.cpp \
20     main.cpp \
21     mainwindow.cpp
22 
23 HEADERS += \
24     MySpinButton.h \
25     mainwindow.h
26 
27 FORMS += \
28     mainwindow.ui
29 
30 # Default rules for deployment.
31 qnx: target.path = /tmp/$${TARGET}/bin
32 else: unix:!android: target.path = /opt/$${TARGET}/bin
33 !isEmpty(target.path): INSTALLS += target
View Code

main.cpp

 1 #include "mainwindow.h"
 2 
 3 #include <QApplication>
 4 
 5 int main(int argc, char *argv[])
 6 {
 7     QApplication a(argc, argv);
 8     MainWindow w;
 9     w.show();
10     return a.exec();
11 }
View Code

mainwindow.h

 1 #ifndef MAINWINDOW_H
 2 #define MAINWINDOW_H
 3 
 4 #include <QMainWindow>
 5 #include "MySpinButton.h"
 6 
 7 QT_BEGIN_NAMESPACE
 8 namespace Ui { class MainWindow; }
 9 QT_END_NAMESPACE
10 
11 class MainWindow : public QMainWindow
12 {
13     Q_OBJECT
14 
15 public:
16     MainWindow(QWidget *parent = nullptr);
17     ~MainWindow();
18 
19 private:
20     Ui::MainWindow *ui;
21 };
22 #endif // MAINWINDOW_H
View Code

mainwindow.cpp

 1 #include "mainwindow.h"
 2 #include "ui_mainwindow.h"
 3 
 4 MainWindow::MainWindow(QWidget *parent)
 5     : QMainWindow(parent)
 6     , ui(new Ui::MainWindow)
 7 {
 8     ui->setupUi(this);
 9 
10     MySpinButton *Spin_button = new MySpinButton(this);
11     Spin_button->resize (200, 200);
12     Spin_button->move (10, 10);
13     Spin_button->show();
14 }
15 
16 MainWindow::~MainWindow()
17 {
18     delete ui;
19 }
View Code

mainwindow.ui

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <ui version="4.0">
 3  <class>MainWindow</class>
 4  <widget class="QMainWindow" name="MainWindow">
 5   <property name="geometry">
 6    <rect>
 7     <x>0</x>
 8     <y>0</y>
 9     <width>184</width>
10     <height>188</height>
11    </rect>
12   </property>
13   <property name="windowTitle">
14    <string>MainWindow</string>
15   </property>
16   <widget class="QWidget" name="centralwidget"/>
17   <widget class="QMenuBar" name="menubar">
18    <property name="geometry">
19     <rect>
20      <x>0</x>
21      <y>0</y>
22      <width>184</width>
23      <height>23</height>
24     </rect>
25    </property>
26   </widget>
27   <widget class="QStatusBar" name="statusbar"/>
28  </widget>
29  <resources/>
30  <connections/>
31 </ui>
View Code

MySpinButton.h

 1 #ifndef MYSPINBUTTON_H
 2 #define MYSPINBUTTON_H
 3 
 4 #include <QWidget>
 5 
 6 #define whirlbuttonHeigth   130
 7 #define whirlbuttonWidth    120
 8 
 9 class MySpinButton : public QWidget
10 {
11     Q_OBJECT
12 public:
13     void  paintEvent(QPaintEvent *event);
14     explicit MySpinButton(QWidget *parent = nullptr);
15     ~MySpinButton();
16     void setDegree(int deg);
17     int getDegree();
18 
19 signals:
20     void updateDegree();
21 protected:
22     void mousePressEvent(QMouseEvent *event);
23     void mouseMoveEvent(QMouseEvent *event);
24     void mouseReleaseEvent(QMouseEvent *event);
25     void mouseToPosion(QMouseEvent *event);
26     QSize sizeHint() const;
27     QSize minimumSizeHint() const;
28 private:
29     int degree;
30 };
31 
32 
33 #endif // MYSPINBUTTON_H
View Code

MySpinButton.cpp

  1 #include "MySpinButton.h"
  2 
  3 
  4 #include <QPainter>
  5 #include <QMouseEvent>
  6 #include <math.h>
  7 
  8 MySpinButton::MySpinButton(QWidget *parent) : QWidget(parent)
  9 {
 10     setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
 11     degree = 90;
 12 }
 13 
 14 MySpinButton::~MySpinButton()
 15 {
 16 }
 17 
 18 void MySpinButton::setDegree(int deg)
 19 {
 20     this->degree = deg;
 21     this->update();
 22 }
 23 void MySpinButton::paintEvent(QPaintEvent *event)
 24 {
 25     QPainter painter(this);
 26     //反走样
 27     painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
 28     QTransform tranform1;
 29     int originY = whirlbuttonHeigth/2;
 30     int originX = whirlbuttonWidth/2;
 31 
 32 
 33     const int triangle[3][2] =
 34     {
 35         { originX-2, 0 },
 36         { originX+2, 0 },
 37         { originX, 7 }
 38     };
 39 
 40     painter.setPen(QPen(Qt::red));
 41     painter.setBrush(QBrush(Qt::red));
 42     //绘制多边形,三角形。
 43     painter.drawPolygon(QPolygon(3, &triangle[0][0]));
 44 
 45 
 46     tranform1.translate(originX,originY);
 47     tranform1.rotate(degree);
 48     tranform1.translate(-(originX),-(originY));
 49     painter.setWorldTransform(tranform1);
 50 
 51     QPen thickPen(palette().foreground(), 1.5);
 52     QPen midPen(palette().foreground(), 1.0);
 53     QPen thinPen(palette().foreground(), 0.5);
 54     QColor niceBlue(150, 150, 200);
 55     painter.setPen(thinPen);
 56 
 57 
 58     //随着程度逐渐改变
 59     QConicalGradient coneGradient(originX, originY, -90.0);
 60     coneGradient.setColorAt(0.0, Qt::darkGray);
 61     coneGradient.setColorAt(0.2, niceBlue);
 62     coneGradient.setColorAt(1.0, Qt::white);
 63     coneGradient.setColorAt(1.0, Qt::darkGray);
 64 
 65     unsigned r = 56;
 66     painter.setBrush(coneGradient);
 67     painter.drawEllipse((originX-r), (originY-r), r*2, r*2);
 68 
 69     r = 24;
 70     QRadialGradient haloGradient(originX, originY, r, originX, originY);
 71     haloGradient.setColorAt(0.0, Qt::lightGray);
 72     haloGradient.setColorAt(0.8, Qt::darkGray);
 73     haloGradient.setColorAt(0.9, Qt::white);
 74     haloGradient.setColorAt(1.0, Qt::black);
 75 
 76     painter.setPen(Qt::NoPen);
 77     painter.setBrush(haloGradient);
 78 
 79     painter.drawEllipse(originX-r, originY-r, r*2, 2*r);
 80 
 81     unsigned rx = 30,ry = 8;
 82     QLinearGradient knobGradient(originX-rx, originY-ry,originX-rx, originY+ry);
 83     knobGradient.setColorAt(0.0, Qt::black);
 84     knobGradient.setColorAt(0.2, niceBlue);
 85     knobGradient.setColorAt(0.3, Qt::lightGray);
 86     knobGradient.setColorAt(0.8, Qt::white);
 87     knobGradient.setColorAt(1.0, Qt::black);
 88 
 89     painter.setBrush(knobGradient);
 90     painter.setPen(thinPen);
 91     painter.drawRoundRect(originX-rx,originY-ry, rx*2, ry*2, 49, 99);
 92 
 93 
 94     for (int i = 0; i < 36; ++i)
 95     {
 96         if (i%6)
 97         {
 98             painter.setPen(midPen);
 99             painter.drawLine(5,originY, 10,originY);
100         }
101         else
102         {
103             painter.setPen(thickPen);
104             painter.drawLine(5,originY, 13,originY);
105 
106             tranform1.translate(25,originY);
107             tranform1.rotate(-90);
108             tranform1.translate(-25,-originY);
109             painter.setWorldTransform(tranform1);
110 
111             painter.drawText(22, originY,QString::number(i/6));
112             tranform1.translate(25,originY);
113             tranform1.rotate(90);
114             tranform1.translate(-25,-originY);
115             painter.setWorldTransform(tranform1);
116 
117         }
118 
119         tranform1.translate(originX,originY);
120         tranform1.rotate(-10);
121         tranform1.translate(-originX,-originY);
122         painter.setWorldTransform(tranform1);
123     }
124 }
125 QSize MySpinButton::sizeHint() const
126 {
127     QSize size = QSize(whirlbuttonHeigth,whirlbuttonWidth);
128     return size;
129 }
130 QSize MySpinButton::minimumSizeHint() const
131 {
132     QSize size = QSize(whirlbuttonHeigth,whirlbuttonWidth);
133     return size;
134 }
135 void MySpinButton::mousePressEvent(QMouseEvent *event)
136 {
137     mouseToPosion(event);
138     this->update();
139 }
140 int MySpinButton :: getDegree()
141 {
142     return(degree);
143 }
144 void MySpinButton::mouseMoveEvent(QMouseEvent * event)
145 {
146     mouseToPosion(event);
147     this->update();
148 }
149 void MySpinButton::mouseReleaseEvent(QMouseEvent * event)
150 {
151     mouseToPosion(event);
152     this->updateDegree();
153 }
154 void MySpinButton:: mouseToPosion(QMouseEvent * event)
155 {
156     QPoint currentPoint = event->pos();
157     double pi = 3.1415927;
158     double  x = currentPoint.x() - whirlbuttonHeigth/2;
159     double  y = currentPoint.y() - whirlbuttonWidth/2;
160     if((x ==0)&&(y<=0))
161         degree = 90;
162     else if((x==0)&&(y>0))
163         degree = 270;
164     else if(x>0)
165         degree = atan(y/x)*180/pi + 180;
166     else if(y>0)
167         degree = atan(y/x)*180/pi + 360;
168     else
169         degree = atan(y/x)*180/pi;
170 }
View Code

 

实例二:

.pro

 1 QT       += core gui
 2 
 3 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 4 
 5 CONFIG += c++11
 6 
 7 # The following define makes your compiler emit warnings if you use
 8 # any Qt feature that has been marked deprecated (the exact warnings
 9 # depend on your compiler). Please consult the documentation of the
10 # deprecated API in order to know how to port your code away from it.
11 DEFINES += QT_DEPRECATED_WARNINGS
12 
13 # You can also make your code fail to compile if it uses deprecated APIs.
14 # In order to do so, uncomment the following line.
15 # You can also select to disable deprecated APIs only up to a certain version of Qt.
16 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
17 
18 SOURCES += \
19     MySpinButton.cpp \
20     main.cpp \
21     mainwindow.cpp
22 
23 HEADERS += \
24     MySpinButton.h \
25     mainwindow.h
26 
27 FORMS += \
28     mainwindow.ui
29 
30 # Default rules for deployment.
31 qnx: target.path = /tmp/$${TARGET}/bin
32 else: unix:!android: target.path = /opt/$${TARGET}/bin
33 !isEmpty(target.path): INSTALLS += target
View Code

main.cpp

 1 #include "mainwindow.h"
 2 
 3 #include <QApplication>
 4 
 5 int main(int argc, char *argv[])
 6 {
 7     QApplication a(argc, argv);
 8     MainWindow w;
 9     w.show();
10     return a.exec();
11 }
View Code

mainwindow.h

 1 #ifndef MAINWINDOW_H
 2 #define MAINWINDOW_H
 3 
 4 #include <QMainWindow>
 5 #include "MySpinButton.h"
 6 #include <QTimer>
 7 
 8 QT_BEGIN_NAMESPACE
 9 namespace Ui { class MainWindow; }
10 QT_END_NAMESPACE
11 
12 class MainWindow : public QMainWindow
13 {
14     Q_OBJECT
15 
16 public:
17     MainWindow(QWidget *parent = nullptr);
18     ~MainWindow();
19 private slots:
20     void on_pushButton_clicked();
21     void on_horizontalSlider_valueChanged(int value);
22     void on_horizontalSlider_2_valueChanged(int value);
23     void on_horizontalSlider_3_valueChanged(int value);
24 private:
25     Ui::MainWindow *ui;
26     MySpinButton *Spin_button;
27     QTimer *m_pQTimer;
28 };
29 #endif // MAINWINDOW_H
View Code

mainwindow.cpp

 1 #include "mainwindow.h"
 2 #include "ui_mainwindow.h"
 3 
 4 MainWindow::MainWindow(QWidget *parent)
 5     : QMainWindow(parent)
 6     , ui(new Ui::MainWindow)
 7 {
 8     ui->setupUi(this);
 9 
10     int n = 200;
11 
12     Spin_button = new MySpinButton(n, n, this);
13     Spin_button->move (0, 0);
14     Spin_button->show();
15 
16     m_pQTimer = new QTimer(this);
17     m_pQTimer->setSingleShot(false);
18     m_pQTimer->start(100);
19     connect(m_pQTimer, &QTimer::timeout, this, &MainWindow::on_pushButton_clicked);
20 }
21 
22 MainWindow::~MainWindow()
23 {
24     delete ui;
25 }
26 
27 
28 void MainWindow::on_pushButton_clicked()
29 {
30     setWindowTitle(QString::number(Spin_button->getDegree()));
31 }
32 
33 void MainWindow::on_horizontalSlider_valueChanged(int value)
34 {
35     Spin_button->setPaintCount(ui->horizontalSlider->value());
36 }
37 
38 void MainWindow::on_horizontalSlider_2_valueChanged(int value)
39 {
40     Spin_button->setPaintRotate(ui->horizontalSlider_2->value());
41 }
42 
43 void MainWindow::on_horizontalSlider_3_valueChanged(int value)
44 {
45     Spin_button->setPaintOffset(ui->horizontalSlider_3->value());
46 }
View Code

MySpinButton.h

 1 #ifndef MYSPINBUTTON_H
 2 #define MYSPINBUTTON_H
 3 
 4 #include <QWidget>
 5 #include <QDebug>
 6 
 7 //#define whirlbuttonHeigth   130
 8 //#define whirlbuttonWidth    120
 9 
10 //#define whirlbuttonHeigth   120
11 //#define whirlbuttonWidth    120
12 
13 class MySpinButton : public QWidget
14 {
15     Q_OBJECT
16 public:
17     void  paintEvent(QPaintEvent *event);
18     explicit MySpinButton(int width, int height, QWidget *parent = nullptr);
19     ~MySpinButton();
20     void setDegree(int deg);
21     int getDegree();
22     void setPaintCount(int paintCount);
23     void setPaintRotate(int paintRotate);
24     void setPaintOffset(int paintOffset);
25 signals:
26     void updateDegree();
27 protected:
28     void mousePressEvent(QMouseEvent *event);
29     void mouseMoveEvent(QMouseEvent *event);
30     void mouseReleaseEvent(QMouseEvent *event);
31     void mouseToPosion(QMouseEvent *event);
32     QSize sizeHint() const;
33     QSize minimumSizeHint() const;
34 private:
35     int m_nWidth = 200;
36     int m_nHeight = 200;
37     int degree = 0;
38     int m_nPaintCount = 360;
39     int m_nPaintRotate = 1;
40     int m_nPaintOffset = 90;
41 };
42 
43 
44 #endif // MYSPINBUTTON_H
View Code

MySpinButton.cpp

  1 #include "MySpinButton.h"
  2 
  3 
  4 #include <QPainter>
  5 #include <QMouseEvent>
  6 #include <math.h>
  7 
  8 MySpinButton::MySpinButton(int width, int height, QWidget *parent) : QWidget(parent)
  9 {
 10     setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
 11     degree = 0;
 12     m_nWidth = width;
 13     m_nHeight = height;
 14     this->resize (m_nWidth, m_nHeight);
 15 }
 16 
 17 MySpinButton::~MySpinButton()
 18 {
 19 }
 20 
 21 void MySpinButton::setDegree(int deg)
 22 {
 23     this->degree = deg;
 24     this->update();
 25 }
 26 void MySpinButton::paintEvent(QPaintEvent *event)
 27 {
 28     QPainter painter(this);
 29     //反走样
 30     painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
 31     // 背景
 32     QBrush objBrush(Qt::black, Qt::SolidPattern);
 33     painter.fillRect(0, 0, m_nWidth, m_nHeight, objBrush);
 34     // 设置画笔
 35     QPen oLinePen;
 36     oLinePen.setColor(QColor("#00f301"));
 37     oLinePen.setWidth(1);
 38     oLinePen.setStyle(Qt::SolidLine);
 39     painter.setPen(oLinePen);
 40     // 计算中心点
 41     QTransform tranform1;
 42     int originY = m_nHeight/2;
 43     int originX = m_nWidth/2;
 44     // 打印角度
 45     painter.drawText(QPoint(originX - 5, originY), QString::number(degree));
 46     // 进行错位,不错位的0度在再左边
 47     tranform1.translate(originX,originY);
 48     tranform1.rotate(90);
 49     tranform1.translate(-(originX),-(originY));
 50     painter.setWorldTransform(tranform1);
 51     // 画出刻度
 52     for (int i = 0; i < m_nPaintCount; ++i)
 53     {
 54         if (i%m_nPaintOffset)
 55         {
 56             if (i%10)
 57             {
 58             }
 59             else
 60             {
 61                 painter.drawLine(5,originY, 10,originY);
 62             }
 63         }
 64         else
 65         {
 66             tranform1.translate(25,originY);
 67             tranform1.rotate(-90);
 68             tranform1.translate(-25,-originY);
 69             painter.setWorldTransform(tranform1);
 70 
 71             painter.drawText(22, originY -15,QString::number(i));//22
 72             tranform1.translate(25,originY);//25
 73             tranform1.rotate(90);
 74             tranform1.translate(-25,-originY);
 75             painter.setWorldTransform(tranform1);
 76         }
 77         tranform1.translate(originX,originY);
 78         tranform1.rotate(m_nPaintRotate);
 79         tranform1.translate(-originX,-originY);
 80         painter.setWorldTransform(tranform1);
 81     }
 82     tranform1.translate(originX,originY);
 83     tranform1.rotate(degree);
 84     tranform1.translate(-(originX),-(originY));
 85     painter.setWorldTransform(tranform1);
 86     // 绘制多边形,三角形。画红三角
 87     const int triangle[3][2] =
 88     {
 89         { 15, originX-5 },
 90         { 15, originX+5 },
 91         { 5, originX }
 92     };
 93     painter.setPen(QPen(Qt::red));
 94     painter.setBrush(QBrush(Qt::red));
 95     painter.drawPolygon(QPolygon(3, &triangle[0][0]));
 96 }
 97 
 98 QSize MySpinButton::sizeHint() const
 99 {
100     QSize size = QSize(m_nHeight,m_nWidth);
101     return size;
102 }
103 
104 QSize MySpinButton::minimumSizeHint() const
105 {
106     QSize size = QSize(m_nHeight,m_nWidth);
107     return size;
108 }
109 
110 void MySpinButton::mousePressEvent(QMouseEvent *event)
111 {
112     mouseToPosion(event);
113     this->update();
114 }
115 
116 int MySpinButton :: getDegree()
117 {
118     return(degree);
119 }
120 
121 void MySpinButton::setPaintCount(int paintCount)
122 {
123     m_nPaintCount = paintCount;
124     this->update();
125 }
126 
127 void MySpinButton::setPaintRotate(int paintRotate)
128 {
129     m_nPaintRotate = paintRotate;
130     this->update();
131 }
132 
133 void MySpinButton::setPaintOffset(int paintOffset)
134 {
135     m_nPaintOffset = paintOffset;
136     this->update();
137 }
138 
139 void MySpinButton::mouseMoveEvent(QMouseEvent * event)
140 {
141     mouseToPosion(event);
142     this->update();
143 }
144 
145 void MySpinButton::mouseReleaseEvent(QMouseEvent * event)
146 {
147     mouseToPosion(event);
148     this->updateDegree();
149 }
150 
151 void MySpinButton:: mouseToPosion(QMouseEvent * event)
152 {
153     QPoint currentPoint = event->pos();
154 
155     double pi = 3.1415927;
156     double  x = currentPoint.x() - m_nHeight/2;
157     double  y = currentPoint.y() - m_nWidth/2;
158 
159     if((x ==0)&&(y<=0))
160         degree = 0;
161     else if((x==0)&&(y>0))
162         degree = 180;
163     else
164         if(x>0)
165         degree = atan(y/x)*180/pi + 90;
166     else if(y>0)
167         degree = atan(y/x)*180/pi + 270;
168     else
169         degree = atan(y/x)*180/pi+270;
170 }
View Code

 

posted on 2021-04-13 17:30  疯狂delphi  阅读(459)  评论(0)    收藏  举报

导航