Qt--paintEvent绘制雷达扫描图

新建一个Qt的窗口类,默认命名:

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    QPixmap paintWidget();

protected:
    void paintEvent(QPaintEvent *event);
    void resizeEvent(QResizeEvent *event);
protected slots:
    void timerTimeOut();

private:
    Ui::Widget *ui;
    QTimer *timer;
    QPoint point;
    int i_diameter=0;
    double d_angle=0;
    QList<QPixmap> list_pixmap;
};
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setStyleSheet("background-color:black");//设置窗口背景色为黑色
    timer = new QTimer();
    connect(timer,SIGNAL(timeout()),this,SLOT(timerTimeOut()));

    timer->start(10);
}

重写resizeEvent函数,当窗口缩放时,对绘图的大小也进行缩放:

void Widget::resizeEvent(QResizeEvent *event)
{
    if(this->width() > this->height()){
        point = QPoint((this->width()-this->height())/2+(this->height()-12)/2,this->height()/2);
        i_diameter = this->height()-12;
    }else{
        point = QPoint(this->width()/2,(this->height()-this->width())/2+(this->width()-12)/2);
        i_diameter = this->width()-12;
    }
}

在绘图函数中主要使用了QPixmap的定义画布,QPEN定义画笔,QConicalGradient对图形进行渐变填充,drawEllipse进行画圆:

QPixmap Widget::paintWidget()
{
    QPixmap pixmap(this->width(),this->height());
    QPainter p_painter(&pixmap);
    QPen pen;
    QTime timedebug;
    timedebug.start();
    //反锯齿
    p_painter.setRenderHint(QPainter::Antialiasing);
    pixmap.fill(Qt::black);

    pen.setColor(Qt::green);
    p_painter.setPen(pen);

    pen.setColor(Qt::gray);
    p_painter.setPen(pen);
    p_painter.drawLine(point.x(),point.y()-i_diameter/2-10,point.x(),point.y()+i_diameter/2+10);//画坐标
    p_painter.drawLine(point.x()-i_diameter/2-10,point.y(),point.x()+i_diameter/2+10,point.y());
    pen.setColor(Qt::green);
    p_painter.setPen(pen);
    for(int i=0; i<6; i++){
        p_painter.drawEllipse(point.x()-i_diameter*0.2*i/2,point.y()-i_diameter*0.2*i/2,i_diameter*0.2*i,i_diameter*0.2*i);
    }

    QConicalGradient conical_gradient(point,(6.28-d_angle)/6.28*720);//定义圆心和渐变的角度
    conical_gradient.setColorAt(0,Qt::green);
    conical_gradient.setColorAt(0.2,QColor(255,255,255,0));
    p_painter.setBrush(conical_gradient);
    p_painter.drawEllipse(point.x()-i_diameter/2,point.y()-i_diameter/2,i_diameter,i_diameter);


    qDebug()<<"time_end="<<timedebug.elapsed()<<"ms";

    return pixmap;

}

QTimer定义定时器连接槽函数,当定时溢出时对图像进行刷新,同时重新开启定时,定时单位是毫秒:

void Widget::timerTimeOut()
{
    timer->start(10);
    d_angle += 3.14/720;
    if(d_angle >= 6.28){
        d_angle = 0;
    }
    update();

}

最后对paintEven进行重构:

void Widget::paintEvent(QPaintEvent *event)
{
    QPainter p_painter(this);
    //反锯齿
    p_painter.setRenderHint(QPainter::Antialiasing);

    p_painter.drawPixmap(0,0,this->width(),this->height(),paintWidget());

    QWidget::paintEvent(event);
}

就可以得到一直在扫描的图像:

源码:

https://download.csdn.net/download/sinan1995/10576897(paintEven绘图)

更新:

https://download.csdn.net/download/sinan1995/10603637(使用QML进行绘图,占用资源较少,这个做的比较简单一点,仅供参考)

问题:

因为图像会随着窗口的拉伸而变大,当图像变得比较大时,绘图的时间就会变的比较长,图像越大绘图时间越长,看着图像的移动比较缓慢。目前暂时想到了几种简单的思路:

1,使用图片:的paintEvent只绘制坐标,扫描的动画使用图片的格式来实现,对图片不断进行旋转,这种方法对图片的透明度有要求。

2,使用多线程:使用多线程同时绘制多个图形,使用信号量对图形进行读取显示。

3,改变渐变填充的区域:这里的渐变填充是填充了整个圆形区域,可以改变填充的区域,使用drawPie绘制扇形进行渐变填充。

4,使用Qt封装的openGL或者第三方库,例如:https://sourceforge.net/projects/qfi/ 这种(这是飞行仪表的开源库,代码很短)。

猜你喜欢

转载自blog.csdn.net/sinan1995/article/details/81329274