我有一些数据会不断变化。我通过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;
}
答案 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();
}