主窗口 mainWindow
前面学习的所有代码,都是基于QWidget
控件,其更多的是作为别的窗口的部分
现在来学习QMainWindow
,即主窗口,其包含以下属性
Window Title
:标题栏Menu Bar
:菜单栏Tool Bar Area
:工具栏Dock Widget Area
:铆接部件(子窗口)Central Widget
:中央窗口Status Bar
:状态栏
菜单栏 Menu Bar
一个窗口,只能有一个菜单栏,但是可以有很多个菜单,每一个菜单又可以很多菜单项
例如,用代码创建菜单栏、菜单、菜单项、子菜单、分割线、图标:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 获取菜单栏
QMenuBar* menuBar = this->menuBar();
// 创建菜单,并设置快捷键
QMenu* menu1 = new QMenu("文件 (&F)");
QMenu* menu2 = new QMenu("设置 (&S)");
QMenu* menu3 = new QMenu("关于 (&A)");
menuBar->addMenu(menu1);
menuBar->addMenu(menu2);
menuBar->addMenu(menu3);
// 创建菜单项
QAction* act1 = new QAction("新建");
QAction* act2 = new QAction("保存");
QAction* act3 = new QAction("退出");
menu1->addAction(act1);
menu1->addSeparator(); // 添加分割线
menu1->addAction(act2);
menu1->addSeparator(); // 添加分割线
menu1->addAction(act3);
// 为菜单项添加图片
act1->setIcon(QIcon(":/open"));
act2->setIcon(QIcon(":/save"));
// 为菜单添加图片
menu1->setIcon(QIcon(":/file"));
// 设置菜单项快捷键
act1->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N));
act2->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_B));
act3->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_E));
// 创建子菜单
QMenu* menu_child = new QMenu("高级 (&L)");
QAction* act4 = new QAction("字体");
QAction* act5 = new QAction("语言");
menu_child->addAction(act4);
menu1->addSeparator(); // 添加分割线
menu_child->addAction(act5);
// 将子菜单添加到菜单 menu2
menu2->addMenu(menu_child);
connect(act1, &QAction::triggered, this, [](){
qDebug() << "新建文件";
});
connect(act2, &QAction::triggered, this, [](){
qDebug() << "保存文件";
});
connect(act3, &QAction::triggered, this, [](){
qDebug() << "退出窗口";
});
connect(act3, &QAction::triggered, this, &QMainWindow::close);
}
QAction::triggered
:该信号为菜单项被用户执行时触发- 可以通过
& + 按键
的方式,设置菜单的快捷键,此时,按下Alt + 按键
即可打开对应的菜单 - 尽管也可以通过
& + 按键
的方式,设置菜单项的快捷键,但是如果要使用,就必须先展开对应的菜单。 因此对于**QAction
快捷键的设置,优先使用setShortcut
** - 如果为菜单设置图片,那么菜单的文本就不会显示;如果为菜单项设置图片,菜单项的图片和文本都可以显示
效果:
工具栏 Tool Bar
一个窗口,可以没有工具栏,可以有工具栏,也可以有多个
一个窗口,默认不自带工具栏,需要手动创建
例如:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 创建工具栏
QToolBar* toolBar = new QToolBar();
this->addToolBar(toolBar);
// 创建工具项
QAction* act1 = new QAction("打开文件");
QAction* act2 = new QAction("保存文件");
act1->setIcon(QIcon(":/open"));
act2->setIcon(QIcon(":/save"));
// 将工具项 添加到 工具栏
toolBar->addAction(act1);
toolBar->addAction(act2);
connect(act1, &QAction::triggered, this, [](){
qDebug() << "打开文件";
});
connect(act2, &QAction::triggered, this, [](){
qDebug() << "保存文件";
});
}
如果工具项被设置了图标,那么其文本就会被隐藏
被隐藏的文本会以
toolTip
的方式存在工具栏和菜单栏往往搭配使用,工具栏中的工具项也可以在菜单栏中出现
工具栏可以被拖动,我们可以对其相关属性进行设置:
可以设置工具栏出现的初始位置。可以在
addToolBar
中添加选项来设置Qt::LeftToolBarArea
停靠在左侧Qt::RightToolBarArea
停靠在右侧Qt::TopToolBarArea
停靠在顶部Qt::BottomToolBarArea
停靠在底部Qt::AllToolBarAreas
以上四个位置都可停靠
可以设置工具栏允许停靠在哪些边缘
- 通过函数设置:
setAllowedAreas()
- 通过函数设置:
可以设置工具栏是否允许浮动
- 通过函数设置:
setFloatable()
- 通过函数设置:
可以设置工具栏是否可以移动
- 通过函数设置:
setMovable()
- 通过函数设置:
效果:
状态栏 Status Bar
QMainWindow
自带状态栏Status Bar
,且一个窗口状态栏只存在一个
例如:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 获取状态栏
QStatusBar* statusBar = this->statusBar();
// 添加临时控件
QLabel* label = new QLabel("这是一条临时消息");
statusBar->addWidget(label, 1);
// 添加永久控件
QProgressBar* progress = new QProgressBar();
progress->setTextVisible(true);
progress->setRange(0, 100);
progress->setValue(40);
statusBar->addPermanentWidget(progress, 2);
// 线是一条信息
statusBar->showMessage("这是一条显示信息", 3000);
}
addWidget
:向状态栏添加一个临时控件,这个控件可以被showMessage()
显示的信息覆盖。后面的数字为拉伸系数addPermanentWidget
:向状态栏添加一个永久控件,这个控件不可以被showMessage()
显示的信息覆盖。后面的数字为拉伸系数showMessage
:在状态栏显示一条消息,后面的数字为显示时间(ms),默认为0,0为永久显示
浮动窗口 Dock Widget
可以像正常窗口一样,给浮动窗口内部,添加一些其他控件
但是不能直接给这个浮动窗口添加子控件,而是需要创建出一个单独的QWidget
,将控件添加到QWidget
中
最后再将QWidget
添加到子窗口中
例如:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 创建子窗口,并放置在主窗口顶部
QDockWidget* dock = new QDockWidget("子窗口");
// 只允许停靠在顶部和右侧
dock->setAllowedAreas(Qt::DockWidgetArea::RightDockWidgetArea | Qt::DockWidgetArea::TopDockWidgetArea);
this->addDockWidget(Qt::DockWidgetArea::TopDockWidgetArea, dock);
// 添加一个容器窗口
QWidget* container = new QWidget();
QVBoxLayout* layout = new QVBoxLayout();
container->setLayout(layout);
QLabel* label = new QLabel("这是一段文本");
layout->addWidget(label);
// 将容器窗口添加到子窗口中
dock->setWidget(container);
}
效果: