本文接下來試圖看看 qlayout 與視窗的幾何尺寸控制。
注意:本文只是試**釋,qlayout其實沒有任何神秘的東西,它所有的功能離開它你也都可以做。但這並不是鼓勵大家不使用qlayout。
始終記住一點:要改變乙個widget的大小,只有move()、resize()、setgeometry()這3個東西可用,當然,對於帶裝飾器的頂級視窗,你還可以通過滑鼠等改變大小或移動視窗位置(但這個不在本文討論範圍內)。
乙個qwidget 或其派生類
對於乙個視窗(window)來說,還要區分:
看起來還蠻複雜的哈,列個表看看。
framegeometry()
幾何尺寸(位置+大小)
對於視窗,包含視窗裝飾器
x()y()
pos()
只包含位置資訊(左上角座標)
move()
只移動位置
geometry()
幾何尺寸(位置+大小)
不包含視窗裝飾器
width()
height()
rect()
size()
只包含大小資訊
setgeometry()
改變 位置+大小
resize()
只改變大小
關鍵記住一點:要程式內改變乙個widget的大小,只有move、resize、setgeometry這3個東西可用。不要被qlayout干擾,它一點都不神秘,它也只能老老實實去呼叫這類函式。
用個例子看看吧,如果
int main(int argc, char *argv)
}widget.show();
return a.exec();
}只需要挨個設定一下幾何尺寸,似乎也不複雜嘛。是吧?
其實這也不是大問題,我們只需要在子類化qwidget,覆蓋(override)它的resizeevent()函式
void widget::resizeevent(qresizeevent *)在這兒重新設定它上面的按鈕的位置和大小就行了。
這是個大問題,單一的widget還好解決,比如乙個按鈕,你可以根據文字、按鈕樣式等等計算乙個大小。可是對於復合的widget:比如我們例子中的widget中有64個按鈕,如果再將這樣的64個widget放於另外乙個widget中,會怎麼樣?
沒有什麼好辦法,仍然是需要我們乙個乙個進行計算。其實不是太難,但是操作特別繁雜。
只能是按鈕通知其parent(通過layoutrequest事件),而後parent重新排布子控制項,以獲得最佳顯示效果。
接下來,我們看看 qlayout 是如何解決這三個問題的。
layout 做哪些事情呢?
初始放置
將子widget乙個乙個放置到父widget上
layout 計算各個子widget大小,並呼叫setgeometry() 來設定
響應父widget變化
父widget大小變化時,子widget相應變化
layout 通過監聽父widget的qresizeevent事件來實現
響應子widget變化
子widget的最佳大小變化時
(比如給按鈕設定新的text)
讓父物件的layout 重新計算幾何尺寸
當乙個widget的大小變化後,會生成qresizeevent事件(這時widget所關聯layout就開始重新計算嘍...)。
我們知道,事件都是通過qwidget::event()派發的:
bool qwidget::event(qevent *event)恩,注意看上面**:如果reciever是widget而且有layout,該事件先送到layout的widgetevent()中。然後才會通過event()派發到達大家熟悉的resizeevent()等函式。}bool consumed = receiver->event(e);
...而後layout開始工作
void qlayout::widgetevent(qevent *e)
else
break;
...
前面的resize比較容易理解,如果子widget的大小想變化,如何通知layout呢?
通過void qwidget::updategeometry ()函式。
void qwidgetprivate::updategeometry_helper(bool forceupdate)看看這段**,如果parent有layout布局,直接讓布局無效(強制layout重新計算大小)。
而如果parent沒有布局呢?恩,思想也比較簡單:它給父widget傳送 layoutrequest 事件。注意:如果我們不使用布局的話,面對這種情況,我們就要自己處理這個事件嘍。
這個其實似乎是最有趣的,qlayout如果知道它負責控制的各個widget該有多大的大小呢?
qwidget::sizepolicy()
這3個東西為layout提供一些大小資訊
對於自定義widget,子類化時你可能需要提供這些資訊
qwidget::sizehint()
qwidget::minimumsizehint()
熟悉這3個東西,以及各個qlayout派生類的使用,不然,你可能會抱怨——qlayout太難用了
比如:前面的例子,我們64個按鈕,如果32個使用qgridlayout進行管理,32個不用layout進行管理。結果會怎麼樣?
其實不會怎麼樣。qgridlayout 負責對它管理的widget呼叫setgeometry,而你負責對自己管理的呼叫setgeometry。想怎麼放就怎麼放。(但是你要注意:最好別讓它們重合,不然...)
qmainwindow 上面放置很多的widget:
選單欄qmenubar
這些全是qwidget的派生類
工具欄q*******
狀態列qstatusbar
停靠視窗
qdockwidget
中心窗體
...
其實沒有什麼神秘的,一堆widget放置到了qmainwindow中,而且還會自動隨著qmainwindow變化。你很容易想到它預設就已經設定了乙個qlayout!
class qmainwindowlayout : public qlayout這是乙個私有類,你不必關心細節,但是可以考慮:平時如何使用qlayout的?是不是要將你的widget加入到layout中??{ q_object
...
在qmainwindow中,qmenubar、q*******等等都已經加入到了它的layout中,而且layout中為你留了乙個位置,就是中心窗體。
在qmainwindow,qmainwindowlayout管理的這些子widget布滿了幾乎整個窗體。所以:有人抱怨
漫談QWidget及其派生類 二
本文接下來試圖看看 qlayout 與視窗的幾何尺寸控制。注意 本文只是試 釋,qlayout其實沒有任何神秘的東西,它所有的功能離開它你也都可以做。但這並不是鼓勵大家不使用qlayout。始終記住一點 要改變乙個widget的大小,只有move resize setgeometry 這3個東西可用...
漫談QWidget及其派生類 二
本文接下來試圖看看 qlayout 與視窗的幾何尺寸控制。注意 本文只是試 釋,qlayout其實沒有任何神秘的東西,它所有的功能離開它你也都可以做。但這並不是鼓勵大家不使用qlayout。始終記住一點 要改變乙個widget的大小,只有move resize setgeometry 這3個東西可用...
漫談QWidget及其派生類 二
本文接下來試圖看看 qlayout 與視窗的幾何尺寸控制。注意 本文只是試 釋,qlayout其實沒有任何神秘的東西,它所有的功能離開它你也都可以做。但這並不是鼓勵大家不使用qlayout。始終記住一點 要改變乙個widget的大小,只有move resize setgeometry 這3個東西可用...