我可以将画家放入类变量中吗? :
protected:
QPainter *myPainter;
...
void MyWidget::paintEvent(QPaintEvent *event)
{
myPainter = new QPainter(this);
答案 0 :(得分:3)
更具体地解决更多重入问题的新广告......
danatel将以下评论留给this message(部分):
通过重入我的意思是这种特殊情况:1)paintEvent处理程序将QPainter保存到类变量中。 2)paintEvent处理程序调用子程序来绘制东西3)其中一个子程序调用Qt方法4)这个Qt方法递归地生成另一个paintEvent
对此的答案是它应该是可以接受的,除非你做了一些非常奇怪的事情。 (如果你做了一些奇怪的事情,Qt可能会警告你或中止。)我认为对于你的意思可能仍然存在一些混淆,但是生成一个paintEvent不会立即停止当前动作的执行流程处理那个事件。相反(与所有事件一样),它将排队等待以后处理。只要您没有进行多线程或调用processEvents,当您在自己的函数中时,代码的执行顺序应该非常简单。
举个例子,让我们按照您的步骤进行更详细的检查。
Foo::paintEvent()
处理程序
创建一个QPainter并设置
Foo::m_painter_p
就可以了。 Foo::paintEvent()
来电
Foo::paintAntarticaFlag()
。Foo::paintAntarticaFlag()
:a)使用Foo::m_painter_p
,然后b)调用调用Foo::update()
的内容,然后c)再使用Foo::m_painter_p
。Foo::update()
,它实际上是一个Qt方法,为Foo生成一个paintEvent。上述顺序很好,因为更新会创建事件,这意味着延迟处理。如果您调用了Foo :: repaint(),那么会导致立即递归到Foo :: paintEvent(),这会导致Qt中止,因为您为同一个对象创建了多个画家,或者您的程序要中止因为它最终(你知道,在几百毫秒内)吹灭了堆栈。
如果您正在执行多个线程并且只想触发重绘,您仍然可以从另一个线程执行此操作,因为它只会在队列上放置一个paintEvent,以便在适当的时间由正确的线程处理。如果你正在做多个线程,并希望使用相同的画家绘制这些标志,那么,不要。只是不要。在这种情况下,您可以考虑将每个标志绘制到共享图像,并将该图像绘制到您现在使用QPainter的位置。
答案 1 :(得分:2)
不要那样做。只需将它放在堆栈上,这样当它在析构函数中被销毁时,它将自动执行绘制。
void MyWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
// use painter
...
// paint object automatically closes and paint on desctruction
}
答案 2 :(得分:1)
如果您试图避免将painter小部件传递给许多子例程调用,您可能会将指向画家的指针作为类变量。如前所述,您仍应在paintEvent函数中创建/销毁它。就个人而言,我可能只是将它传递给辅助函数,但你可以这样做。
另外,我不确定你的问题与重入有关。如果你有多个线程,那么所有UI元素的绘制都应该只在UI线程中。你可以在不同的线程中对图像做一个画家,但在这种情况下,你可能只想在该线程中绘制该图像,而不是在多个线程中。无论哪种方式,只要你遵守这些条件,我认为你不会遇到Qt函数的重入问题,你可以调用它们。