仅在关闭窗口时更新带有计时器的Qpainter更新

时间:2013-07-30 07:16:00

标签: c++ c qt

我有一些数据会不断变化。我通过QPainter将这些数据绘制成行,并希望通过QTimer进行动态更新(每秒更新),但数据只会在关闭绘制窗口时更新,不会在窗口中实时更新。我哪里错了? 这是代码:

#include <QtGui/QApplication>
#include <QApplication>
#include <QLabel>
#include <QWidget>
#include <QPainter>
#include <QTimer>

#define WINDOW_H 512
#define WINDOW_W 512

unsigned char *pMergedData; 

class DrawDemo : public QWidget {
    Q_OBJECT
public: 
    DrawDemo( QWidget *parent=0); 
public slots:
    void MyUpdate();
protected:
    void paintEvent(QPaintEvent*);
private:
    QTimer *timer; 
}; 

void DrawDemo::MyUpdate(){
    test_plot();
    update();
}

DrawDemo::DrawDemo( QWidget *parent) :QWidget(parent){ 
    pMergedData = (unsigned char *)malloc(200*sizeof(short));
    QTimer *timer = new QTimer(this); 
    connect( timer, SIGNAL( timeout() ), this, SLOT(  MyUpdate()  ) ); 
    timer->start( 1000 ); //ms 
} 

void DrawDemo::paintEvent( QPaintEvent * ) {
    short *buf16 = (short *)pMergedData;

    QPainter painter( this );
    QPoint beginPoint;
    QPoint endPoint; 

    painter.setPen(QPen(Qt::red, 1));
    for( int i=0; i<199; i++ ) {
        beginPoint.setX( 2*i );
        beginPoint.setY( WINDOW_H - buf16[i] ); 
        endPoint.setX( 2*i+1 );
        endPoint.setY( WINDOW_H - buf16[i+1]);
        painter.drawLine( beginPoint, endPoint );
    }
} 

int test_plot(){

    counter_globol ++;
    if(counter_globol%2==0){
        for(int i=0; i<200; i++ ) { 
            pMergedData[i] = 100;
         } 
    }else{
            for(int i=0; i<200; i++ ) { 
            pMergedData[i] = i;
        } 
    }

    return 0;

}
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    DrawDemo *drawdemo = new DrawDemo( 0 ); 
    drawdemo->setWindowTitle("QPainter");
    drawdemo->resize(WINDOW_W, WINDOW_H);
    drawdemo->show();

    a.exec();
    free(pMergedData);
    return 0;
}

1 个答案:

答案 0 :(得分:1)

更新仅在关闭窗口时发生,因为代码结构错误。

a.exec()函数启动程序的主事件循环,该循环处理正在发生的所有事件,例如鼠标移动,按钮按下和定时器。在窗口关闭之前,它不会退出该功能。此时,a.exec()期望程序正在完成。

在您发布的代码中,它设置行的数据,创建窗口小部件,然后使用a.exec()启动消息处理程序。现在,这些行永远不会改变,因为pMergedData中的数据永远不会被再次调用,直到窗口关闭,但不应该以这种方式处理a.exec()。

关闭窗口并重新打开它时,a.exec()函数返回,由于你的while循环,pMergedData中的数据被重新初始化并创建一个新窗口。

所以,要解决这个问题,你需要这样的东西: -

int main(int argc, char *argv[])
{
    QApplication a;

    DrawDemo *drawdemo = new DrawDemo( 0 ); 
    drawdemo->setWindowTitle("QPainter");
    drawdemo->resize(WINDOW_W, WINDOW_H);
    drawdemo->show();   

    a.exec();
    return 0;
}

如您所见,我已将QApplication和DrawDemo对象的创建移出test_plot函数。由于您希望每秒更改数据,您还应该每秒调用test_plot,因此不是让计时器每秒调用窗口小部件函数更新,而是创建自己的函数MyUpdate并连接到它: -

void DrawDemo::MyUpdate()
{
    test_plot();
    update();
}