QMainWindow

  • 1 简介
  • 2 Menu Bar
    • 2.1 简单示例
  • 3 状态栏
    • 3.1 示例
  • 4 工具栏
    • 4.1 简单示例
    • 4.3 设置方向和工具栏中组件的排列方向
    • 4.4 设置固定方向
    • 4.5 addToolBarBreak()
  • 5 setCentralWidget() 设置中心区域
  • 6 QDockWidget
    • 6.1 setFeatures()
  • 7 保存 / 设置窗口状态
    • 7.1 简单示例:
  • 8 完整代码

1 简介

在桌面程序中,任何软件都有界面,界面就是与用户交互的,一般体现为窗口。在 QT 中通过继承 QMainWindow 来实现自定义的窗口,并为我们规划好了一个窗口大致包含的几个部分:顶部的菜单栏、底部的状态栏、外圈环绕的工具栏、内圈环绕的可悬浮的窗口部件以及最中心的中心部件。如下图:

下面就依次介绍一下 QMainWindow 中各个组件的 UI 效果及作用,这里只是简单的介绍一下,让大家有个印象,后面的文章再逐个详细的介绍。

2 Menu Bar

菜单中栏中,

  • 可以添加多个菜单,但是菜单并不负责执行具体的操作,而是在菜单中添加不同的 “动作”(QAction)来完成
  • 在菜单栏中除了添加菜单,还可以直接添加 QAction。

2.1 简单示例

MainWindow.h :

class MainWindow : public QMainWindow
{Q_OBJECTprivate slots:void newActTriggered();void operateActTriggered();public:QMenuBar *mBar;//菜单栏QMenu *fileMenu;QMenu *editMenu;QAction *newAct;QAction *operateAct;MainWindow(QWidget *parent = 0);void createMenus();
};

MainWindow.cpp:
本段代码主要完成在菜单栏中:

  • 添加一个 “文件” 菜单,并在文件菜单中添加一个 “new” 菜单项
  • 添加一个 “编辑”菜单,但是给菜单没有菜单项
  • 添加一个 “操作” 动作。
#include "mainwindow.h"
#include "qdebug.h"
void MainWindow::createMenus(){mBar = menuBar();//获取菜单栏fileMenu = mBar->addMenu(tr("文件"));//创建文件菜单editMenu = mBar->addMenu(tr("编辑"));//创建编辑菜单//在菜单栏中添加一个 QAction 并指定 triggered() 信号的槽函数operateAct = mBar->addAction(tr("操作"),this,SLOT(operateActTriggered()));//在文件菜单中添加 new 菜单子项newAct = new QAction("new");fileMenu->addAction(newAct);connect(this->newAct,SIGNAL(triggered()),this,SLOT(newActTriggered()));
}
//当 new 菜单子项被点击时执行
void MainWindow::newActTriggered(){qDebug()<<"newActTriggered()";
}
//当 操作 被点击时执行
void MainWindow::operateActTriggered(){qDebug()<<"operateTriggered()";
}MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{createMenus();
}

运行结果如下:

当我们点击 “new” 时就会在控制台输出:

newActTriggered()

当我们点击 “操作” 时就会在控制台输出:

operateTriggered()

我们除了可以通过 menuBar() 方法获取一个系统为我们创建好的 QMenuBar 对象外,我们也可以自己创建一个 QMenuBar 对象,再通过 setMenuBar() 将它设置到 MainWindow 中。

3 状态栏

一般的桌面软件,在窗口界面的左下角或者最下面都是有一个状态栏的,一般显示文本编辑器中此时光标的位置,或当前文件的名称等等。在 qt 中,我们也可以给 QMainWindow 设置状态栏。

3.1 示例

void MainWindow::createStatusBar(){sBar = statusBar();//获取窗口的状态栏对象 QStatusBar 实例。sBar->showMessage(tr("这里是状态栏"),0);//状态栏显示的文本
}

4 工具栏

一般软件中,工具栏也是由一些可点击的“动作”组成的,与菜单栏不同的是,工具栏一般都是些可点击的图标,在 UI 交互上,给用户一种更加直观的感觉。

我们看一下 NodePad++ 的界面做一个简单的认识:

4.1 简单示例

接下来我们就看一下如何用 QT 给窗口添加工具栏。

void MainWindow::showToolBar(){fileToolBar = addToolBar(tr("文件工具"));fileToolBar->addAction(newAct);
}

在这个案例中我们通过 QMainWindowaddToolBar() 方法向窗口中添加一个工具栏,然后再在窗口中添加了一个 QAction 。这个 newAct 是我们前面定义的,它一样可以被点击,并执行槽函数。

运行结果:这个我们的工具栏就是很简单的文字,大家可以给它添加一些有图标的QAction 就可以了。

并且现在这个工具栏我们可以随意拖动到窗口的下方、右方、左方。


这也就是为什么,在介绍 QMainWindow 的各个组件的时候,QToolBar 是占了一圈的原因,工具栏可以随意的放在四个方向。

4.3 设置方向和工具栏中组件的排列方向

我们可以通过 fileToolBar->setMovable(false); 方法将工具栏固定住,用户就不能随意拖动了。
也可通过 fileToolBar->setOrientation(Qt::Horizontal); 方法设置工具栏中的各个组件为水平排列,Qt::Vertical 为竖直方向

4.4 设置固定方向

通过 addToolBar(const QString &title); 默认是在上方的,且不能再设置位置了。可以通过addToolBar(Qt::ToolBarArea area, QToolBar *toolbar); 方法将一个工具栏添加到指定的位置上:

 ediToolBar = new QToolBar(tr("操作工具"));ediToolBar->addAction(operateAct);ediToolBar->addAction(newAct);ediToolBar->setMovable(false);addToolBar(Qt::RightToolBarArea,ediToolBar);//添加到右边

4.5 addToolBarBreak()

addToolBarBreak(); 使工具栏之间添加一个间隔。

void MainWindow::showToolBar(){fileToolBar = addToolBar(tr("文件工具"));fileToolBar->setMovable(false);fileToolBar->addAction(newAct);addToolBarBreak(Qt::TopToolBarArea);//Qt::TopToolBarArea 两个工具栏上下排列ediToolBar = new QToolBar(tr("操作工具"));ediToolBar->addAction(operateAct);ediToolBar->addAction(newAct);ediToolBar->setMovable(false);addToolBar(ediToolBar);
}


这两个工具栏中间有一条横线间隔,且这两个工具栏是上下方向排列的。
默认情况下是左右方向的:

5 setCentralWidget() 设置中心区域

顾名思义,中心区域就是窗口最中心的地方,一般是用户主要操作的地方,比如,前面的 NodePad++ 的中心区域就是用户编辑文本的地方。

//将一个给定的 QWidget 作为中心区域
void QMainWindow::setCentralWidget(QWidget *widget)
//获取系统创建的中心区域
QWidget *QMainWindow::centralWidget() const

从这两个方法可以看出,只要是一个 widget 都可以作为中心区域。
简单示例:将一个 TextEdit 文本编辑框作为 centralWidget

void MainWindow::showCentralWidget(){centerTextEdit=new QTextEdit(this);centerTextEdit->setText(tr("这里是中心区域"));centerTextEdit->setAlignment(Qt::AlignCenter);setCentralWidget(centerTextEdit);
}


中间的文本编辑框就是我们的中心区域了,它在菜单栏、工具栏的下面,在状态栏的上面。

6 QDockWidget

QDockWidget类提供了一个特殊的窗口部件,它可以是被锁在 QMainWindow 窗口内部或者是作为顶级窗口悬浮在桌面上。
它可以围绕在中心区域的四周,即四个方向都可以放置,与工具栏类似。

先看一个简单的示例:

void MainWindow::showDockWidget(){dock1 = new QDockWidget(tr("dock1"),this);dock1->setFeatures(QDockWidget::DockWidgetMovable);dock1->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);QTextEdit *textEdit1=new QTextEdit();textEdit1->setText(tr("这是第一个 dockWidget,只能放在左部、右部,用户可以拖动位置"));dock1->setWidget(textEdit1);addDockWidget(Qt::RightDockWidgetArea,dock1);//默认在窗口的右部dock2 = new QDockWidget(tr("dock2"),this);dock2->setFeatures(QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetClosable);QTextEdit *textEdit2=new QTextEdit();textEdit2->setText(tr("这是第二个 dockWidget 只能放在下部、右部,用户可以将它拖出窗口,浮动在桌面上;也可以关闭它"));dock2->setWidget(textEdit2);addDockWidget(Qt::RightDockWidgetArea,dock2);
}

6.1 setFeatures()

上面的例子我们创建了两个 QDockWidget ,都通过 setFeatures() 设置了一些特性 :dock1 可以移动;dock2 可浮动和可关闭。

可移动就是指用户可以将 dockWidget 从原本的右部拖到左部、下部等,至于可以拖动哪个部位则由 setAllowedAreas() 来控制。


上图是将 dock1 移动到了窗口的左部。

上图是将 dock2 拖出了主窗口,让 dock2 悬浮在桌面上。因为我们给 dock2 设置了:

dock2->setFeatures(QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetClosable);

点击右上角的关闭按钮即可关闭 dock2 ,而 dock1 没有设置可关闭特性,则不能关闭。

到这里,QMainWindow 中的各个部件就简单的介绍完了,对于每个部件更加详细的介绍就在后面的文章介绍了。比如让部件的 UI 元素更加丰富,功能更强大。

7 保存 / 设置窗口状态

很多时候,用户在关闭软件后,会记录一下程序当前的状态,用户下次打开软件后,还是上一次退出时的状态。比如:wps 的最近打开的文件记录;对软件界面的大小设置、常用快捷键的设置等

下面两个方法可以保存窗口信息

QByteArray saveGeometry() const;//保存窗口大小
QByteArray saveState(int version = 0) const;//保存当前状态,QToolBar 和 QDockWidget,version 可以自己设置版本号

相反的方法就是设置状态了:

bool restoreGeometry(const QByteArray &geometry);
bool restoreState(const QByteArray &state, int version = 0);

7.1 简单示例:

我们拿前面的例子做一个简单示例,启动程序后,我们调整窗口的大小,并将 dock2 拖出窗口,然后关闭窗口,再次启动程序,将会是我们上一次关闭时的状态

//点击窗口的关闭按钮时执行
void MainWindow::closeEvent(QCloseEvent *event){QSettings settings("com.llk", "mainwindowtest");settings.beginGroup("mainWindow");settings.setValue("geometry", saveGeometry());settings.setValue("windowState", saveState());settings.endGroup();QMainWindow::closeEvent(event);
}
void MainWindow::readSettings(){QSettings settings("com.llk", "mainwindowtest");settings.beginGroup("mainWindow");//读取出保存的值,并设置到窗口中restoreGeometry(settings.value("geometry").toByteArray());restoreState(settings.value("windowState").toByteArray());settings.endGroup();
}

启动程序后,我们调整窗口的大小,再将 dock2 拖出窗口:

然后关闭软件,再启动我们的程序,还将展示上图的界面,说明程序记录了我们前一次关闭时的状态。

【注意】readSettings(); 方法的调用应在各个部件创建完成后再调用,否则没有效果

这里我们是使用了 QSettings 类来帮我们存储窗口状态,其实我们也可以将数据保存到自己想保存的任意文件中,或是通过网络传给服务器保存都可以。只要将 saveGeometry() 和 saveState() 方法返回的字节数组的值保存起来,再次启动程序的时候再设置给 restoreGeometry() 和 restoreState() 即可。

8 完整代码

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include "qaction.h"
#include "qmenu.h"
#include "qmenubar.h"
#include "qstatusbar.h"
#include "qtoolbar.h"
#include "QDockWidget"
#include "qtextedit.h"
#include "QCloseEvent"
#include "qsettings.h"
#include "qdebug.h"class MainWindow : public QMainWindow
{Q_OBJECTprivate slots:void newActTriggered();void operateActTriggered();public:QMenuBar *mBar;//菜单栏QMenu *fileMenu;QMenu *editMenu;QAction *newAct;QAction *operateAct;QStatusBar *sBar;//状态栏QToolBar *fileToolBar;//文件工具栏QToolBar *ediToolBar;//文件工具栏QTextEdit *centerTextEdit;QDockWidget *dock1;QDockWidget *dock2;MainWindow(QWidget *parent = 0);void showMenus();void showStatusBar();void showToolBar();void showCentralWidget();void showDockWidget();void closeEvent(QCloseEvent *event);void readSettings();~MainWindow();
};

mainwindow.cpp:

#include "mainwindow.h"
//1、菜单栏
void MainWindow::showMenus()
{mBar = menuBar();fileMenu = mBar->addMenu(tr("文件"));editMenu = mBar->addMenu(tr("编辑"));operateAct = mBar->addAction(tr("操作"),this,SLOT(operateActTriggered()));newAct = new QAction("new");fileMenu->addAction(newAct);connect(this->newAct,SIGNAL(triggered()),this,SLOT(newActTriggered()));
}//2、状态栏
void MainWindow::showStatusBar(){sBar = statusBar();sBar->showMessage(tr("这里是状态栏"),0);
}
//3、工具栏
void MainWindow::showToolBar(){fileToolBar = addToolBar(tr("文件工具"));fileToolBar->setObjectName("fileToolBar");fileToolBar->setMovable(false);fileToolBar->addAction(newAct);ediToolBar = new QToolBar(tr("操作工具"));ediToolBar->setObjectName("ediToolBar");ediToolBar->addAction(operateAct);ediToolBar->addAction(newAct);ediToolBar->setMovable(false);addToolBar(ediToolBar);
}//4、中心区域
void MainWindow::showCentralWidget(){centerTextEdit=new QTextEdit(this);centerTextEdit->setText(tr("这里是中心区域"));centerTextEdit->setAlignment(Qt::AlignCenter);setCentralWidget(centerTextEdit);
}//5、悬浮部件
void MainWindow::showDockWidget(){dock1 = new QDockWidget(tr("dock1"),this);dock1->setObjectName("dock1");dock1->setFeatures(QDockWidget::DockWidgetMovable);dock1->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);QTextEdit *textEdit1=new QTextEdit();textEdit1->setText(tr("这是第一个 dockWidget,只能放在左部、右部,用户可以拖动位置"));dock1->setWidget(textEdit1);addDockWidget(Qt::RightDockWidgetArea,dock1);//默认在窗口的右部dock2 = new QDockWidget(tr("dock2"),this);dock2->setObjectName("dock2");dock2->setFeatures(QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetClosable);dock2->setAllowedAreas(Qt::BottomDockWidgetArea|Qt::RightDockWidgetArea);QTextEdit *textEdit2=new QTextEdit();textEdit2->setText(tr("这是第二个 dockWidget 只能放在下部、右部,用户可以将它拖出窗口,浮动在桌面上;也可以关闭它"));dock2->setWidget(textEdit2);addDockWidget(Qt::RightDockWidgetArea,dock2);
}void MainWindow::closeEvent(QCloseEvent *event){QSettings settings("com.llk", "mainwindowtest");settings.beginGroup("mainWindow");settings.setValue("geometry", saveGeometry());settings.setValue("windowState", saveState());settings.endGroup();QMainWindow::closeEvent(event);
}void MainWindow::readSettings(){QSettings settings("com.llk", "mainwindowtest");settings.beginGroup("mainWindow");restoreGeometry(settings.value("geometry").toByteArray());restoreState(settings.value("windowState").toByteArray());settings.endGroup();
}void MainWindow::newActTriggered(){qDebug()<<"newActTriggered()";
}void MainWindow::operateActTriggered(){qDebug()<<"operateTriggered()";
}MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{showMenus();showStatusBar();showToolBar();showCentralWidget();showDockWidget();readSettings();
}MainWindow::~MainWindow()
{}

main.cpp:

#include "mainwindow.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}

QT入门之QMainWindow相关推荐

  1. C++Qt入门(3)---QMainWindow的基本组件

    文章目录 四.QT中的QMainWindow 1.QMenuBar 2.QTool 3.QStatusBar 4.QDockWidget 5.中心部件(核心部件) 6. 完整代码和效果图 四.QT中的 ...

  2. QT入门第一天平台使用规则和代码逻辑学习(初学者)

    QT入门第一天平台使用规则和代码逻辑学习 QT学习目的,岗位需求 QT的 应用领域,发展历史 QT下载安装,不同版本QT介绍 新建QT工程 1.集成开发环境介绍 2.新建QT工程 3.QT工程介绍 Q ...

  3. Qt入门学习——Qt Creator的使用

    Qt Creator介绍 通过前面<Qt快速入门(vim纯代码编写)>的学习得知,只有搭建好了 Qt 环境(Qt库和开发工具),即可通过 vim 纯代码编写 Qt 程序,再借助 Qt 里的 ...

  4. Qt中的QMainWindow

    文章目录 1 Qt中的QMainWindow简介 1.1 应用程序中的主窗口 1.2 QMainWindow 2 QMainWindow中的菜单栏 3 QMainWindow中的工具栏 4 QMain ...

  5. Qt实现基本QMainWindow主窗口程序

    这个实验用Qt实现基本QMainWindow主窗口 先上实验效果图    打开一个文件,读取文件类容 详细步骤: 1.打开Qt creator新建MainWindow工程 右键工程名添加新文件,mai ...

  6. topic1:Qt入门之搭建环境与hello world看Qt开发框架

    1.搭建开发环境 网上有太多的开发环境的详细文章,并且window开发环境包都封装好了,按着顺序一步步来,基本没有问题,这里说明一下需要安装的内容: 编译器,常常是mingw编译器,可去官网下载.安装 ...

  7. QT入门之UI设计界面

    QT入门之UI设计界面 在UI设计界面中,可以观察到属性编辑器实际上就是对派生类的各个成员数据进行赋值.因为QLineEdit继承自QWidget,QWidget又继承自QObject,所以可以看出属 ...

  8. 树莓派python界面qt_树莓派QT入门教程——使用Qt开发界面程序控制GPIO

    树莓派QT入门教程--使用Qt开发界面程序控制GPIO 玩转树莓派2017-07-12 12:36 树莓派入门教程--使用Qt开发界面程序 前言 Qt是一个1991年由奇趣科技开发的跨平台C++图形用 ...

  9. opic4:Qt入门之常用qt控件认知之Button系列

    opic4:Qt入门之常用qt控件认知之Button系列 2013-06-27 18:21:54 标签:QAbstractButton QPushButton QRadioButton 原创作品,允许 ...

最新文章

  1. Kotlin let、with、run、apply、also函数的使用
  2. 上下文菜单Context Menu
  3. 03:Poor Herobrine 直接插入排序
  4. python自带的数据库_Python小白的数据库入门
  5. cfb为什么不需要填充_为什么很多高中生数学成绩不理想,需要补课?因为不熟练啊!...
  6. CDH4.0安装及配置(二)配置网易yum源
  7. CentOS 7/8 安装 oniguruma 和 oniguruma-devel
  8. SharePoint Framework 企业向导(三)
  9. 后副车架焊接机器人_焊接机器人的工装设计和工装的使用方法
  10. 【液晶模块系列基础视频】3.2fatfs接口函数的使用2
  11. c#.net常用函数列表
  12. 百度竞价文章怎么写?
  13. 自动生成条形码软件如何批量打印可变条码
  14. arn-linux-gcc编译失败,arm-linux-gnueabihf-gcc交叉编译可执行程序失败的一种处理办法...
  15. sql 时间的模糊查询
  16. Excel常用技巧—数字和文本转换,三种方法任你选!!
  17. Unity - Timeline 之 Muting tracks(屏蔽轨道)
  18. pytorch提供的maskrcnn训练自己的数据
  19. linux下获取微秒级精度的时间
  20. 元旦节前后,Python兼职接单的小高潮来了

热门文章

  1. egg使用egg-socket.io
  2. 群晖 | ESXI下安装群晖NAS,可安装至6.17版本,6.2版本无法使用此方法。
  3. Getter和Setter的介绍
  4. 《程序员面试金典(第6版)》面试题 08.14. 布尔运算(动态规划,分治,递归,难度hard++)
  5. 虫师selenium3+python自动化测试电子版_Selenium3.0 自动化测试
  6. 迁出X86架构,你准备好了吗?
  7. win10笔记本显示网络正常,但是无法使用QQ、微信、不能浏览网页,怎么办?
  8. Docker保姆级学习教程
  9. linux网卡掉包或挂掉解决办法
  10. SpringBoot实战系列之发送短信验证码