目录
1、菜单栏QMenuBar
1.1 使用QMainWindow的准备工作
1.2 在ui文件中设计窗口
1.3 在代码中设计窗口
1.4 实现点击菜单项的反馈
1.5 菜单中设置快捷键
1.6 菜单中添加子菜单
1.7 菜单项中添加分割线和图标
1.8 关于菜单栏创建方式的讨论
2、工具栏QToolBar
2.1 创建工具栏
2.2 设置工具项图标
2.3 设置工具栏的停靠位置
2.4 设置浮动、移动属性
3、状态栏QStatusBar
3.1 显示临时消息
3.2 显示永久消息
4、浮动窗口QDockWidget
4.1 设置停靠位置
结语
前言:
Qt的窗口界面是通过QMainWindow类实现的,该类继承自QWidget。相比于QWidget,QMainWindow生成的界面更像是一个窗口,因为该界面的布局已经设置好了,分成五个部分:1、⼀个菜单栏(menu bar),2、多个工具栏(tool bars),3、多个浮动窗⼝(dock widgets),4、⼀个状态栏(status bar) ,5、 中心部件(central widget)。开发者只需要在这框架中加入相关控件就能构建出一个窗口了。QMainWindow窗口界面示意图如下:
由于中心部件就是QWidget控件本身,而QWidget的作用就是接纳各种控件,本质上和新建一个QWidget项目的使用逻辑是一样的(关于QWidget请看:Qt_QWidget的基本使用),因此下文就不再描述中心部件的使用了。
1、菜单栏QMenuBar
Qt中的菜单栏是通过QMenuBar类来实现的,⼀个主窗⼝最多只有⼀个菜单栏,位于窗口标题栏下⾯。其中菜单栏中可以有多个菜单,而菜单下可以有多个项目,当然菜单里也可以有子菜单,他们的关系如下图:
菜单栏的类是QMenuBar,菜单的类是QMenu,菜单项的类是QAction(此处菜单项实际上就是一个项目,只不过该项目在菜单中,因此叫做菜单项)。
1.1 使用QMainWindow的准备工作
在使用QMainWindow前,必须要在Qt创建QMainWindow项目,步骤很简单,在新建项目后选择界面类的信息时选择QMainWindow即可,如下图:
后续一直点击下一步就能够自动生成相关文件和代码,如下图:
关于这里的代码和文件的含义可以移步至此处了解:Qt中QWidget的创建和使用,此处的代码和文件只不过将QWidget换成了QMainWindow,使用原则都是一样的。
1.2 在ui文件中设计窗口
可以在ui文件中对QMainWindow做一些设计,这种方式简单明了,能够直接观察出效果,效果图如下:
运行结果:
1.3 在代码中设计窗口
除了直接在ui文件中设计窗口,还可以用代码的形式来设计窗口,首先new一个QMenuBar,然后将该QMenuBar通过调用setMenuBar接口设置到当前的窗口中,在MainWindow.cpp下实现代码,代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMenuBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建菜单栏
QMenuBar* menubar = new QMenuBar(this);
this->setMenuBar(menubar);//设置到当前的窗口中
//添加菜单,菜单的类是QMenu
QMenu* menu1 = new QMenu("保存",this);
QMenu* menu2= new QMenu("编辑",this);
menubar->addMenu(menu1);
menubar->addMenu(menu2);
//添加项目至菜单中
QAction* action1 = new QAction("菜单项1");
QAction* action2 = new QAction("菜单项2");
menu1->addAction(action1);
menu1->addAction(action2);
}
MainWindow::~MainWindow()
{
delete ui;
}
运行结果:
1.4 实现点击菜单项的反馈
在正常的窗口使用中,往往是点击一个菜单项后会得到相应的反馈,这需要绑定菜单项的信号与槽,这里简单的模拟该反馈,代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMenuBar>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建菜单栏
QMenuBar* menubar = new QMenuBar(this);
this->setMenuBar(menubar);
//添加菜单,菜单的类是QMenu
QMenu* menu1 = new QMenu("保存",this);
QMenu* menu2= new QMenu("编辑",this);
menubar->addMenu(menu1);
menubar->addMenu(menu2);
//添加项目至菜单中
QAction* action1 = new QAction("菜单项1");
QAction* action2 = new QAction("菜单项2");
menu1->addAction(action1);
menu1->addAction(action2);
//实现菜单项的信号,在MainWindow.h头文件中声明了QAction_tri函数
connect(action1,&QAction::triggered,this,&MainWindow::QAction_tri);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::QAction_tri()
{
qDebug()<<"实现菜单项1的功能";
}
运行结果:
1.5 菜单中设置快捷键
给菜单以及菜单项设置快捷键(通过&+“字母”的方式),并通过键盘上的Alt+“字母”点击菜单项,代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMenuBar>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建菜单栏
QMenuBar* menubar = new QMenuBar(this);
this->setMenuBar(menubar);
//添加菜单,菜单的类是QMenu
QMenu* menu1 = new QMenu("保存 (&A)",this);
QMenu* menu2= new QMenu("编辑 (&F)",this);
menubar->addMenu(menu1);
menubar->addMenu(menu2);
//添加项目至菜单中
QAction* action1 = new QAction("菜单项1 (&C)");
QAction* action2 = new QAction("菜单项2 (&B)");
menu1->addAction(action1);
menu1->addAction(action2);
//实现菜单项的信号
connect(action1,&QAction::triggered,this,&MainWindow::QAction_tri);
connect(action2,&QAction::triggered,this,&MainWindow::QAction_tri2);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::QAction_tri()
{
qDebug()<<"实现菜单项1的功能";
}
void MainWindow::QAction_tri2()
{
qDebug()<<"实现菜单项2的功能";
}
运行结果:
1.6 菜单中添加子菜单
菜单里除了可以有菜单项,还可以存放子菜单,在上述构造函数代码中添加代码:
//子菜单
QMenu* menu_child= new QMenu("子菜单",this);
menu1->addMenu(menu_child);
//子菜单添加项目
menu_child->addAction(action1);
运行结果:
1.7 菜单项中添加分割线和图标
可以给菜单项添加分割线来区别彼此,添加分割线的代码很简单,让菜单调用addSeparator函数即可,不过添加分割线一定会在该菜单的末尾处添加,因此要注意添加顺序,代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMenuBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建菜单栏
QMenuBar* menubar = new QMenuBar(this);
this->setMenuBar(menubar);
//添加菜单,菜单的类是QMenu
QMenu* menu1 = new QMenu("保存 (&A)",this);
QMenu* menu2= new QMenu("编辑 (&F)",this);
menubar->addMenu(menu1);
menubar->addMenu(menu2);
//添加项目至菜单中
QAction* action1 = new QAction("菜单项1 (&C)");
QAction* action2 = new QAction("菜单项2 (&B)");
menu1->addAction(action1);
menu1->addSeparator();//添加分割线
menu1->addAction(action2);
}
MainWindow::~MainWindow()
{
delete ui;
}
运行结果:
调用添加图标的接口setIcon即可完成图标的添加,不仅菜单项能够添加,菜单本身也可以添加,具体添加图标的细节请看Qt_控件的QWidget属性介绍,代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMenuBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建菜单栏
QMenuBar* menubar = new QMenuBar(this);
this->setMenuBar(menubar);
//添加菜单,菜单的类是QMenu
QMenu* menu1 = new QMenu("保存 (&A)",this);
QMenu* menu2= new QMenu("编辑 (&F)",this);
menubar->addMenu(menu1);
menubar->addMenu(menu2);
//添加项目至菜单中
QAction* action1 = new QAction("菜单项1 (&C)");
QAction* action2 = new QAction("菜单项2 (&B)");
menu1->addAction(action1);
menu1->addSeparator();//添加分割线
menu1->addAction(action2);
//添加图片
action1->setIcon(QIcon(QPixmap(":/action1")));
action2->setIcon(QIcon(QPixmap(":/action2")));
}
MainWindow::~MainWindow()
{
delete ui;
}
运行结果:
1.8 关于菜单栏创建方式的讨论
我们可以在ui文件的右上角看到关于QMainWindow的初始化状况:
上述代码中使用菜单栏的方式是new一个QMenuBar,然后将该QMenuBar设置到当前窗口中。这么做会导致内存泄漏,因为在创建QMainWindow时,Qt会自动生成了一个QMenuBar,若我们自己再new一个QMenuBar,并对其调用setMenuBar接口,那么会导致旧的QMenuBar脱离Qt对象树,即旧的QMenuBar无法自动释放了从而导致内存泄漏。
所以使用菜单栏QMenuBar时,推荐的做法是调用函数menuBar,该函数的作用是:1、如果QMenuBar已经存在,直接获取并返回。2、如果QMenuBar不存在,则会自动new一个新的,然后返回new出来的菜单栏。
因此上述代码中创建菜单栏的推荐的代码为:
//创建菜单栏
//QMenuBar* menubar = new QMenuBar(this);
QMenuBar* menubar = this->menuBar();
this->setMenuBar(menubar);
恒古不变的是都要调用setMenuBar将菜单栏设置到当前界面。
2、工具栏QToolBar
工具栏跟菜单栏不一样,菜单栏是QMainWindow默认就有的,而工具栏是必须需要我们手动new的,并且菜单栏只能有一个,而工具栏可以有多个,并且工具栏默认是可以用鼠标拖动的。工具栏里存放的直接就是项目QAction,目的就是方便用户快速使用某个功能,通常这些项目以图标的形式存在。工具栏实物图如下:
2.1 创建工具栏
先手动new出工具栏对象QToolBar,然后调用QMainWindow的addToolBar函数,将new出的对象作为该函数的实参,完成工具栏的创建和显示,并在工具栏中创建工具项,代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QToolBar>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建工具栏
QToolBar* toolbar = new QToolBar(this);
this->addToolBar(toolbar);
//创建工具项
QAction* action1 = new QAction("文件");
QAction* action2 = new QAction("编辑");
toolbar->addAction(action1);
toolbar->addAction(action2);
//连接工具项的信号与槽
connect(action1,&QAction::triggered,this,&MainWindow::action2_tri1);
connect(action2,&QAction::triggered,this,&MainWindow::action2_tri2);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::action2_tri1()
{
qDebug()<<"文件";
}
void MainWindow::action2_tri2()
{
qDebug()<<"编辑";
}
运行结果:
2.2 设置工具项图标
设置图标的逻辑和上述给菜单项设置图标的逻辑是一样的,只需要用工具项调用函数setIcon即可,不过对工具项设置图标后,会覆盖原先的文本内容,将原先的文本内容以鼠标停悬时的提示信息显示出来,代码如下:
//设置图标
action1->setIcon(QIcon(":/action1"));
action2->setIcon(QIcon(":/action2"));
运行结果:
也可以通过调用函数setToolTip自定义提示信息,代码如下:
//设置图标
action1->setIcon(QIcon(":/action1"));
//设置提示信息
action1->setToolTip("这是一个文件");
action2->setIcon(QIcon(":/action2"));
运行结果:
2.3 设置工具栏的停靠位置
工具栏默认停靠位置是在窗口的上方,位置设置有两个概念。⼀个是在添加⼯具栏调用addToolBar()的同时指定停靠的位置,另⼀种是在创建之后调用QToolBar类提供的setAllowedAreas()函数来设置允许停靠的位置。可以设置的位置如下:
• Qt::LeftToolBarArea 停靠在左侧
• Qt::RightToolBarArea 停靠在右侧
• Qt::TopToolBarArea 停靠在顶部
• Qt::BottomToolBarArea 停靠在底部
• Qt::AllToolBarAreas 以上四个位置都可停靠
概念一,设置工具栏的初始位置,代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QToolBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建工具栏
QToolBar* toolbar1 = new QToolBar(this);
this->addToolBar(Qt::LeftToolBarArea,toolbar1);
QToolBar* toolbar2 = new QToolBar(this);
this->addToolBar(Qt::RightToolBarArea,toolbar2);
}
MainWindow::~MainWindow()
{
delete ui;
}
运行结果:
概念二,后续使用setAllowedAreas函数来设置允许停靠的位置,代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QToolBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建工具栏
QToolBar* toolbar1 = new QToolBar(this);
this->addToolBar(toolbar1);
QToolBar* toolbar2 = new QToolBar(this);
this->addToolBar(toolbar2);
//只允许toolbar1停靠在左边,但是初始位置依然是在上方
toolbar1->setAllowedAreas(Qt::LeftToolBarArea);
//只允许toolbar1停靠在右边,但是初始位置依然是在上方
toolbar2->setAllowedAreas(Qt::RightToolBarArea);
}
MainWindow::~MainWindow()
{
delete ui;
}
工具栏是可以拖动的,默认情况下工具栏可以停靠在上下左右四个位置,如果调用了setAllowedAreas,则说明工具栏的停靠位置受setAllowedAreas函数的限制了。
2.4 设置浮动、移动属性
通过调用函数setFloatable来设置工具栏的浮动属性,默认运行工具栏可以浮动,若调用setFloatable并传false则不允许浮动工具栏,代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QToolBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建工具栏
QToolBar* toolbar1 = new QToolBar(this);
this->addToolBar(toolbar1);
//设置项目,方便观察运行效果
QAction* action = new QAction("文件");
toolbar1->addAction(action);
//设置不可浮动
toolbar1->setFloatable(false);
}
MainWindow::~MainWindow()
{
delete ui;
}
运行结果:
此时工具栏虽然可以被移动,但是不能浮动在界面中的任意位置,只要鼠标松开,工具栏就会自动恢复到之前的位置。
设置移动属性的逻辑和上述一样,通过QToolBar类提供的setMovable()函数来设置,默认可以移动,传false则不能移动。当工具栏不能移动时,意味着工具栏也不能浮动,并且工具栏的停靠位置也就无法改变了。代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QToolBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建工具栏
QToolBar* toolbar1 = new QToolBar(this);
this->addToolBar(toolbar1);
//设置项目,方便观察运行效果
QAction* action = new QAction("文件");
toolbar1->addAction(action);
//设置不可浮动
toolbar1->setFloatable(false);
//设置不可移动
toolbar1->setMovable(false);
}
MainWindow::~MainWindow()
{
delete ui;
}
运行结果:
3、状态栏QStatusBar
状态栏是界面中输出简要信息的区域,⼀般位于主窗口的最底部,⼀个窗口中最多只能有⼀个状态栏。在Qt中,状态栏是通过QStatusBar类来实现的。在状态栏中可以显示的消息类型有:
• 临时消息:如当前程序状态
• 永久消息:如程序版本号
• 进度消息:如进度条提示
并且状态栏是QMainWindow中默认存在的,因此创建状态栏是无需用new的方式,而是调用statusBar()函数获取默认的状态栏。
3.1 显示临时消息
调用函数showMessage来设置一个临时消息, 代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStatusBar* status = statusBar();
status->showMessage("这是一个临时消息",3000);//3000ms = 3s
}
MainWindow::~MainWindow()
{
delete ui;
}
运行结果:
该信息会在3秒后消失。
3.2 显示永久消息
通过在状态栏中添加标签的方式来实现显示永久消息,因为标签中的文本内容是永久性的,代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStatusBar* status = statusBar();
//status->showMessage("这是一个临时消息",3000);//3000ms = 3s
QLabel* label = new QLabel("这是一个永久消息");
status->addWidget(label);
//在状态栏右侧显示
QLabel* label1 = new QLabel("这是一个右侧消息");
status->addPermanentWidget(label1);
}
MainWindow::~MainWindow()
{
delete ui;
}
运行结果:
4、浮动窗口QDockWidget
有了上述浮动属性的概念,浮动窗口也就不难理解,他是一个窗口并且可以浮动在界面中的任意位置,并且也可以停靠在窗口四周。他的类是QDockWidget ,由于他不是QMainWindow默认就有的控件,因此需要我们手动new出来,然后调用addDockWidget函数将其置于当前窗口中。代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDockWidget>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDockWidget* dock = new QDockWidget(this);
addDockWidget(Qt::BottomDockWidgetArea,dock);//设置初始在底部
}
MainWindow::~MainWindow()
{
delete ui;
}
运行结果:
4.1 设置停靠位置
这里的设置允许停靠的逻辑和工具栏的逻辑是一样的,也通过setAllowedAreas来进行设置,允许停靠的位置有:
• Qt::LeftDockWidgetArea 停靠在左侧
• Qt::RightDockWidgetArea 停靠在右侧
• Qt::TopDockWidgetArea 停靠在顶部
• Qt::BottomDockWidgetArea 停靠在底部
• Qt::AllDockWidgetAreas 以上四个位置都可停靠
设置完成后,则浮动窗口只能在对应位置处停靠。
结语
以上就是关于Qt窗口界面QMainWindow的介绍,QMainWindow相比于QWidget多了四个控件,这些控件都是组成窗口的重要部分,而且在实际运用中,窗口界面才是被运用的最多的,所以理解这四个控件尤为重要。
最后如果本文有遗漏或者有误的地方欢迎大家在评论区补充,谢谢大家!!