Qt 窗口是通过 QMainWindow 类来实现的。
QMainWindow 是一个为用户提供主窗口程序的类,继承自 QWidget 类,并且提供了⼀个预定义的布局。QMainWindow 包含一个菜单栏(menubar)、多个工具栏(toolbars)、多个浮动窗口(铆接部件)(dockwidgets)、一个状态栏(statusbar)和一个中心部件(centralwidget),它是许多应用程序的基础,如文本编辑器,图片编辑器等。如下图为 QMainwindow 中各组件所处的位置:
菜单栏(MenuBar)
Qt 中的菜单栏是通过 QMenuBar 这个类来实现的。一个主窗口最多只有一个菜单栏。位于主窗口顶部、主窗口标题下面。
菜单栏中包含菜单.菜单中包含菜单项.
创建菜单栏
方式一:菜单栏的创建可以借助于 QMainWindow 类提供的 menuBar() 函数来实现。menubar() 函数原型如下:
QMenuBar * menuBar() const
//创建菜单栏
QMenuBar *menubar = menuBar();
//将菜单栏放入窗口中
this->setMenuBar(menubar);
方式二:在堆上动态创建;
QMenuBar *menubar = new QMenuBar(this);
this->setMenuBar(menubar);
使用 setMenuBar
把菜单栏放到窗口中.
在菜单栏中添加菜单
创建菜单,并通过 QMenu
提供的 addMenu()
函数来添加菜单。
示例:
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("构建");
menubar->addMenu(menu1);
menubar->addMenu(menu2);
menubar->addMenu(menu3);
}
mainwindow创建的时候菜单栏默认会创建,所以是setMenuBar,而不是addMenuBar
效果如下:
创建菜单项
在 Qt 中,并没有专门的菜单项类,可以通过 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("构建");
menubar->addMenu(menu1);
menubar->addMenu(menu2);
menubar->addMenu(menu3);
//创建菜单项
QAction *act1 = new QAction("open");
QAction *act2 = new QAction("close");
QAction *act3 = new QAction("create");
//将菜单项添加到菜单上
menu1 ->addAction(act1);
menu1 ->addAction(act2);
menu1 ->addAction(act3);
}
效果如下:
在菜单栏之间添加分割线
在菜单项之间可以添加分割线。分割线如下图所示,添加分割线是通过 QMenu
类提供的 addSeparator()
函数来实现;
示例:
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("构建");
menubar->addMenu(menu1);
menubar->addMenu(menu2);
menubar->addMenu(menu3);
//创建菜单项
QAction *act1 = new QAction("open");
QAction *act2 = new QAction("close");
QAction *act3 = new QAction("create");
//将菜单项添加到菜单上
menu1 ->addAction(act1);
menu1->addSeparator(); //在open和close之间添加分割线
menu1 ->addAction(act2);
menu1->addSeparator();
menu1 ->addAction(act3);
menu1->addSeparator();
}
综合示例
在窗口上创建一个菜单栏,在菜单栏中添加一些菜单,在某一个菜单中添加一些菜单项。
1、新建 Qt 项目
注意:此时新建项目时选择的基类 QMainwindow ,如下图示:
2、在 “mainwindow.cpp” 文件中创建菜单和中央控件
- 创建一个菜单栏, 一个菜单.
- 两个菜单项: 保存, 加载
- 创建一个 QTextEdit 作为窗口的中央控件.
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void save();
void load();
private:
Ui::MainWindow *ui;
QTextEdit* edit;
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 设置标题
this->setWindowTitle("我的记事本");
// 创建菜单栏
QMenuBar* menuBar = new QMenuBar(this);
this->setMenuBar(menuBar);
// 创建菜单
QMenu* menu = new QMenu("文件");
menuBar->addMenu(menu);
// 创建菜单项
QAction* action1 = new QAction("保存");
QAction* action2 = new QAction("加载");
menu->addAction(action1);
menu->addAction(action2);
// 创建中央控件
edit = new QTextEdit(this);
this->setCentralWidget(edit);
edit->setPlaceholderText("此处编写⽂本内容...");
}
3、给 action 添加一些动作
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 设置标题
this->setWindowTitle("我的记事本");
// 创建菜单栏
QMenuBar* menuBar = new QMenuBar(this);
this->setMenuBar(menuBar);
// 创建菜单
QMenu* menu = new QMenu("文件");
menuBar->addMenu(menu);
// 创建菜单项
QAction* action1 = new QAction("保存");
QAction* action2 = new QAction("加载");
QAction* action3 = new QAction("退出");
menu->addAction(action1);
menu->addAction(action2);
menu->addAction(action3);
// 创建中央控件
edit = new QTextEdit(this);
this->setCentralWidget(edit);
edit->setPlaceholderText("此处编写⽂本内容...");
// 连接信号槽, 点击 action 时触发⼀定的效果.
connect(action1, &QAction::triggered, this, &MainWindow::save);
connect(action2, &QAction::triggered, this, &MainWindow::load);
connect(action3, &QAction::triggered, this, &MainWindow::close);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::save()
{
// 弹出对话框, 选择写⼊⽂件的路径
QFileDialog* dialog = new QFileDialog(this);
QString fileName = dialog->getSaveFileName(this, "保存⽂件");
qDebug() << "fileName: " << fileName;
// 写⼊⽂件
std::ofstream file(fileName.toStdString().c_str());
if (!file.is_open()) {
qDebug() << "⽂件保存失败!";
return;
}
const QString& text = edit->toPlainText();
file << text.toStdString();
file.close();
}
void MainWindow::load()
{
// 弹出对话框, 选择打开的⽂件
QFileDialog* dialog = new QFileDialog(this);
QString fileName = dialog->getOpenFileName(this, "加载⽂件");
qDebug() << "fileName: " << fileName;
// 读取⽂件
std::ifstream file(fileName.toStdString().c_str());
if (!file.is_open()) {
qDebug() << "⽂件加载失败!";
return;
}
std::string content;
std::string line;
while (std::getline(file, line)) {
content += line;
content += "\n";
}
file.close();
// 显⽰到界⾯上
QString text = QString::fromStdString(content);
edit->setPlainText(text);
}
执行程序, 可以看到此时就可以通过程序来保存/加载文件了. 并且对文件进行编辑
工具栏(ToolBar)
工具栏是应用程序中集成各种功能实现快捷键使用的一个区域。可以有多个,也可以没有,它并不是应用程序中必须存在的组件。它是一个可移动的组件,它的元素可以是各种窗口组件,它的元素通常以图标按钮的方式存在。如下图为工具栏的示意图:
创建工具栏
调用 QMainWindow 类的 addToolBar() 函数来创建工具栏,每增加一个工具栏都需要调用一次该函数。
如添加两个工具栏:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QToolBar *toolBar1 = new QToolBar(this);
QToolBar *toolBar2 = new QToolBar(this);
this->addToolBar(toolBar1);
this->addToolBar(toolBar2);
}
设置停靠位置
工具栏停靠位置的设置有两种方式。一种是在创建工具栏的同时指定停靠的位置,另一种是通过 QToolBar 类提供的 **setAllowedAreas() **函数来设置。
方式一:创建工具栏的同时指定其停靠的位置。
在创建工具栏的同时,也可以设置工具栏的位置,其默认位置是在窗口的最上面;如上述代码,默认在最上面显示。工具栏允许停靠的区域由 QToolBar 类提供的 allowAreas() 函数决定,其中可以设置的位置包括:
Qt::LeftToolBarArea
停靠在左侧Qt::RightToolBarArea
停靠在右侧Qt::TopToolBarArea
停靠在顶部Qt::BottomToolBarArea
停靠在底部Qt::AllToolBarAreas
以上四个位置都可停靠
示例:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QToolBar *toolBar1 = new QToolBar(this);
QToolBar *toolBar2 = new QToolBar(this);
//创建工具栏的同时,指定工具栏在左侧显示
this->addToolBar(Qt::LeftToolBarArea, toolBar1);
//右侧显示
this->addToolBar(Qt::RightToolBarArea, toolBar2);
}
方式二:使用 QToolBar 类提供的 setAllowedAreas()函数设置停靠位置。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QToolBar *toolBar1 = new QToolBar(this);
QToolBar *toolBar2 = new QToolBar(this);
this->addToolBar(toolBar1);
this->addToolBar(toolBar2);
//只允许在左侧停靠
toolBar1->setAllowedAreas(Qt::LeftToolBarArea);
//只允许在右侧停靠
toolBar2->setAllowedAreas(Qt::RightToolBarArea);
}
说明: 在创建工具栏的同时指定其停靠的位置,指的是程序运行时工具栏默认所在的位置;而使用 setAllowedAreas()函数设置停靠位置,指的是工具栏允许其所能停靠的位置。
设置浮动属性
工具栏的浮动属性可以通过 QToolBar 类提供的 setFloatable() 函数来设置。setFloatable() 函数原型为:
void setFloatable (bool floatable)
参数:
- true:浮动
- false:不浮动
示例:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QToolBar *toolBar1 = new QToolBar(this);
QToolBar *toolBar2 = new QToolBar(this);
this->addToolBar(Qt::LeftToolBarArea,toolBar1);
this->addToolBar(Qt::RightToolBarArea,toolBar2);
toolBar1->setFloatable(true); //允许工具栏浮动
toolBar2->setFloatable(false); //禁止工具栏浮动
}
设置移动属性
设置工具栏的移动属性可以通过 QToolBar 类提供的 setMovable() 函数来设置。**setMovable() **函数原型为:
void setMovable(bool movable)
参数:
- true:移动
- false:不移动
说明:若设置工具栏为不移动状态,则设置其停靠位置的操作就不会生效,所以设置工具栏的移动属性类似于总开关的效果。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QToolBar *toolBar1 = new QToolBar(this);
QToolBar *toolBar2 = new QToolBar(this);
this->addToolBar(Qt::LeftToolBarArea,toolBar1);
this->addToolBar(Qt::RightToolBarArea,toolBar2);
toolBar1->setMovable(true); //允许移动
toolBar2->setMovable(false); //不允许移动
}
综合示例
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800,600); //设置窗口大小
QToolBar *toolBar = new QToolBar(this);
//设置工具栏的位置:默认在窗口的上面,此处设置为在左侧
addToolBar(Qt::LeftToolBarArea,toolBar);
//设置工具栏的停靠位置,设置工具栏只允许在左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
//设置工具栏的浮动属性
toolBar->setFloatable(false);
//设置工具栏的移动(总开关)
toolBar->setMovable(false);
//设置工具栏的内容
QAction *openAction = new QAction("open" ,this);
QAction *newAction = new QAction("new", this);
toolBar->addAction(openAction);
toolBar->addSeparator();
toolBar->addAction(newAction);
//工具栏也可以添加控件
QPushButton *btn = new QPushButton("保存",this);
toolBar->addWidget(btn);
}
状态栏(StatusBar)
状态栏是应用程序中输出简要信息的区域。一般位于主窗口的最底部,一个窗口中最多只能有一个状态栏。在 Qt 中,状态栏是通过 QStatusBar 类来实现的。 在状态栏中可以显示的消息类型有:
- 实时消息:如当前程序状态
- 永久消息:如程序版本号,机构名称
- 进度消息:如进度条提示,百分百提示
状态栏的创建
状态栏的创建是通过 QStatusBar 类提供的 statusBar() 函数来创建;示例如下:
//创建状态栏
QStatusBar *stbr = this->statusBar();
//将状态栏置于窗口中
this->setStatusBar(stbr);
在状态栏中显示实时消息
在状态栏中显示实时消息是通过 showMessage() 函数来实现,示例如下:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建状态栏
QStatusBar *stbr = this->statusBar();
//将状态栏置于窗口中
setStatusBar(stbr);
//状态栏中显示大约2秒的 "hello world"
stbr->showMessage("Hello World", 2000);
}
在状态栏中显示永久消息
在状态栏中可以显示永久消息,此处的永久消息是通过标签来显示的;示例如下:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建状态栏
QStatusBar *stbr = this->statusBar();
//将状态栏置于窗口中
setStatusBar(stbr);
//创建标签
QLabel *label = new QLabel("提示信息",this);
//将标签放入状态栏中
stbr->addWidget(label);
}
显示效果如下:
调整显示消息的位置
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建状态栏
QStatusBar *stbr = this->statusBar();
//将状态栏置于窗口中
setStatusBar(stbr);
//创建标签
QLabel *label = new QLabel("提示信息",this);
//将标签放入状态栏中
stbr->addWidget(label);
//将创建的标签放入到状态栏的右侧
QLabel *label2 = new QLabel("右侧提示信息",this);
stbr->addPermanentWidget(label2);
}
显示效果如下:
浮动窗口(DockWidget)
在 Qt 中,浮动窗口也称之为铆接部件。浮动窗⼝是通过 QDockWidget 类来实现浮动的功能。浮动窗口一般是位于核心部件的周围,可以有多个。
浮动窗口的创建
浮动窗口的创建是通过 **QDockWidget **类提供的构造方法 QDockWidget() 函数动态创建的;示例如下:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//浮动窗口
QDockWidget *dockwidget = new QDockWidget("浮动窗口",this);
//将浮动窗口置于当前窗口中
this->addDockWidget(Qt::BottomDockWidgetArea,dockwidget);
}
设置停靠的位置
浮动窗口是位于中心部件的周围。可以通过 QDockWidget 类中提供 setAllowedAreas() 函数设置其允许停靠的位置。其中可以设置允许停靠的位置有:
Qt::LeftDockWidgetArea
停靠在左侧Qt::RightDockWidgetArea
停靠在右侧Qt::TopDockWidgetArea
停靠在顶部Qt::BottomDockWidgetArea
停靠在底部Qt::AllDockWidgetAreas
以上四个位置都可停靠
示例如下:设置浮动窗口只允许上下停靠
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//浮动窗口
QDockWidget *dockwidget = new QDockWidget("浮动窗口",this);
//将浮动窗口置于当前窗口中
this->addDockWidget(Qt::BottomDockWidgetArea,dockwidget);
//设置浮动窗口的停靠区域,只允许上下停靠
dockwidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
}
效果如下:
数设置其允许停靠的位置。其中可以设置允许停靠的位置有:
Qt::LeftDockWidgetArea
停靠在左侧Qt::RightDockWidgetArea
停靠在右侧Qt::TopDockWidgetArea
停靠在顶部Qt::BottomDockWidgetArea
停靠在底部Qt::AllDockWidgetAreas
以上四个位置都可停靠
示例如下:设置浮动窗口只允许上下停靠
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//浮动窗口
QDockWidget *dockwidget = new QDockWidget("浮动窗口",this);
//将浮动窗口置于当前窗口中
this->addDockWidget(Qt::BottomDockWidgetArea,dockwidget);
//设置浮动窗口的停靠区域,只允许上下停靠
dockwidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
}
效果如下: