2008-10-11 86 views
1

我可以讓畫家進入類變量嗎? :Qt :: paintEvent是否需要重入?

protected: 
QPainter *myPainter; 

... 

void MyWidget::paintEvent(QPaintEvent *event) 
{ 
    myPainter = new QPainter(this); 
+0

你爲什麼要這麼做?爲什麼不把它放在堆棧上? – shoosh 2008-10-11 06:16:50

+0

應用程序繪製航海標誌。我想創建十幾種繪製標記元素的方法,並將它們組合到paintEvent中。我想要的方法像「DrawWedge()」而不是「DrawWedge(QPainter * painter)」。 – danatel 2008-10-11 19:43:58

回答

3

新雁來解決更重入更具體...

danatel留下這樣的評論,以this message(部分):

通過重新進入我的意思是具體情況:1)的paintEvent處理程序將QPainter保存到類變量中。 2)的paintEvent處理程序調用子程序畫點什麼3)子程序調用之一Qt的方法4)該Qt的方法生成另一個的paintEvent遞歸

這個問題的答案是,它應該有可能是可以接受的,除非你做的東西真奇怪。 (如果你做了一些奇怪的事情,Qt可能會警告你或中止。)我認爲你可能仍然會對可重入的含義產生一些困惑,但是生成paintEvent並不會立即停止當前動作的執行流程處理該事件。相反(像所有事件一樣),它將排隊等待以後處理。只要你沒有進行多線程或調用processEvents,當你在自己的函數中時,代碼的執行順序應該是非常簡單的。

作爲一個例子,讓我們按照您的步驟,並更詳細地檢查它們。

  1. Foo::paintEvent()處理 創建的QPainter,並設置 Foo::m_painter_p它。
  2. Foo::paintEvent()來電 Foo::paintAntarticaFlag()
  3. Foo::paintAntarticaFlag():a)使用Foo::m_painter_p,然後b)調用一些調用Foo::update()的東西,然後c)使用Foo::m_painter_p多一些。
  4. Foo::update(),這是一個真正的Qt方法,爲Foo生成一個paintEvent。

上述順序很好,因爲更新會創建事件,這意味着延遲處理。如果你調用Foo :: repaint(),那會導致立即遞歸到Foo :: paintEvent()中,這會導致Qt中止,因爲你爲同一個對象創建了多個畫家,或者你的程序要中止因爲它最終(你知道,在幾百毫秒內)吹掉堆棧。

如果您正在執行多個線程並且只是想觸發重繪,您仍然可以從其他線程執行此操作,因爲它只會將paintEvent放置在隊列中,以便在適當的時候由正確的線程處理。如果你正在做多個線程並且想用同一個畫家繪製這些標誌,那麼不要。不要。在這種情況下,您可以考慮將每個標記繪製到共享圖像,然後在現在使用QPainter的位置繪製該圖像。

2

不這樣做。只需將它放在堆棧上,以便在析構函數中銷燬它時,它將自動執行繪畫。

void MyWidget::paintEvent(QPaintEvent *event) 
{ 
    QPainter painter(this); 
    // use painter 
    ... 
    // paint object automatically closes and paint on desctruction 
} 
+0

IIRC在QT手冊中有一個說明,明確說明爲每次繪畫事件重新創建畫家 – 2008-10-11 10:53:03

1

如果你正試圖避免將畫家小部件的一些子程序調用的,你也許可以矇混過關的指針畫家爲類變量。如前所述,您仍然應該在paintEvent函數中創建/銷燬它。就我個人而言,我可能只是將它傳遞給幫助函數,但你可以這樣做。

另外,我不確定你的問題與重入有關。如果您有多個線程,則UI元素的所有繪製應該只在UI線程中。您可以在不同線程中的圖像上繪製畫家,但在這種情況下,您可能只想在該線程中繪製該圖像,而不是在多個線程中繪製該圖像。無論哪種方式,只要你遵守這些條件,我認爲你不會遇到Qt函數中的重入問題,你可以調用一個畫家。