我有一個全尺寸的QGLWidget,它使用QPainter繪製應用程序背景(將來可能會更改爲本機openGL命令)。QGLWidget上的半透明QWidget:奇怪的結果
在此QGLWidget的頂部,我使用QWidgets(非GL)作爲用戶界面元素。例如,這些是QLineEdits和QPushButtons。我把它們放到一個使用半透明背景繪畫的自定義繪畫QWidget中。 QLineEdit和QPushButton的paintEvents被覆蓋,並使用半透明背景。
整個UI 應該像下面(這是我禁用OpenGL和使用了QWidget代替QGLWidget來繪圖爲背景的截圖。請注意,半透明的頂欄也繪製陰影(其自己的區域內)):
當QLineEdit的具有焦點,它應該有一個更高的透明度,但仍不能完全不透明:
所以現在,在啓用了OpenGL的情況下(背景是QGLWidget),上面的半透明窗口小部件不會在背景上繪製,而是(看起來像)未初始化的數據。通過頂部酒吧照射的圖像有時是整個窗戶本身,有時還有其他窗戶正在我的桌面上。
這目前看起來如下(在這個屏幕截圖中,似乎是小部件本身的圖像在其上的半透明畫操作畫上的數據,具有偏移。):
當我將文本寫入行編輯(這裏是:「這是一些文本已經在那裏!」),刪除它並設置焦點回到背景部件(所以放大鏡圖標和佔位符文本出現),先前繪製的東西仍然閃耀(注意可見邊框應該是而不是可見了,但也還是照過):
所以問題是:與其被畫在底層部件之上,半透明窗口小部件塗在老頂結果,最初就像「未初始化的內存」。
這是爲什麼發生?我該如何解決這個問題?
事情你纔回答應該知道:
- 背景場景是瓷磚的組合物,其呈現在屏幕之外。所以它可以非常快速地繪製,並且重疊的每一個小變化的背景重繪都沒有問題。
- 頂部欄是一個自定義QWidget,包含兩個小部件(按鈕和行編輯)的手動繪製和排列。
- 這兩個小部件覆蓋paintEvent,只有在他們有焦點時才繪製自己的(半透明)背景,並且不使用Qt已經提供的框架。因此,第二個屏幕截圖中的白色邊框繪製在我的自定義paintEvent中。
- 我希望疊加窗口小部件的背景和組成可以分開實現。背景是一個
AbstractMapView
,它有一些具體的地圖視圖類。整個窗口是一個AbstractView
(也有多個具體視圖),它包含具體的地圖視圖和疊加小部件,以一種方式自己決定。因此,我不希望疊加小部件的邏輯成爲底層映射視圖的一部分。 (我希望你明白這一點,因爲它有點複雜。)
感謝您指出問題和鏈接。但是,建議的解決方案(使用圖形場景)聽起來太重了。你說:「確保Qt知道像素是非常重要的,所以你的前景小部件可以將半透明度應用到他們的背景中。」你是怎麼做到的?有沒有圖形場景的可能解決方案?另外請注意,我想繪製小部件,不僅是圖形項目。 – leemes 2012-07-23 11:19:06
@leemes對我們的繪畫專家進行說明,更新我的答案,爲您提供更多信息,簡而言之,使GL輸出可用於緩衝區,並使用Qt的工具將其繪製到屏幕上。 – Matthew 2012-07-23 12:57:24
非常感謝。我還看到一個缺點:渲染的地圖將被複制到RAM中(進入我的過程)。我對麼?正如你所說,由於Qt需要「知道」這些像素,這是一個必要的步驟。所以它不會比這更好? – leemes 2012-07-23 13:07:49