Qt绘制圆环

DrawCircle.h头文件

#ifndef DRAWCIRCLE_H
#define DRAWCIRCLE_H

#include <QWidget>
#include <QPainter>
#include <QtMath>
#include <QTimer>
#include <QDateTime>
#include <QDebug>

namespace Ui {
    class DrawCircle;
}

class DrawCircle : public QWidget
{
    Q_OBJECT

public:
    explicit DrawCircle(QWidget *parent = 0);
    ~DrawCircle();

protected:
//    void paintEvent(QPaintEvent *event)override;
    void showEvent(QShowEvent *event);
    void hideEvent(QHideEvent *event);

    bool eventFilter(QObject *watched, QEvent *event)override; //事件过滤器

private slots:
    void slot_ProhibitUpdates(); //禁止界面刷新

    void on_doubleSpinBox_smallR_BJ1_valueChanged(double arg1);
    void on_doubleSpinBox_middleR_BJ1_valueChanged(double arg1);
    void on_doubleSpinBox_bigR_BJ1_valueChanged(double arg1);

private:
    Ui::DrawCircle *ui;

    QPointF centerPoint; //圆心
    QPointF P1; //半径(小)点
    QPointF P2; //半径(中)点
    QPointF P3; //半径(大)点

    QRectF  rect1; //描述1
    QRectF  rect2; //描述2
    QRectF  rect3; //描述3

    double R1; //半径(小)
    double R2; //半径(中)
    double R3; //半径(大)

    double Radian2; //弧度2
    double Radian3; //弧度3

    double dCoefficient; //系数

    void PaintCircle(); //绘制返航示意圆圈
};

#endif // DRAWCIRCLE_H

DrawCircle.cpp

#include "DrawCircle.h"
#include "ui_DrawCircle.h"

DrawCircle::DrawCircle(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::DrawCircle)
{
    ui->setupUi(this);

    this->setWindowTitle("绘制圆环");

    centerPoint = QPoint(86, 86); //圆心
    dCoefficient = 1.0;
    R1 = ui->doubleSpinBox_smallR_BJ1->value();  //半径(小)
    R2 = ui->doubleSpinBox_middleR_BJ1->value(); //半径(中)
    R3 = ui->doubleSpinBox_bigR_BJ1->value();    //半径(大)

    Radian2 = 0.0; //弧度2
    Radian3 = 0.0; //弧度3

    /*/----------------------------------------------------------------------------------
    注:在控件上绘图一般只有两种方法:
    方法1:使用事件过滤机制
    事件过滤器:由两个函数组成的一种操作,用来完成一个部件对其他部件的事件监视,这两个函数分别是:
    installEventFilter();
    eventFilter(QObject *obj, QEvent *ev),皆为QObject类中的函数。

    方法2:自己定义一个类,让它继承与自己想要实现绘图的控件类
    比如:自己定义一个MyWidget类继承于QWidget,然后在这个类中重写paintEvent(QPaintEvent *)函数,并在里面绘图。然后在ui界面中把对应的QWidget提升为MyWidget。
    //---------------------------------------------------------------------------------*/
    ui->BJ1ReturnConfig->installEventFilter(this); //使用事件过滤机制在控件上绘制图形

    QTimer::singleShot(500, this, SLOT(slot_ProhibitUpdates()));
}

DrawCircle::~DrawCircle()
{
    delete ui;
}

//void DrawCircle::paintEvent(QPaintEvent *event)
//{
//    //不作任何处理!
//}

void DrawCircle::showEvent(QShowEvent *event)
{
    qDebug()<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz") + " 调用界面显示!"<<this->isVisible()<<this->isActiveWindow();

    if(this->isActiveWindow()) { //活跃窗口
        setUpdatesEnabled(true);
        QTimer::singleShot(200, this, SLOT(slot_ProhibitUpdates()));
    }
    else { //不活跃窗口
        //不作处理!
    }
}

void DrawCircle::hideEvent(QHideEvent *event)
{
    qDebug()<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz") + " 调用界面隐藏!"<<this->isVisible()<<this->isActiveWindow();

    if(this->isActiveWindow()) { //活跃窗口
        //不作处理!
    }
    else { //不活跃窗口
        setUpdatesEnabled(false);
    }
}

void DrawCircle::slot_ProhibitUpdates() //禁止界面刷新
{
    setUpdatesEnabled(false);
}

void DrawCircle::PaintCircle() //绘制返航示意圆圈
{
    if (R1 <= 0 && R2 <= 0 && R3 <= 0)
        return;

    if (R3 > 85) { //实际返航配置中,R3值最大!
        dCoefficient = 85/R3;
        R1 *= dCoefficient;
        R2 *= dCoefficient;
        R3 *= dCoefficient;
    }
    else {
        dCoefficient = 1.0;
    }

    qDebug()<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz") + " 调用绘制图形!"<<R1<<R2<<R3<<"系数:"<<dCoefficient;

    QPainter painter(ui->BJ1ReturnConfig); //创建画笔对象
    painter.setRenderHint(QPainter::Antialiasing); //抗锯齿

    painter.setPen(QPen(Qt::transparent,3,Qt::SolidLine));
    painter.setPen(Qt::red);
    painter.setFont(QFont("Arial", 10));

    painter.setPen(Qt::black);
    painter.drawPoint(centerPoint); //圆心

    Radian2 = -35*3.1415926/180; //弧度2
    Radian3 = -70*3.1415926/180; //弧度3
    qDebug()<<"弧度:"<<Radian2<<Radian3;

    P1 = QPointF(centerPoint.x() + R1, centerPoint.y()); //半径(小)点
    P2 = QPointF(centerPoint.x() + (R2 * cos(Radian2)), centerPoint.y() + (R2 * sin(Radian2))); //半径(中)点
    P3 = QPointF(centerPoint.x() + (R3 * cos(Radian3)), centerPoint.y() + (R3 * sin(Radian3))); //半径(大)点

    qDebug()<<"P1:"<<P1.x()<<P1.y()<<", P2:"<<Radian2<<P2.x()<<P2.y()<<", P3:"<<Radian3<<P3.x()<<P3.y();

    rect1 = QRectF(centerPoint.x() + R1/3,             centerPoint.y() - 10, 15, 10); //描述1
    rect2 = QRectF(centerPoint.x() + (R2 * cos(Radian2))/2, centerPoint.y() + ((R2+10) * sin(Radian2)), 15, 10); //描述2
    rect3 = QRectF(centerPoint.x() + (R3 * cos(Radian3))/3, centerPoint.y() + ((R3-2) * sin(Radian3)), 15, 10); //描述3

    painter.setPen(Qt::red);
    if (R1 > 0) {
        painter.drawEllipse(centerPoint,R1,R1); //(圆心,横轴半径,纵轴半径)
        painter.drawLine(centerPoint, P1);
        painter.drawText(rect1, Qt::AlignCenter, "R1");
    }

    painter.setPen(Qt::green);
    if (R2 > 0) {
        painter.drawEllipse(centerPoint,R2,R2); //(圆心,横轴半径,纵轴半径)
        painter.drawLine(centerPoint, P2);
        painter.drawText(rect2, Qt::AlignCenter, "R2");
    }

    painter.setPen(Qt::blue);
    if (R3 > 0) {
        painter.drawEllipse(centerPoint,R3,R3); //(圆心,横轴半径,纵轴半径)
        painter.drawLine(centerPoint, P3);
        painter.drawText(rect3, Qt::AlignCenter, "R3");
    }
}

bool DrawCircle::eventFilter(QObject *watched, QEvent *event) //用过滤器eventFilter()拦截QWidget中的QEvent::Paint事件
{
    if(watched == ui->BJ1ReturnConfig && event->type() == QEvent::Paint) {
        PaintCircle(); //调用 绘制返航示意圆圈
    }

    return QWidget::eventFilter(watched,event);
}

