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


    .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
    作者:疯狂Delphi
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

    欢迎关注我,一起进步!扫描下方二维码即可加我

  • 相关阅读:
    Python 面向对象高级编程
    Python 继承和多态
    Python 访问限制
    学习笔记项目3-Django-管理网站
    学习笔记项目2-Django-创建数据库及应用
    学习笔记项目1-Django-创建虚拟环境和项目
    写一个 100 以内的奇数列表
    给一个字符串,转换成数字整数,若包含非法字符,返回提示,正确则反回整数值,不能使用内置函数转换
    Linux系统实现一个everything程序
    自动化测试常用脚本-等待某个元素是否显示
  • 原文地址:https://www.cnblogs.com/FKdelphi/p/14654345.html
Copyright © 2020-2023  润新知