Qt 中QPainter 使用中出現的問題


這兩天在使用QPainter的過程中出現了一些問題,記錄一下。

測試程序很簡單,寫一個繼承自QWidget的類,重載其paintEvent函數進行繪圖。

 

 

 case1:

在paintEvent函數中使用一個臨時的painter對象進行繪制。

 

 

 結果:能夠正常繪制。

case2:

在paintEvent函數中動態分配一個painter對象進行繪制。

 

 

 結果:能夠正常繪制。

 

case3:將Painter聲明為一個類的成員變量進行繪制。

 

 

 

 

 

 

 

 

 

結果:不能正常繪制

 

 

 分析:由於我在初始化m_painter時,用到的是QPainter m_painter(this);

這句代碼等於QPainter m_painter,m_painter.begin(this);

但是m_painter.begin()函數只有在paintEvent()函數中調用才是有意義的(Qt中的繪制動作只能在paintEvent()函數中完成)

由於此時begin()函數隱式在構造函數中被調用了,最終倒是繪圖動作失效。

試探的解決辦法:在用不帶參數的構造函數初始化painter,然后再paintEvent函數中利用begin函數為painter綁定對象。

 

 

 

 試探的解決方法的結果;窗體先是正常繪制,接着就崩潰了,並報出如下錯誤:

 

 

 我原本的思路是:當MyWidget對象析構是,就會自動調用其內部成員變量painter的析構函數,所以我就沒有顯式的嗲用end()函數,因為我希望painter對象能夠在MyWidget的聲明周期中一直存在。

結果:程序提醒我在繪制完成后必須調用end()函數,難道QPainter對象是一個一次性消耗品,用完一次就得扔?

果然,當加上end()代碼后,程序就沒問題了。

 

 

 

但是,調用end()函數中,m_painter對象就等於析構了。當我第二次進行繪制動作時,會不會出現問題?

結果是並不會,因此當進行隱藏以及重現窗體,更改窗體大小這些動作時(這些動作都會觸發窗體的重繪操作),窗體並沒有崩潰。

這里我有點疑惑,難道時begin()函數為m_painter重新分配了資源?可按理來說,已經析構的對象時無法再次使用的。。

Qt的文檔上並沒有相關的解答。

 

 

 

 總之:從這個例子中我可以體會到painter的構造析構函數與begin()end()函數是有區別的。

 

 case4:以一個QPainter對象的指針作為類成員變量,為這個指針分配資源。

如是在構造函數中以帶參數的構造函數來初始化QPainter對象,依然會出現上面的錯誤。

 

 

 

 

 

 一個嘗試:我故意不用end()函數結束繪制,而選擇delete掉m_painter;

 

 程序果然崩潰了:

總結:end()函數和delete是有區別的,end()之后還能再begin(),在delete之后,該對象就徹底消失了。

 

小小感觸:最好還是將QPainter對象當成一個一次消耗品來用吧,即在需要繪圖時創建一個臨時的QPainter對象來進行繪制。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM