簡述:
QWidget類是所有用戶界面對象的基類。
Widget是用戶界面的基本單元:它從窗口系統接收鼠標,鍵盤和其他事件,並在屏幕上繪制自己。
每個Widget都是矩形的,它們按照Z-order進行排序。
注:Z-order是重疊二維對象的順序,例如堆疊窗口管理器中的窗口。典型的GUI的特征之一是窗口可能重
疊,使得一個窗口隱藏另一個窗口的一部分或全部。 當兩個窗口重疊時,它們的Z順序確定哪個窗口出現在
另一個窗口的頂部。
理解:術語"z-order"指沿着z軸物體的順序。三維坐標軸中x橫軸,y數軸,z上下軸。可以將gui窗口視為平
行與顯示平面的一系列平面。因此,窗口沿着z軸堆疊。所以z-order指定了窗口的前后順序。就像你桌面上
的一堆紙一樣,每張紙是一個窗口,桌面是你的屏幕,最上面的窗口z值最高。
一個控件,沒有被嵌入父類控件,被稱為頂級窗口。一般情況下,窗口有一個框架和標題。可以創建沒
有框架和標題的窗口,通過合適的window flags。在qt中QMainWindow和QDialog及其子類是最常見的
窗口類型。
每一個widget的構造函數接收一個或兩個標准參數:
1.QWidget *parent = 0。如果是0(默認),新建的控件是一個頂級窗口。如果不是0,它將是一個子
窗口,受父窗口的幾何約束。(除非設置window flag為 Qt::Window)
2.Qt::WindowFlags f = 0 設置window flag。默認0,基本適合所有的窗口控件。但是如果沒有Qt窗口
系統,新建一個窗口必須使用特殊的flag。
QWidget有很多的成員函數,但是有些沒有作用。比如QWidget有一個font屬性,但是從不使用。
QWidget的一些子類,提供真的有作用的函數。比如 QLabel、QPushButton、QListWidget、
QTabWidget。
Top-Level and Child Widgets
沒有父窗口的控件總是一個獨立的窗口(頂級控件)。 對於這些小部件,setWindowTitle()和
setWindowIcon()分別設置標題欄和圖標。
非窗口控件是子窗口控件,顯示在其父窗口控件中。Qt中的大多數widget主要用作子窗口控件。例如,
可以將按鈕顯示為頂級窗口,但大多數人喜歡將按鈕放在其他widget,例如QDialog。
上圖顯示了一個QGroupBox控件,用於在QGridLayout提供的布局中保存各種子窗口控件。
如果要使用QWidget來容納子窗口控件,則通常需要向父級QWidget添加布局。 有關詳細信息,請
參閱布局管理。
Composite Widgets (組合控件)
當一個控件用作容器來組織一些子窗口控件時,它被稱為組合窗口小部件。例如上圖中的QGroupBox。這種組合控件,
一般是構造函數創建一個有視覺屬性的widget,比如QFrame。然后添加小控件,小控件用布局管理。
復合窗口小部件也可以通過子類化標准窗口小部件(如QWidget或QFrame)以及在子類的構造函數中添加必要的布局
和子窗口小部件來創建。 Qt提供的許多示例使用這種方法,它也在Qt教程中介紹。
Custom Widgets and Painting
由於QWidget是QPaintDevice的子類,因此QWidget的子類來可以使用QPainter類的實例進行一系列繪圖操作來顯示自
定義內容。
每個窗口小部件都在其paintEvent()函數內執行所有的繪畫操作。 每當需要重新繪制小部件時,無論是由於某些外部更
改還是應用程序請求,都會調用此操作。
Size Hints and Size Policies
實現新的widget時,重寫sizeHint()幾乎總是有用的,為窗口小部件提供合理的默認大小,並用setSizePolicy()
設置正確的大小策略。
默認情況下,復合窗口不提供size Hint,而是根據其子窗口小部件的空間要求進行調整大小。
SizePolicy允許您為布局管理系統提供良好的默認行為,以便其他小部件可以輕松地包含和管理您的內容。 默認
SizePolicy表示size Hint表示窗口小部件的首選大小,這對於許多窗口小部件通常是足夠好的。
注意:頂級小部件的大小限制在桌面的高度和寬度的2/3。 如果這些邊界不足,您可以手動調整()窗口小部件。
Event
窗口小部件響應通常由用戶操作引起的事件。 Qt傳遞事件給widget通過調用事件處理函數。事件處理函數的參數是一個
QEvent子實例。子實例告訴我們事件的基本信息。
如果您的窗口小部件僅包含子窗口小部件,則可能不需要實現任何事件處理程序(默認函數足夠)。 如果你想檢測一個
鼠標單擊在窗口中的一個子窗口事件:調用窗口的mousePressEvent()函數,mousePressEvent()函數中調用子窗口
的underMouse()函數。
您將需要為自己的小部件提供行為和內容,但以下是與QWidget相關的事件的簡要概述,以最常見的方式開始:
1.每當需要重繪時,都會調用paintEvent()。 自定義的窗口都必須實現這個函數。 使用QPainter繪制只能在
paintEvent()或paintEvent()調用的函數中進行。
2.當調整窗口部件大小時調用resizeEvent()。
3.當鼠標光標位於部件內部按下鼠標按鈕時,或當部件使用grabMouse()抓住鼠標時,將會調用mousePressEvent()。
按下鼠標而不釋放它與調用grabMouse()有相同的效果。
4.當鼠標按鈕被釋放時,mouseReleaseEvent()被調用。 當接收到相應的鼠標按壓事件時,部件同時接收鼠標釋放事件。
這意味着如果用戶在您的部件中按下鼠標,然后將鼠標拖動到其他位置,在釋放鼠標之前,部件將收到鼠標release事件。
有一個例外:如果在按住鼠標按鈕的同時出現彈出菜單,則此彈出菜單會立即竊取鼠標事件。
5.當用戶在窗口部件中雙擊時,會調用mouseDoubleClickEvent()。 如果用戶雙擊,該部件將接收鼠標按鍵事件,鼠標
釋放事件,最后是該事件,而不是第二個鼠標按下事件。 (如果在此操作期間鼠標未穩定,則還可能會接收到某些鼠標移動
事件。) 程序無法區分是不是DoubleClick事件,直到第二次鼠標點擊到達。
接受鍵盤輸入的部件需要重新實現更多的事件處理程序:
1.keyPressEvent()在按下一個鍵時被調用,並且當一個鍵被按下足夠長時間以使其自動重復時再次調用。 Tab和Shift鍵
都是qt焦點機制的關鍵字。如果要強制這些鍵由您的部件處理,您必須重新實現QWidget :: event()。
2.當控件獲得鍵盤的焦點時(調用setFocusPolicy()使控件獲得焦點),調用focusInEvent()。表現良好的部件表明他
們以清晰而謹慎的方式擁有鍵盤焦點。
3.當部件失去鍵盤焦點時,調用focusOutEvent()。
您可能需要重新實現一些較不常見的事件處理程序:
1.只要按住鼠標按鈕並拖動鼠標就會調用mouseMoveEvent()。 這在拖放操作中可能很有用。
如果您調用setMouseTracking(true),即使沒有按鈕被按下,您也可以獲取鼠標移動事件。
2.keyReleaseEvent()每當一個鍵按下時被釋放時調用。(如果該鍵是自動重復的),在這種情況下,部件將為每次重復
接收一對密鑰釋放和按鍵事件。
3.當控件有焦點,並滾動鼠標上的滑輪時,wheelEvent()事件被調用。
4.當鼠標進入窗口部件的屏幕空間時,將調用enterEvent()。這不包括任何部件的子類擁有的屏幕空間。
5.當鼠標離開窗口部件的屏幕空間時,將調用leaveEvent()。 如果鼠標進入一個部件,它不會導致leaveEvent()。
6.當部件移動到其父項時,將調用moveEvent()。
7.當用戶關閉窗口部件時調用closeEvent()(或者調用close()時)。
在QEvent :: Type的文檔中也有一些相當模糊的事件。 要處理這些事件,您需要直接重新實現event()。
event()的默認實現處理Tab和Shift + Tab(移動鍵盤焦點),並將大多數其他事件傳遞給上面更專業
的處理程序處理。
事件系統中涵蓋了事件和用於傳遞的機制。
Groups of Functions and Properties
Widget Style Sheets
除了每個平台的標准窗口部件樣式外,窗口部件也可以根據樣式表中指定的規則進行樣式化。 此功能使您能夠自定義特定部件的外觀,以向用戶提供有關其目的的視覺提示。 例如,可以以特定方式對按鈕進行風格化以指示其執行破壞性動作。
Qt樣式表文檔中更詳細地描述了窗口部件樣式表的使用。
Transparency and Double Buffering(透明度和雙緩沖)
自Qt 4.0起,QWidget自動對其繪制進行雙緩沖,因此不需要在paintEvent()中寫入雙緩沖代碼,以避免閃爍。
自Qt 4.1起,Qt::WA_ContentsPropagated 屬性已被棄用。只要沒有設置Qt::WA_PaintOnScreen,默認情況下,父窗口部件的內容將傳播給每個子項。自定義的控件可以利用這個特征,更新不規則區域(創建非矩形窗口部件),或使用顏色少於alpha組件來繪制自定義控件。下圖顯示了如何通過微調自定義窗口部件的屬性來實現不同的效果。
在上圖中,構造了一個具有半透明矩形子窗小部件,並將其添加到父窗口小部件(QLabel顯示為像素圖)。 然后,設置不同的屬性和部件屬性來實現不同的效果:
1.左窗口部件沒有設置其他屬性或窗口部件屬性。 這種默認狀態適用於大多數自定義小部件使用透明度,不規則形狀,或者不用不透明的畫筆在整個區域上繪制。
2.中心部件具有autoFillBackground屬性集。 此屬性用於依靠窗口部件提供默認背景的自定義窗口小部件,並且不要使用不透明的畫筆在其整個區域上繪制。
3.屬性組件具有Qt::WA_OpaquePaintEvent部件屬性集。 這表示窗口部件將用不透明的顏色在其整個區域上繪制。 窗口部件的區域最初將初始化,在圖中表示為紅色對角網格圖案,通過覆蓋區域發光。 Qt :: WA_OpaquePaintArea屬性對於需要快速繪制自己的專用內容並且不需要默認填充背景的小部件很有用。
要使用簡單的背景顏色(如實時繪圖或繪圖部件)快速更新自定義小部件,最好選擇合適的背景顏色(使用setBackgroundRole()和 QPalette::Window角色),設置autoFillBackground屬性,並且只能在窗口小部件的paintEvent()中實現必要的繪圖功能。
要快速更新使用不透明內容(例如視頻流部件),最好設置部件的Qt :: WA_OpaquePaintEvent,以避免與重新繪制部件背景相關的任何不必要的開銷。
如果窗口小部件同時具有Qt :: WA_OpaquePaintEvent部件屬性和autoFillBackground屬性集,則Qt :: WA_OpaquePaintEvent屬性優先。 根據您的要求,您應該選擇其中之一。
由於Qt 4.1,父窗口部件的內容也被傳播到標准的Qt窗口部件。 如果父窗口小部件以非標准方式進行裝飾,則可能會導致一些意外的結果,如下圖所示。