天天看点

Qt:双缓存绘图总结Qt:绘图总结流程图主线程主要的工作内容:绘图线程主要的工作内容:

目录

Qt:绘图总结

流程图

主线程主要的工作内容:

绘图线程主要的工作内容:

Qt:绘图总结

  • 在线实时动态绘图—双缓存绘图法(两个线程,【主线程】和【绘图线程】)

流程图

如下:

Qt:双缓存绘图总结Qt:绘图总结流程图主线程主要的工作内容:绘图线程主要的工作内容:

关于流程图的说明:

主线程(QWidget):负责绘图线程变量的声明定义及初始化,信号和槽,并将绘图线程绘制好的图片打印在主窗口上。

绘图线程(QObejct):负责按照要求绘图,并将绘制好的图片传递给主窗口。

  • 具体程序说明

主线程主要的工作内容:

  1. 包含必要的头文件(QT及绘图线程的头文件)
  2. 声明各类指针(1:绘图线程的指针对象,2:线程指针)
  3. 在构造函数中,对指针进行初始化【此处要注意,要将指针对象的父类指向线程指针,进行信号和槽的设置(包括各类槽函数和信号的原型声明及定义),主线程触发信号,绘图线程进行绘图】
  4. 绘图线程完成绘图,发送信号给主线程,并将绘制好的图片传递给主线程
  5. 主线程接受到绘图线程的图片后,进行绘制
  • 主线程.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
//绘图线程的头文件
#include"imagethread.h"
//线程头文件
#include<QThread>
//绘图需要的头文件
#include<QImage>
#include<QPainter>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

protected:
    void paintEvent(QPaintEvent *event);
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

     void stopimage();//关闭image画图线程

     void getimag(QImage);//接受绘图线程绘制好的图片,并更新绘图事件
     
     void imagesignal();//启动绘图线程绘图函数的命令

private slots:
    ...
private:
    Ui::Widget *ui;

   imagethread *imT;//建立属于绘图线程的指针对象
   QThread *imgthread;//线程指针
   QImage image;//image变量

signals:
   void sendimage();//主线程.cpp中有解释这个型号的作用
  
};

#endif // WIDGET_H
           
  • 主线程.cpp
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
//    ui->setupUi(this);//自己写的ui,就不需要这个了
    uiset();

    /*****************线程image********************/

    imT = new imagethread;//分配空间

    imgthread = new QThread(this);//指定父对象,子线程

    imT->moveToThread(imgthread);//自定义线程加入子线程

    //注意:使用moveToThread的对象的父对象必须是QObejct类型

    //启动image子线程
    imgthread->start();

    //启动线程绘图函数的信号和槽,只有发送sendimage信号时,绘图线程中真正绘图的函数才会启动
    connect(this,&Widget::sendimage,imT,&imagethread::drawImage);//发送sendimage,就会启动线程中的drawimage函数,进行画图

    connect(imT,&imagethread::updateImage,this,&Widget::getimag);//一旦画图线程被调用,就会把画好的内容反馈到传输到getimage函数
    
}
Widget::~Widget()
{
    delete ui;
}

//画图信号(绘图线程的启动)
void Widget::imagesignal()
{
   ..............

    emit sendimage();//启动绘图线程的信号,正式进入绘图线程,进行绘图

   ..............

}
//前界面画图程序
void Widget::getimag(QImage temp)
{

    qDebug()<<"image绘制好的图片已经传输给widget,完成";
  
    update();//更新paintEvent事件
  

}
//画图事件
void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    QPainter p(this);//指定对象为窗口

    p.drawPixmap(0,0,width(),height(),QPixmap("://image/ubk.png"));//设置背景图片
    
    p.drawImage(x,y,image);//起点坐标x和y,之后绘图线程绘制好的图片
}


 //关闭线程image
 void Widget::stopimage()
 {

     if(imgthread->isRunning() == true)
     //首先判断线程是否已经关闭,如果关闭请避免多次关闭引发内存泄漏
     {

         imgthread->quit();
         imgthread->wait();
     }
     if(imT!=NULL)//imT不为空,删除,让他变成空的
     {
         delete imT;
     }
 }

           

注意:使用moveToThread的对象的父对象必须是QObejct类型 子线程的类必须是QObject

绘图线程主要的工作内容:

  1. 与主线程信号和槽对应的槽函数的原型声明及定义
  2. 将绘制好的图片返回给主线程
  • 绘图线程.h
#ifndef IMAGETHREAD_H
#define IMAGETHREAD_H

#include <QObject>
#include<QPainter>
#include<QImage>

#include<QDebug>

class imagethread : public QObject
{
    Q_OBJECT
public:
    explicit imagethread(QObject *parent = nullptr);
    //线程处理函数
    void drawImage();


signals:
    //发送信号,把画好的图片进行传送
    void updateImage(QImage temp);

public slots:

};

#endif // IMAGETHREAD_H

           

绘图线程.cpp

#include "imagethread.h"

imagethread::imagethread(QObject *parent) : QObject(parent)
{

}

void imagethread::drawImage()
{   
    QImage image(truesize,truesizeh,QImage::Format_ARGB32);//画幅大小
    //定义画家,指定绘图设备
    QPainter p(&image);

    ................//绘制操作

    emit updateImage(image);//将绘制好的图片传送
}