目錄
一、窗口預覽
二、菜單欄
快捷鍵
子菜單
分割線
圖標
內存泄露
一、窗口預覽
在前面幾篇文章中,或者說,Qt初學階段,接觸到的都是QWidget,QWidget指控件,往往作為一個窗口的一部分出現。所謂的窗口,形象的說,就是在Qt Creator中創建項目時,可選項目類型中的MainWindow
Qt的窗口,是通過QMainWindow類實現,繼承自QWidget。
下圖為QMainWindow中各個部分所在位置。
Menu Bar,粗略的理解。
Tool Bar Area,往往是菜單欄中常用的工具,比如XShell
Dock Widget Area
二、菜單欄
一個窗口只能有一個菜單欄(QMenuBar),一個菜單欄可以有多個菜單(QMenu),一個菜單往往會有多個菜單項(QAction),之所以命名為QAction,是因為工具欄中的多數操作也是菜單欄的快捷方式,統一稱QAction。
- 代碼實踐
圖形化創建菜單很簡單,這里不再演示。
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QMenuBar* menuBar = new QMenuBar(this);//設置窗口有一個菜單欄this->setMenuBar(menuBar);//菜單QMenu* menu1= new QMenu("文件");QMenu* menu2= new QMenu("編輯");QMenu* menu3= new QMenu("視圖");QMenu* menu4= new QMenu("關于");//菜單欄中加菜單menuBar->addMenu(menu1);menuBar->addMenu(menu2);menuBar->addMenu(menu3);menuBar->addMenu(menu4);//設置菜單項QAction* action1 = new QAction("新建");QAction* action2 = new QAction("打開");QAction* action3 = new QAction("關閉");menu1->addAction(action1);menu1->addAction(action2);menu1->addAction(action3);//菜單項的點擊是一個信號,名為觸發信號connect(action1,&QAction::triggered,this,&MainWindow::handle_create);connect(action2,&QAction::triggered,this,&MainWindow::handle_open);connect(action3,&QAction::triggered,this,&MainWindow::close);}
void MainWindow::handle_create()
{qDebug() << "新建";
}void MainWindow::handle_open()
{qDebug() << "打開";
}
快捷鍵
有一種很簡單的方式,像下面這樣寫,比如&F 就等于 添加了Alt + F這樣的快捷鍵。
QMenu* menu1= new QMenu("文件 (&F)");QMenu* menu2= new QMenu("編輯 (&E)");QMenu* menu3= new QMenu("視圖 (&V)");QMenu* menu4= new QMenu("關于 (&A)");
- QAction綁定快捷鍵
QAction綁定方式也可以效仿上面那樣。
QAction* action1 = new QAction("新建(&C)");QAction* action2 = new QAction("打開(&O)");QAction* action3 = new QAction("關閉(&Q)");
運行程序,按下 Alt + F 、C
子菜單
//添加子菜單QMenu* menuChild = new QMenu("子菜單");menu1->addMenu(menuChild);//給子菜單添加菜單項QAction* actionChild = new QAction("菜單項");menuChild->addAction(actionChild);
分割線
menu1->addAction(action1);menu1->addSeparator();menu1->addAction(action2);menu1->addSeparator();menu1->addAction(action3);
圖標
QAction* action1 = new QAction("新建(&C)");action1->setIcon(QIcon(":/create.jpg"));
也可以給菜單設置圖標,只不過QMenu的圖標會覆蓋文本,而子菜單的圖片和文本可以共存。
內存泄露
在上述代碼實踐中,造成了內存泄露。原因是QMainWindow下,Qt的ui文件會自動生成一個QMenuBar。
而代碼中我們是new了一個新的MenuBar,又因為一個窗口只能有一個MenuBar,導致自動生成的MenuBar被new出來的替換,脫離了對象樹,造成內存泄露。
解決的辦法很簡單,保留一個即可,我們在代碼中不再new一個新的,而是使用本來就有的。
//QMenuBar* menuBar = new QMenuBar(this);QMenuBar* menuBar = this->menuBar();
這種寫法,如果menuBar存在,則直接獲取。如果不存在,則新創建一個。