• 4174阅读
  • 0回复

[讨论]在 qt 事件中含有耗时操作的函数的处理 [复制链接]

上一主题 下一主题
离线qypan
 

只看楼主 倒序阅读 楼主  发表于: 2016-07-25
就比如我希望实现这样的功能:
我单击鼠标时,程序以鼠标当前坐标 (x, y) 为圆心画了一个圆,半径随意(比如 30),然后我希望程序在我单击 3 秒后自动以 (x+40, y+40) 为圆心画一个跟前面同样大小的圆.
3 秒只是模拟耗时操作,这里我并不希望使用多线程,我上网查过,应该可以使用 QCoreApplication::processEvents() 或 QEventLoop 类实现。但没有找到实例,这两个东西真心不会用。希望有人可以提供可以解决我问题的链接,或者给我提供一个类似的实例。
我的代码(可在 linux 系统编译执行):
//mything.h
#ifndef MYTHING_H
#define MYTHING_H

#include <QtGui>

class myThing : public QLabel{
    Q_OBJECT
public:
    myThing(QWidget *parent = 0);
protected:
    void drawAnother(int x, int y);
    void paintEvent(QPaintEvent *event);
    void mousePressEvent(QMouseEvent *event);
private:
    QPixmap *pixmap;
};

#endif

------------------------------------------------------------------------------------------
//mything.cpp
#include <unistd.h> //linux 系统函数库
#include "mything.h"

myThing::
myThing(QWidget *parent)
    : QLabel(parent)
{
    resize(400, 200);
    pixmap = new QPixmap(400, 200);
    pixmap->fill(QColor(255, 255, 255));
}

void myThing::
paintEvent(QPaintEvent *event){
    QPainter painter(this);
    QRect dirtyRect = event->rect();
    painter.drawPixmap(dirtyRect, *pixmap, dirtyRect);
}

void myThing::
drawAnother(int x, int y){
    sleep(3); //其他平台做适当更改
    QPainter painter;
    painter.begin(pixmap);
    painter.setPen(Qt::NoPen);
    painter.setBrush(QColor(56, 12, 23, 141));
    painter.drawEllipse(QPoint(x, y), 30, 30);
    update(QRect(QPoint(x-30, y-30), QSize(60, 60)).
            normalized().adjusted(-2, -2, 2, 2));
    painter.end();
}

void myThing::
mousePressEvent(QMouseEvent *event){
    int x = event->x();
    int y = event->y();
    QPainter painter;
    painter.begin(pixmap);
    painter.setPen(Qt::NoPen);
    if(event->button() == Qt::LeftButton){
        painter.setBrush(QColor(43, 56, 233, 111));
        painter.drawEllipse(QPoint(x, y), 30, 30);
        update(QRect(QPoint(x-30, y-30), QSize(60, 60)).
                normalized().adjusted(-2, -2, 2, 2));
        painter.end();
        // 下面的函数是耗时函数,程序执行的效果是,单击鼠标左键 3 秒后连续画了 2 个圆,我希望的效果是单击时画一个,3 秒后再自动画一个。问题是鼠标事件没返回,所以事件循环队列里的第一个圆的绘图事件处理不了;直到下面的函数调用之后,才一次处理两个绘图事件
        drawAnother(x+40, y+40);
    }
}
------------------------------------------------------------------------------------------
//main.cpp
#include "mything.h"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
      
    QCoreApplication::processEvents();
    myThing window;
    window.setWindowTitle("myThing");
    window.show();

    return app.exec();
}
快速回复
限100 字节
 
上一个 下一个