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
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 }
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
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 }
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>
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
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 }
实例二:
.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
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 }
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
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 }
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
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 }
作者:疯狂Delphi
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
欢迎关注我,一起进步!扫描下方二维码即可加我

