天天看點

QWidget,QMainWindow和QDialog的差別

在建立Qt Gui Application時,總會讓你選擇在QWidget,QMainWindow和QDialog中選擇一個Base Class。

這三個類具體有什麼差別呢?在Qt的手冊和網上找了一些資料。

先看官方的手冊:

QWidget Class Reference

The QWidget class is the base class of all user interface objects. 

Inherits: QObject and QPaintDevice.

Inherited by: ……, QDialog, ……,QMainWindow, ……

QDialog Class Reference

The QDialog class is the base class of dialog windows.

Inherits: QWidget.

QMainWindow Class Reference

The QMainWindow class provides a main application window.

Inherits: QWidget.

可以看到QMainWindow和QDialog都是繼承自QWidget。再看看下面那段從網上轉過來的介紹,大概就能了解三者之間的差別了。

QWidget類是所有使用者界面對象的基類。 視窗部件是使用者界面的一個原子:它從視窗系統接收滑鼠、鍵盤和其它事件,并且在螢幕上繪制自己的表現。每一個視窗部件都是矩形,并且它們按Z軸順序排列的。一個視窗部件可以被它的父視窗部件或者它前面的視窗部件蓋住一部分。

QMainWindow 類提供一個有菜單條、錨接視窗(例如工具條)和一個狀态條的主應用程式視窗。主視窗通常用在提供一個大的中央視窗部件(例如文本編輯或者繪制畫布)以及周圍菜單、工具條和一個狀态條。QMainWindow常常被繼承,因為這使得封裝中央部件、菜單和工具條以及視窗狀态變得更容易。繼承使建立當使用者點選菜單項或者工具條按鈕時被調用的槽成為可能。你也可以使用Qt設計器來建立主視窗。

QDialog類是對話框視窗的基類。對話框視窗是主要用于短期任務以及和使用者進行簡要通訊的頂級視窗。QDialog可以是模式的也可以是非模式的。QDialog支援擴充性并且可以提供傳回值。它們可以有預設按鈕。QDialog也可以有一個QSizeGrip在它的右下角,使用setSizeGripEnabled()。

QDialog 是最普通的頂級視窗。不被嵌入到一個父視窗部件的視窗部件被叫做頂級視窗部件。通常情況下,頂級視窗部件是有架構和标題欄的視窗(盡管如果使用了一定的視窗部件标記,建立頂級視窗部件時也可能沒有這些裝飾。)在Qt中,QMainWindow和和不同的QDialog的子類是最普通的頂級視窗。

如果是頂級對話框,那就基于QDialog建立,如果是主窗體,那就基于QMainWindow,如果不确定,或者有可能作為頂級窗體,或有可能嵌入到其他窗體中,則基于QWidget建立。當然了,實際中,你還可以基于任何其他部件類來派生。看實際需求了,比如QFrame、QStackedWidget等等。

我以前給QWidget或者QDialog設定布局的時候方式很簡單。建立好一個布局:mainLayout,然後不停地把各個控件往mainLayout裡面放,最後調用setLayout(mainLayout)就行了。

錯誤提示:…Which already has a layout

可是今天在QMainWindow中使用這個方法的時候卻不管用。

當時我也建立了一個mainLayout,再建立了一個QTreeWidget, 我吧QTreeWidget設定為centralWidget,然後把其他的控件有規律地放入mainLayout中,再調用setLayout(mainLayout),結果出錯了。

編譯的時候提示

QWidget::setLayout: Attempting to set QLayout "" on MainWindow "", which already has a layout
      

這句話的意思是說,你已經給MainWindow設定過一個布局了,再設定一個會出錯。

該如何給QMainWindow正确地設定布局呢

要想QMainWidget建立布局,合理的步驟應該是這樣的:

第一步建立一個QWidget執行個體,并将這個執行個體設定為centralWidget:

QWidget   *widget   =   new  QWidget ( ) ;

this - >setCentralWidget (widget ) ;

然後建立一個主布局mainLayout,并把所需要的所有控件都往裡面放(工具欄、菜單欄、狀态欄除外):

QHBoxLayout   *mainLayout   =   new  QHBoxLayout ;

mainLayout - >addWidget (... ) ;

mainLayout - >addLayout (... ) ;

...

最一步就是将widget的布局設定為mainLayout:

centralWidget()->setLayout(mainLayout);

//centralWidget()傳回的是第一步建立的那個QWidget執行個體 Posted in: C/C++  ⋅  Tagged: QT, 布局

繼續閱讀