#(12):菜單欄、工具欄和狀態欄
在之前的《[添加動作](http://www.devbean.net/2012/08/qt-study-road-2-action/)》一文中,我們已經了解了,Qt 將用戶與界面進行交互的元素抽象為一種“動作”,使用`QAction`類表示。`QAction`可以添加到菜單上、工具欄上。期間,我們還詳細介紹了一些細節問題,比如資源文件的使用、對象模型以及布局管理器。這一節則是詳細介紹關于菜單欄、工具欄以及狀態欄的相關內容。
我們假設窗口還是建立在`QMainWindow`類之上,這會讓我們的開發簡單許多。當然,在實際開發過程中,`QMainWindow`通常只作為“主窗口”,對話框窗口則更多地使用`QDialog`類。我們會在后面看到,`QDialog`類會缺少一些`QMainWindow`類提供方便的函數,比如`menuBar()`以及`toolBar()`。
下面還是回到《[添加動作](http://www.devbean.net/2012/08/qt-study-road-2-action/)》一文中的代碼片段:
~~~
openAction = new QAction(QIcon(":/images/doc-open"), tr("&Open..."), this);
openAction->setShortcuts(QKeySequence::Open);
openAction->setStatusTip(tr("Open an existing file"));
connect(openAction, &QAction::triggered, this, MainWindow::open);
QMenu *file = menuBar()->addMenu(tr("&File"));
file->addAction(openAction);
QToolBar *toolBar = addToolBar(tr("&File"));
toolBar->addAction(openAction);
~~~
我們看到,使用`menuBar()`函數,Qt 為我們創建了一個菜單欄。`menuBar()`是`QMainWindow`提供的函數,因此你是不會在`QWidget`或者`QDialog`中找到它的。這個函數會返回窗口的菜單欄,如果沒有菜單欄則會新創建一個。這也就解釋了,為什么我們可以直接使用`menuBar()`函數的返回值,畢竟我們并沒有創建一個菜單欄對象啊!原來,這就是`menuBar()`為我們創建好并且返回了的。
Qt 中,表示菜單的類是`QMenuBar`(你應該已經想到這個名字了)。`QMenuBar`代表的是窗口最上方的一條菜單欄。我們使用其`addMenu()`函數為其添加菜單。盡管我們只是提供了一個字符串作為參數,但是 Qt 為將其作為新創建的菜單的文本顯示出來。至于 & 符號,我們已經解釋過,這可以為菜單創建一個快捷鍵。當我們創建出來了菜單對象時,就可以把`QAction`添加到這個菜單上面,也就是`addAction()`函數的作用。
下面的`QToolBar`部分非常類似。顧名思義,`QToolBar`就是工具欄。我們使用的是`addToolBar()`函數添加新的工具欄。為什么前面一個是`menuBar()`而現在的是`addToolBar()`呢?因為一個窗口只有一個菜單欄,但是卻可能有多個工具欄。如果我們將代碼修改一下:
~~~
QToolBar *toolBar = addToolBar(tr("&File"));
toolBar->addAction(openAction);
QToolBar *toolBar2 = addToolBar(tr("Tool Bar 2"));
toolBar2->addAction(openAction);
~~~
我們看到,現在有兩個工具欄了:
[](http://files.devbean.net/images/2012/09/qtoolbar-2.png)
工具欄可以設置成固定的、浮動的等等,具體設置可以參考 Qt 文檔。
前面我們說過,使用`QAction::setStatusTip()`可以設置該動作在狀態欄上的提示文本。但我們現在把鼠標放在按鈕上,是看不到這個提示文本的。原因很簡單,我們沒有添加一個狀態欄。怎么添加呢?類似前面的`QMainWindow::menuBar()`,`QMainWindow`有一個`statusBar()`函數。讓我們把這個函數添加上去:
~~~
QToolBar *toolBar2 = addToolBar(tr("Tool Bar 2"));
toolBar2->addAction(openAction);
statusBar();
~~~
然后編譯運行一下:
[](http://files.devbean.net/images/2012/09/statusbar.png)
我們添加了一個孤零零的`statuBar()`顯得不倫不類,但是,同前面的`menuBar()`的實現類似,這個函數會返回一個`QStatusBar`對象,如果沒有則先創建再返回。
`QStatusBar`繼承了`QWidget`,因此,我們可以將其它任意`QWidget`子類添加到狀態欄,從而實現類似 Photoshop 窗口底部那種有比例顯示、有網格開關的復雜狀態欄。有關`QStatusBar`的更多信息,請參考 Qt 文檔。
對于沒有這些函數的`QDialog`或者`QWidget`怎么做呢?要記得,`QToolBar`以及`QStatusBar`都是`QWidget`的子類,因此我們就可以將其結合布局管理器添加到另外的`QWidget`上面。`QLayout`布局提供了`setMenuBar()`函數,可以方便的添加菜單欄。具體細節還是詳見文檔。
至此,我們已經將組成窗口元素介紹過一遍。結合這些元素以及布局管理,我們就應該可以實現一個簡單的通用的窗口。當我們完成窗口布局之后,我們就可以考慮向其中添加功能。這就是我們后面章節的內容。
- (1)序
- (2)Qt 簡介
- (3)Hello, world!
- (4)信號槽
- (5)自定義信號槽
- (6)Qt 模塊簡介
- (7)MainWindow 簡介
- (8)添加動作
- (9)資源文件
- (10)對象模型
- (11)布局管理器
- (12)菜單欄、工具欄和狀態欄
- (13)對話框簡介
- (14)對話框數據傳遞
- (15)標準對話框 QMessageBox
- (16)深入 Qt5 信號槽新語法
- (17)文件對話框
- (18)事件
- (19)事件的接受與忽略
- (21)事件過濾器
- (22)事件總結
- (23)自定義事件
- (24)Qt 繪制系統簡介
- (25)畫刷和畫筆
- (26)反走樣
- (27)漸變
- (28)坐標系統
- (29)繪制設備
- (30)Graphics View Framework
- (31)貪吃蛇游戲(1)
- (32)貪吃蛇游戲(2)
- (33)貪吃蛇游戲(3)
- (34)貪吃蛇游戲(4)
- (35)文件
- (36)二進制文件讀寫
- (37)文本文件讀寫
- (38)存儲容器
- (39)遍歷容器
- (40)隱式數據共享
- (41)model/view 架構
- (42)QListWidget、QTreeWidget 和 QTableWidget
- (43)QStringListModel
- (44)QFileSystemModel
- (45)模型
- (46)視圖和委托
- (47)視圖選擇
- (48)QSortFilterProxyModel
- (49)自定義只讀模型
- (50)自定義可編輯模型
- (51)布爾表達式樹模型
- (52)使用拖放
- (53)自定義拖放數據
- (54)剪貼板
- (55)數據庫操作
- (56)使用模型操作數據庫
- (57)可視化顯示數據庫數據
- (58)編輯數據庫外鍵
- (59)使用流處理 XML
- (60)使用 DOM 處理 XML
- (61)使用 SAX 處理 XML
- (62)保存 XML
- (63)使用 QJson 處理 JSON
- (64)使用 QJsonDocument 處理 JSON
- (65)訪問網絡(1)
- (66)訪問網絡(2)
- (67)訪問網絡(3)
- (68)訪問網絡(4)
- (69)進程
- (70)進程間通信
- (71)線程簡介
- (72)線程和事件循環
- (73)Qt 線程相關類
- (74)線程和 QObject
- (75)線程總結
- (76)QML 和 QtQuick 2
- (77)QML 語法
- (78)QML 基本元素
- (79)QML 組件
- (80)定位器
- (81)元素布局
- (82)輸入元素
- (83)Qt Quick Controls
- (84)Repeater
- (85)動態視圖
- (86)視圖代理
- (87)模型-視圖高級技術
- (88)Canvas
- (89)Canvas(續)