目录
一、窗口预览
在前面几篇文章中,或者说,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存在,则直接获取。如果不存在,则新创建一个。