17、多线程画图

1、界面上的按钮,按下一次随机产生5个点,并连接起来,画一个五边形;

2、程序实现框图

 

3、创建一个类继承QObject 

  1、创建线程类

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

signals:
    void updataImage(QImage tmp);  // 线程执行完毕信号

public slots:
};

  2、实现线程处理函数

// 线程处理函数
void MyThread::drawImage()
{
    // 定义一个画图设备
    QImage image(500,500,QImage::Format_ARGB32);
    // 定义画家  指定绘图设备
    QPainter p(&image);

    // 定义一个画笔
    QPen pen;
    pen.setWidth(5);  // 定义画笔宽度
    p.setPen(pen);    // 画笔交给画家

    // 定义画刷
    QBrush brush;
    brush.setStyle(Qt::SolidPattern);  // 设置画刷样式
    brush.setColor(Qt::red);   // 设置画刷颜色
    p.setBrush(brush);
    // 定义五个点 随机产生五个点
    QPoint a[]={
        QPoint(qrand()&500,qrand()&500),
        QPoint(qrand()&500,qrand()&500),
        QPoint(qrand()&500,qrand()&500),
        QPoint(qrand()&500,qrand()&500),
        QPoint(qrand()&500,qrand()&500)
    };
   // 画线 与点的顺序有关,依次连接起来
    p.drawPolygon(a,5);
    emit updataImage(image);  // 通过信号发送图片
}

  3、主窗口类中用的资源初始化

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();
    void paintEvent(QPaintEvent* e);
    QImage image;   // 全局用于接收 线程返回来的image设备
    MyThread *myT;  // 自定义线程
    QThread *thread; // 定义子线程
    void getImage(QImage img); // 获取image
    void dealClose();  // 关闭窗口槽函数 关闭线程 释放资源
private:
    Ui::Widget *ui;
};

  4、构造函数中资源、信号处理

// 自定义类对象 分配空间
    myT = new MyThread;
    // 创建子线程对象
    thread = new QThread(this);
    // 把自定义模块添加到子线程
    myT->moveToThread(thread);
    // 启动子线程 不起启动线程处理函数
    thread->start();

    // 线程处理函数必须 通过signal-slot调用
    connect(ui->pushButton,&QPushButton::pressed,myT,&MyThread::drawImage);
    connect(myT,&MyThread::updataImage,this,&Widget::getImage);  // 处理线程画图结束信号 并返回绘图设备
    connect(this,&Widget::destroyed,this,&Widget::dealClose);  // 处理关闭窗口信号 释放线程资源

  5、connect中槽函数实现

// 处理窗口关闭信号
void Widget::dealClose()
{
    thread->quit();  // 退出线程
    thread->wait();  // 回收资源
    delete(myT);     // 释放对象
}
// 接收绘图设备
void Widget::getImage(QImage img)
{
    image = img;  // 将绘图设备传过去
    update();     // 更新绘图窗口  间接调用paintevent
}
// 重写绘图事件
void Widget::paintEvent(QPaintEvent* e)
{
    QPainter p(this);   // 创建画家 指定窗口绘图设备
    p.drawImage(50,50,image);  // 将接收过来的绘图设备 画在主窗口上
}

4、结果显示

 

posted @ 2020-08-17 14:48  笑不出花的旦旦  阅读(973)  评论(0)    收藏  举报