文章目录
Qt 窗口
QWidget 更多作为别的窗口的一个部分,QMainWindow更像是完全体。
铆接部件(子窗口):

菜单

QWidget不能设置菜单栏,需要QMainWindow



添加一些菜单:

点击并没有效果,需要加一些菜单项:输入时只能输入英文,想要输入中文复制粘贴,算是Qt Creator的BUG

效果:

代码创建菜单:
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 创建一个菜单栏
QMenuBar* menuBar = new QMenuBar();
// 设置到当前窗口之中
this->setMenuBar(menuBar);
// 创建菜单
QMenu* menu1 = new QMenu("文件");
QMenu* menu2 = new QMenu("编辑");
QMenu* menu3 = new QMenu("视图");
// 添加菜单到菜单栏
menuBar->addMenu(menu1);
menuBar->addMenu(menu2);
menuBar->addMenu(menu3);
// 给菜单添加菜单项
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);
connect(action3,&QAction::triggered,this,&MainWindow::close);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::handle()
{
qDebug() << "新建";
}
给菜单和菜单项设置快捷键,类似于:

给菜单创建快捷键,alt + 键位触发:

菜单项同理:

添加子菜单
以上都是 菜单栏 -> 菜单 -> 菜单项。
也可以菜单栏 -> 菜单 -> 子菜单 -> 子菜单 -> 菜单项。
不仅QMenuBar可以通过addMenu添加菜单。
QMenu也提供了addMenu添加子菜单。

添加分割线

添加图标
用到qrc文件:

菜单也能设置图标:我们发现文字没了

如果给QMenu设置图标,当前QMenu是长在QMenuBar上的,此时文本就不显示,图标覆盖了文本。
QMenuBar 创建方式可能出现的BUG
cpp
QMenuBar* MenuBar = new QMenuBar();
this->setMenuBar(MenuBar);
如果我们创建的项目,没有勾选自动生成的 ui 文件,上述代码是OK的。
如果勾选了自动生成 ui 文件(QT会帮我们生成一个QMenuBar),上述代码会引起 内存泄漏。

当然,如果窗口关闭了,对象树释放,进程结束了,操作系统会把所有的内存回收,内存泄漏就不会产生影响。
避免上述情况可以这样写:
cpp
QMenuBar* menuBar = this->menuBar();
- 如果 QMenuBar 已经存在,直接获取并返回。
- 如果 QMenuBar 不存在,就先创建一个新的,再返回。
这样就是自己替换自己:
cpp
this->setMenuBar(MenuBar);
工具栏 QToolBar
一个窗口可以有多个工具栏,也可以没有。
并且工具栏需要自己手动创建,自身不会自动创建。

示例:
cpp
#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->addToolBar(toolBar);
// 创建菜单项
QAction* action1 = new QAction("文件");
QAction* action2 = new QAction("保存");
action1->setIcon(QIcon(":/file-open.png"));
action2->setIcon(QIcon(":/save-fill.png"));
toolBar->addAction(action1);
toolBar->addAction(action2);
connect(action1,&QAction::triggered,this,&MainWindow::handle1);
connect(action2,&QAction::triggered,this,&MainWindow::handle2);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::handle1()
{
qDebug() << "handle1";
}
void MainWindow::handle2()
{
qDebug() << "handle2";
}
现象:放到上面会显示文本

这是因为文本会以 toolTip 的方式存在。鼠标悬停上去时,就会显出一段提示信息。
也可以手动的设置 toolTip:

菜单项可以被被菜单和工具栏同时使用,那么:

创建多个工具栏:

工具栏点击竖条是可以上下左右拖动的:称为"浮动"状态

可以设置工具栏出现的初始位置:画红线的是指出当前位置。

- Qt::LeftToolBarArea 停靠在左侧
- Qt::RightToolBarArea 停靠在右侧
- Qt::TopToolBarArea 停靠在顶部
- Qt::BottomToolBarArea 停靠在底部
- Qt::AllToolBarAreas 以上四个位置都可停靠

设置工具栏允许停放到哪些边缘:QToolBar 有 setAllowedAraes方法
只允许左右停靠:
cpp
toolBar2->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);

设置不允许浮动:禁止工具栏或停靠窗口脱离主窗口成为独立窗口(工具栏可以拖出窗口的)
cpp
toolBar2->setFloatable(false);
设置不允许移动:禁止工具栏在主窗口内移动位置
cpp
toolBar2->setMovable(false);
状态栏
样例:按比例拉伸

显示一个暂时的消息:
timeout:超出时间,单位为ms,如果timeout == 0(或不填)为永久存在

创建进度条:

浮动窗口
浮动窗口可以认为是子窗口。
Qt 中使用 QDockWidget 实现:

若要给浮动窗口内部,添加一些其它控件,不能直接给这个浮动窗口添加子控件,而是创建出一个单独的QWidget,把添加的控件加入到QWidget中。然后把这个QWidget设置到dockWidget中:

对话框
形如:

Qt 中使用 QDialog 类表示对话框。

在实际开发中,往往不是直接在创建项目时继承自QDialog,而是在代码中,创建额外的类,让额外的类继承自QDialog。
示例:主窗口中,通过点击按钮,弹出一个新的对话框。
QDialog 其实也是 QWidget的子类,QWidget的各种属性方法,QDialog也能使用。

不同于界面上的其他控件,此处 QDialog 每次按下按钮,都会创建一个新的 QDialog 对象,并进行显示,每次点击都会创建的新的对话框对象!
cpp
QDialog* dialog = new QDialog(this);
QMainWindow 被销毁时,此时QDialog 是会随之销毁。但架不住 QDialog会在QMainWindow 之前就存在很多个。
一个程序运行过程中,可以无数次点击这个按钮,进一步的就产生了无数个这样的对象了 -》导致内存泄漏
解决办法:用户点击对话框关闭按钮的时候,再delete操作。
Qt 为了让我们方便,给了Dialog 设置了一个属性,可以通过设置属性,完成上述效果:
cpp
// 关闭时,自动进行delete
dialog->setAttribute(Qt::WA_DeleteOnClose);
自定义对话框
上述的对话框都是空白的,如果想往里面添加内容,就需要自定义对话框。
要想自定义对话框,就需要继承自QDialog 创建类:
用代码创建:

Dialog要继承自QDialog:

cpp
遇到的BUG

原因:moc 文件没有正确生成和链接。
清除后,qmake重新生成在运行:
