目录
Qt:绘图总结
流程图
主线程主要的工作内容:
绘图线程主要的工作内容:
Qt:绘图总结
- 在线实时动态绘图—双缓存绘图法(两个线程,【主线程】和【绘图线程】)
流程图
如下:
关于流程图的说明:
主线程(QWidget):负责绘图线程变量的声明定义及初始化,信号和槽,并将绘图线程绘制好的图片打印在主窗口上。
绘图线程(QObejct):负责按照要求绘图,并将绘制好的图片传递给主窗口。
- 具体程序说明
主线程主要的工作内容:
- 包含必要的头文件(QT及绘图线程的头文件)
- 声明各类指针(1:绘图线程的指针对象,2:线程指针)
- 在构造函数中,对指针进行初始化【此处要注意,要将指针对象的父类指向线程指针,进行信号和槽的设置(包括各类槽函数和信号的原型声明及定义),主线程触发信号,绘图线程进行绘图】
- 绘图线程完成绘图,发送信号给主线程,并将绘制好的图片传递给主线程
- 主线程接受到绘图线程的图片后,进行绘制
- 主线程.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
绘图线程主要的工作内容:
- 与主线程信号和槽对应的槽函数的原型声明及定义
- 将绘制好的图片返回给主线程
- 绘图线程.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);//将绘制好的图片传送
}