仅在关闭窗口时才更新带有计时器的 QT 画家更新
Posted
技术标签:
【中文标题】仅在关闭窗口时才更新带有计时器的 QT 画家更新【英文标题】:QT painter update with timer only update when close window 【发布时间】:2013-07-30 07:15:59 【问题描述】:我有一些数据会不断变化。我通过 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;
【问题讨论】:
您在此期间无限次调用a.exec()
。可能不是问题。但有些东西肯定需要修复。
【参考方案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();
【讨论】:
感谢您的回复。但是当我创建另一个函数来包装 update() 时,它不会在超时时进行更新。将我的计时器连接更改为:'connect(timer, SIGNAL(timeout()), this, SLOT(MyUpdate()))' 是否正确? 是的,但如果它不起作用,请在您的问题中添加编辑并向我们展示代码。导致问题的原因可能很简单。 每次输入函数 test_plot 时,您都会使用 malloc 为 pMergedData 创建一个新的点数组。这应该只做一次,要么在 main 中(因为它是一个全局变量),要么更好地将数组移动到类中并在构造函数中初始化它。 我还注意到您缺少 Q_OBJECT 宏,该宏需要在声明类之后放置在您的标题中。所以就在这行之后, class DrawDemo : public QWidget Q_OBJECT.您需要它来使信号和插槽正常工作。 终于可以实时更新了!非常感谢您帮我找到问题!!以上是关于仅在关闭窗口时才更新带有计时器的 QT 画家更新的主要内容,如果未能解决你的问题,请参考以下文章
Mongoose:批量更新插入,但仅在满足某些条件时才更新记录