QWidget的paintEvent()滞后应用程序
我正在研究和修改 冰箱磁铁 示例,最后一件事是我我尝试做的是画一些应该在背景上的标签和线条。
在环顾四周试图弄清楚如何绘制标签和线条之后,我了解到我可以重写 QWidget 的 PaintEvent() 来完成它。在我这样做之后,应用程序变得缓慢,我发现这是因为在看似无限循环中调用了paintEvent()。
为了弄清楚如何解决这个问题,我将绘制标签和线条的代码移到了类的构造函数中。但应用程序上仅绘制了标签。之后,我将标签留在了构造函数中,但将绘制线条的代码移回了paintEvent()。它有效,线条按预期绘制,并且仅在拖动东西时才调用paintEvent()。
为什么线条没有在构造函数上绘制,为什么paintEvent() 进入无限循环?
这是应该绘制标签和线条的片段:
QPen pen(Qt::lightGray, 0, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin);
QPainter paint(this);
paint.setPen(pen);
int scale = 20;
for(int x=0; x<25; x++){
QString timetext= "0"+QString::number(x)+":00";
QLabel *time= new QLabel(timetext,this);
time->move(x*scale,2);
time->show();
paint.drawLine(x*scale,12,x*scale,400);
}
i'm studying and modifying the fridge magnets example, and the last thing I've tried to do was to draw a few labels and lines that are supposed to be on the background.
After looking around trying to figure out how to draw the labels and lines, I learned that I could override QWidget's paintEvent() to do it. After I did it though, the application got laggy, and I found out that it was because paintEvent() was being called in a seemingly infinite loop.
Trying to figure out how to fix that, I moved the code that drew the labels and lines to the constructor of the class. Only the labels were drawn on the application though. After that, I left the labels in the constructor, but moved the code that drew the lines back to paintEvent(). It worked, the lines were drawn as expected, and paintEvent() was called only when dragging stuff around.
Why were the lines not being drawn on the constructor, and why paintEvent() got into an infinite loop?
Here's the snippet that's supposed to draw the labels and lines:
QPen pen(Qt::lightGray, 0, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin);
QPainter paint(this);
paint.setPen(pen);
int scale = 20;
for(int x=0; x<25; x++){
QString timetext= "0"+QString::number(x)+":00";
QLabel *time= new QLabel(timetext,this);
time->move(x*scale,2);
time->show();
paint.drawLine(x*scale,12,x*scale,400);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您将在
paintEvent()
期间将对象添加到 Widget Tree。则视为失败。用于损坏和绘制的 Qt 调度程序将看到必须绘制一个新的子级并尝试对其进行管理,并且可能会导致循环。如果您重写paintEvent(),请在同一个对象中进行所有绘画!黄金法则:paintEvent()
仅用于绘画!不用于创建对象或其他任何东西。这样做:
You are adding Objects to the Widget Tree during
paintEvent()
. That is deemed to fail. The Qt scheduler for damage&drawing will see that a new child has to be drawn and try to manage that and likely the loop is the result. If you override paintEvent(), do all the painting in the same object! Golden rule:paintEvent()
is only for painting! Not for creating objects or anything else.Do it like this:
为什么这些线条没有在构造函数上绘制?
我认为它们是这样,但是它们被下次调用paintEvent()时“擦除”了,在该调用中您不再绘制线条了...
为什么paintEvent()进入无限循环?
我认为这可能与你的 time->show(); 有关。每次调用 PaintEvent 时都会调用 25 次...我对此不确定,但是,由于时间作为窗口小部件作为父级,当您调用“show”时,也许它会在其父级上调用“show”,因此触发 PaintEvent。 ...你知道我的意思...
既然Ypnos给了你一个解决方案,我就参考他:)
Why were the lines not being drawn on the constructor ?
I think they were, but they were "erased" by the next call to paintEvent() in which you didn't draw the lines anymore...
Why paintEvent() got into an infinite loop?
I think it could be related to your time->show(); which is called 25 times everytime paintEvent is called... I'm not sure about that but, since time as the widget as parent, when you call "show", maybe it calls "show" on its parent, therefore triggering paintEvent.... You know what I mean...
Since, Ypnos gave you a solution, I refer to him :)