void DrawCircle::on_doubleSpinBox_smallR_BJ1_valueChanged(double arg1)
{
    R1 = ui->doubleSpinBox_smallR_BJ1->value();  //半径(小)
    R2 = ui->doubleSpinBox_middleR_BJ1->value(); //半径(中)
    R3 = ui->doubleSpinBox_bigR_BJ1->value();    //半径(大)

    setUpdatesEnabled(true);
    repaint();
    setUpdatesEnabled(false);
}

void DrawCircle::on_doubleSpinBox_middleR_BJ1_valueChanged(double arg1)
{
    R1 = ui->doubleSpinBox_smallR_BJ1->value();  //半径(小)
    R2 = ui->doubleSpinBox_middleR_BJ1->value(); //半径(中)
    R3 = ui->doubleSpinBox_bigR_BJ1->value();    //半径(大)

    setUpdatesEnabled(true);
    repaint();
    setUpdatesEnabled(false);
}

void DrawCircle::on_doubleSpinBox_bigR_BJ1_valueChanged(double arg1)
{
    R1 = ui->doubleSpinBox_smallR_BJ1->value();  //半径(小)
    R2 = ui->doubleSpinBox_middleR_BJ1->value(); //半径(中)
    R3 = ui->doubleSpinBox_bigR_BJ1->value();    //半径(大)

    setUpdatesEnabled(true);
    repaint();
    setUpdatesEnabled(false);
}

DrawCircle.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>DrawCircle</class>
 <widget class="QWidget" name="DrawCircle">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>644</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>DrawCircle</string>
  </property>
  <widget class="QDoubleSpinBox" name="doubleSpinBox_smallR_BJ1">
   <property name="geometry">
    <rect>
     <x>501</x>
     <y>10</y>
     <width>130</width>
     <height>22</height>
    </rect>
   </property>
   <property name="maximum">
    <double>6500.000000000000000</double>
   </property>
   <property name="value">
    <double>40.000000000000000</double>
   </property>
  </widget>
  <widget class="QDoubleSpinBox" name="doubleSpinBox_middleR_BJ1">
   <property name="geometry">
    <rect>
     <x>501</x>
     <y>40</y>
     <width>130</width>
     <height>22</height>
    </rect>
   </property>
   <property name="maximum">
    <double>6500.000000000000000</double>
   </property>
   <property name="value">
    <double>60.000000000000000</double>
   </property>
  </widget>
  <widget class="QDoubleSpinBox" name="doubleSpinBox_bigR_BJ1">
   <property name="geometry">
    <rect>
     <x>501</x>
     <y>70</y>
     <width>130</width>
     <height>22</height>
    </rect>
   </property>
   <property name="maximum">
    <double>6500.989999999999782</double>
   </property>
   <property name="value">
    <double>80.000000000000000</double>
   </property>
  </widget>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>441</x>
     <y>16</y>
     <width>54</width>
     <height>12</height>
    </rect>
   </property>
   <property name="text">
    <string>半径(小):</string>
   </property>
  </widget>
  <widget class="QLabel" name="label_2">
   <property name="geometry">
    <rect>
     <x>441</x>
     <y>46</y>
     <width>54</width>
     <height>12</height>
    </rect>
   </property>
   <property name="text">
    <string>半径(中):</string>
   </property>
  </widget>
  <widget class="QLabel" name="label_3">
   <property name="geometry">
    <rect>
     <x>441</x>
     <y>76</y>
     <width>54</width>
     <height>12</height>
    </rect>
   </property>
   <property name="text">
    <string>半径(大):</string>
   </property>
  </widget>
  <widget class="QWidget" name="BJ1ReturnConfig" native="true">
   <property name="geometry">
    <rect>
     <x>130</x>
     <y>60</y>
     <width>172</width>
     <height>172</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">background-color: rgb(255, 255, 220);</string>
   </property>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

执行效果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhongliang1020

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值