Qt自定义/绘制控件

作者 :默默地EEer

原文地址:http://www.cnblogs.com/hebaichuanyeah/p/6083445.html

Qt中需要自定义/绘制控件时,基本上继承自QWidget,重新实现绘制函数,定义大小,增加相应的信号和槽……

例子:自定义旋钮控件,通过鼠标控制旋转(可通过Qt的世界变换旋转图形),并在旋转停止时触发一次信号获得当前角度。

实现效果:

实现:

自定义控件类,

#ifndef WHIRLBUTTON_H
#define WHIRLBTUUON_H

#include <QColor>
#include <QImage>
#include <QWidget>

#define whirlbuttonHeigth   130
#define whirlbuttonWidth    120

class whirlbutton : public QWidget
{
    Q_OBJECT
public:
    void  paintEvent(QPaintEvent *event);
    whirlbutton();
    ~whirlbutton();
    void setDegree(int deg);
    int getDegree();

signals:
    void updateDegree();
protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void mouseToPosion(QMouseEvent *event);
    QSize sizeHint() const;
    QSize minimumSizeHint() const;
private:
    int degree;

};

#endif

 

 以及该类的实现。

#include "whirlbutton.h"
#include <QPainter>
#include <QMouseEvent>
#include <math.h>

whirlbutton::whirlbutton()
{
 //   setMouseTracking(true);
    setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
    degree = 90;
}

whirlbutton::~ whirlbutton()
{
}

void whirlbutton::setDegree(int deg)
{
    this->degree = deg;
    this->update();
}
void whirlbutton::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QTransform tranform1;
    int originY = whirlbuttonHeigth/2;
    int originX = whirlbuttonWidth/2;


    const int triangle[3][2] =
    {
        { originX-2, 0 },
        { originX+2, 0 },
        { originX, 7 }
    };

    painter.setPen(QPen(Qt::red));
    //painter.setBrush(palette().foreground());
    painter.setBrush(QBrush(Qt::red));
    //draw polygon,triangle.
    painter.drawPolygon(QPolygon(3, &triangle[0][0]));


    //   painter.setWindow(0,0,150,150);
    tranform1.translate(originX,originY);
    tranform1.rotate(degree);
    tranform1.translate(-(originX),-(originY));
    painter.setWorldTransform(tranform1);
    
    QPen thickPen(palette().foreground(), 1.5);
    QPen midPen(palette().foreground(), 1.0);
    QPen thinPen(palette().foreground(), 0.5);
    QColor niceBlue(150, 150, 200);
    painter.setPen(thinPen);


    //gradually change with degree
    QConicalGradient coneGradient(originX, originY, -90.0);
    coneGradient.setColorAt(0.0, Qt::darkGray);
    coneGradient.setColorAt(0.2, niceBlue);
    coneGradient.setColorAt(1.0, Qt::white);
    coneGradient.setColorAt(1.0, Qt::darkGray);

    unsigned r = 56;
    painter.setBrush(coneGradient);
    painter.drawEllipse((originX-r), (originY-r), r*2, r*2);

    r = 24;
    QRadialGradient haloGradient(originX, originY, r, originX, originY);
    haloGradient.setColorAt(0.0, Qt::lightGray);
    haloGradient.setColorAt(0.8, Qt::darkGray);
    haloGradient.setColorAt(0.9, Qt::white);
    haloGradient.setColorAt(1.0, Qt::black);

    painter.setPen(Qt::NoPen);
    painter.setBrush(haloGradient);

    painter.drawEllipse(originX-r, originY-r, r*2, 2*r);

    unsigned rx = 30,ry = 8;
    QLinearGradient knobGradient(originX-rx, originY-ry,originX-rx, originY+ry);
    knobGradient.setColorAt(0.0, Qt::black);
    knobGradient.setColorAt(0.2, niceBlue);
    knobGradient.setColorAt(0.3, Qt::lightGray);
    knobGradient.setColorAt(0.8, Qt::white);
    knobGradient.setColorAt(1.0, Qt::black);

    painter.setBrush(knobGradient);
    painter.setPen(thinPen);
    painter.drawRoundRect(originX-rx,originY-ry, rx*2, ry*2, 49, 99);


    for (int i = 0; i < 36; ++i)
    {
        if (i%6)
        {
            painter.setPen(midPen);
            painter.drawLine(5,originY, 10,originY);
        }
        else
        {
            painter.setPen(thickPen);
            painter.drawLine(5,originY, 13,originY);

            tranform1.translate(25,originY);
            tranform1.rotate(-90);
            tranform1.translate(-25,-originY);
            painter.setWorldTransform(tranform1);

            painter.drawText(22, originY,QString::number(i/6));
            tranform1.translate(25,originY);
            tranform1.rotate(90);
            tranform1.translate(-25,-originY);
            painter.setWorldTransform(tranform1);

        }

        tranform1.translate(originX,originY);
        tranform1.rotate(-10);
        tranform1.translate(-originX,-originY);
        painter.setWorldTransform(tranform1);
    }
}
QSize whirlbutton::sizeHint() const
{
    QSize size = QSize(whirlbuttonHeigth,whirlbuttonWidth);
    return size;
}
QSize whirlbutton::minimumSizeHint() const
{
    QSize size = QSize(whirlbuttonHeigth,whirlbuttonWidth);
    return size;
}
void whirlbutton::mousePressEvent(QMouseEvent *event)
{
    mouseToPosion(event);
    this->update();   
}
int whirlbutton :: getDegree()
{
    return(degree);
}
void whirlbutton::mouseMoveEvent(QMouseEvent * event)
{
    mouseToPosion(event);
    this->update();
}
void whirlbutton::mouseReleaseEvent(QMouseEvent * event)
{
    mouseToPosion(event);
    this->updateDegree();
}
void whirlbutton:: mouseToPosion(QMouseEvent * event)
{
    QPoint currentPoint = event->pos();
    double pi = 3.1415927;
    double  x = currentPoint.x() - whirlbuttonHeigth/2;
    double  y = currentPoint.y() - whirlbuttonWidth/2;
    if((x ==0)&&(y<=0))
        degree = 90;
    else if((x==0)&&(y<0))
        degree = 270;
    else if(x>0)
        degree = atan(y/x)*180/pi + 180;
    else if(y>0)
        degree = atan(y/x)*180/pi + 360;
    else
        degree = atan(y/x)*180/pi;
}

 

posted @ 2016-11-20 20:43  默默地EEer  阅读(8545)  评论(0编辑  收藏  举报