『QT』窗口 (一)

个人博客地址

|----------------------------------------|
| 个人博客: 花开富贵 |

文章目录

  • 个人博客地址
    • [1 窗口介绍](#1 窗口介绍)
    • [2 Menu Bar 菜单栏](#2 Menu Bar 菜单栏)
      • [2.1 创建菜单栏](#2.1 创建菜单栏)
      • [2.2 创建菜单](#2.2 创建菜单)
      • [2.3 添加菜单项](#2.3 添加菜单项)
      • [2.4 添加子菜单](#2.4 添加子菜单)
      • [2.5 为菜单, 菜单项添加分隔线](#2.5 为菜单, 菜单项添加分隔线)
      • [2.6 菜单项的信号](#2.6 菜单项的信号)
      • [2.7 为菜单, 菜单项添加快捷键](#2.7 为菜单, 菜单项添加快捷键)
      • [2.7 为菜单, 菜单项设置图标](#2.7 为菜单, 菜单项设置图标)
    • [3 Tool Bar 工具栏](#3 Tool Bar 工具栏)
      • [3.1 创建工具栏](#3.1 创建工具栏)
      • [3.2 添加快捷项](#3.2 添加快捷项)
      • [3.3 工具栏的浮动与停靠](#3.3 工具栏的浮动与停靠)
      • [3.4 设置图标](#3.4 设置图标)
    • [4 Status Bar 状态栏](#4 Status Bar 状态栏)
      • [4.1 状态栏的创建](#4.1 状态栏的创建)
      • [4.2 状态栏添加内容](#4.2 状态栏添加内容)
        • [4.2.1 从右往左放置](#4.2.1 从右往左放置)
        • [4.2.2 显示状态信息](#4.2.2 显示状态信息)

1 窗口介绍

在以往的博客中, 常常一QWidget类进行示例, 而通常情况下, 大部分的窗口都是由QMainWindow类进行的实现, 而QWidget通常以一个子控件(自定义控件)镶嵌在QMainWindow之中;

通常一个QMainWindow布局包含一个WindowTitle窗口标题(通常为系统默认), 一个菜单栏Menu Bar, 多个工具栏Tool Bars, 多个浮动窗口Dock Widgets(铆接部件, 可以认为是Tool BarCentral Widget的粘合剂), 一个状态栏Status Bar以及最中心的中心部件Central Widget;

如下图所示:


通常很多软件都会有一个菜单栏, 来赋予一些程序应有的一些功能;

通常一个窗口只会有一个菜单栏Menu Bar, 菜单栏中可以添加菜单, 菜单可以为菜单添加菜单项, 菜单项内可以添加子菜单项;

通常情况下, 主窗口中最多只能有一个菜单栏, 数量为[0, 1], 即可以有也可以没有, 若是有菜单栏的话, 那只能拥有一个菜单栏;

菜单栏通常由QMainWindow类提供的menuBar()来实现;


2.1 创建菜单栏

创建菜单通常有两三种方式:

  1. 在堆中自动创建

    可以手动采用new的方式进行创建菜单栏;

    cpp 复制代码
    QMenuBar* menubar = new QMenuBar(this); // 创建MenuBar
    this->setMenuBar(menubar); // 设置MenuBar进当前窗口

    即 创建一个QMenuBar对象, 并指名其的父节点为this控件以更好进行内存管理;

  2. 使用函数创建

    除了直接在堆上开辟空间创建QMenuBar以外, 在QMainWindow中提供了一个专门创建QMenuBar的函数;

    cpp 复制代码
    QMenuBar *menuBar() const;

    使用方式为:

    cpp 复制代码
    QMenuBar *menubar = this->menuBar(); // 当前窗口是否有menubar, 有则获取, 无则创建并设置进对象树
  3. 使用QtDesigner创建菜单栏

    通常情况下, 当存在UI文件时将默认存在QMenuBar菜单栏;

    可以看到, 可以完全采用QtDesigner来构建菜单, 菜单项, 甚至是子菜单项;

    可能使用QtDesigner来构建菜单或许会有一些Bug, 如菜单项无法使用中文创建或是其他

通常情况下, 若是用代码来创建菜单栏时, 我们推荐使用第二种方式来创建Menubar, 本质原因是, 在上文中我们提到, 在一个窗口内, 最多只能拥有一个Menubar;

而在QtCreator中, 我们可以勾选是否建立UI文件;

当勾选上时, 对应的界面文件中, 将会自带一个QMenuBar;

而当使用setMenuBar()后, 由于原先的Menubar我们无法在替换后再次获取他的指针, 因此无法对其进行销毁释放内存(替换后, 原有的Menubar无法被管理), 从而导致内存泄漏;

若是该窗口是一个高频被打开后销毁的窗口, 将促成严重的内存泄漏问题;

而第二种方式直接调用QMainWindow提供的menuBar(), 当若是该窗口内存在菜单栏时将获取当前窗口内的菜单栏, 若是没有则创建一个菜单栏QMenuBar;

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QMenuBar* menuBar = this->menuBar();
}

运行程序结果为:


2.2 创建菜单

可以看到实际上上文所展出的结果并没有菜单栏;

而通常情况, 菜单通常要伴随着菜单才可以显示;

Qt中, 通常使用addMenu()来为菜单栏添加菜单;

该函数有两种调用方式(重载):

  1. addMenu(QString)
  2. addMenu(QMenu*)

无论哪种方式都会将QMenu设置在自己的对象树中, 因此在创建QMenu时无需指名父对象;

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 创建菜单栏 - 没有就创建并设置进窗口
    QMenuBar* menuBar = this->menuBar();

    // 创建菜单
    QMenu* menu1 = new QMenu("文件");
    QMenu* menu2 = new QMenu("编辑");
    QMenu* menu3 = new QMenu("视图");

    // 将菜单设置进菜单栏
    menuBar->addMenu(menu1);
    menuBar->addMenu(menu2);
    menuBar->addMenu(menu3);
}

运行结果为:


2.3 添加菜单项

在上文中, 提到, 我们可以对菜单设置对应的菜单项;

通常情况下, 我们采用addAction来为添加菜单项;

在以往中, 当控件存在子控件时, 对应的子控件命名方式往往采用xxxItem的命名方式, 但针对菜单项而言其所使用的是QAction类, 并且通过addAction()方法来添加菜单项;

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /*
     * 创建菜单栏 - 没有就创建并设置进窗口
     */
    QMenuBar* menuBar = this->menuBar();

    /*
     * 创建菜单
     */
    QMenu* menu1 = new QMenu("文件");
    QMenu* menu2 = new QMenu("编辑");
    QMenu* menu3 = new QMenu("视图");

    /*
     * 将菜单设置进菜单栏
     */
    menuBar->addMenu(menu1);
    menuBar->addMenu(menu2);
    menuBar->addMenu(menu3);

    /*
     * 创建菜单项
     */
    // 写法1
    QAction* action1 = new QAction("保存");
    menu1->addAction(action1);
    // 写法2
    menu1->addAction("另存为");
    menu1->addAction("打开");
}

运行结果为:


2.4 添加子菜单

Qt中, 可以对一个菜单中添加子菜单, 即 将一个子菜单作为他的菜单项加入进去;

通常同样采用addMenu的方式进行添加;

同样的, 可以对这个子菜单来添加对应的QAction;

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /*
     * 创建菜单栏 - 没有就创建并设置进窗口
     */
	// ...

    /*
     * 创建菜单
     */
	// ...

    /*
     * 将菜单设置进菜单栏
     */
	// ...

    /*
     * 创建菜单项
     */
	// ...

    /*
     * 添加子菜单
     */
    QMenu* menu1_1 = new QMenu("最近打开");
    menu1->addMenu(menu1_1);

    /*
     * 为子菜单添加菜单项
     */
    menu1_1->addAction("./Hello.txt");
    menu1_1->addAction("./World.rar");
}

运行结果为:


2.5 为菜单, 菜单项添加分隔线

添加分隔线通常主要通过addSeparator()进行;

可以为菜单, 菜单项来添加分隔线;

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /*
     * 创建菜单栏 - 没有就创建并设置进窗口
     */
    QMenuBar* menuBar = this->menuBar();

    /*
     * 创建菜单
     */
    QMenu* menu1 = new QMenu("文件");
    QMenu* menu2 = new QMenu("编辑");
    QMenu* menu3 = new QMenu("视图");

    /*
     * 将菜单设置进菜单栏
     */
    menuBar->addMenu(menu1);
    menuBar->addSeparator(); // 添加分隔线
    menuBar->addMenu(menu2);
    menuBar->addSeparator(); // 添加分隔线
    menuBar->addMenu(menu3);

    /*
     * 创建菜单项
     */
    // 写法1
    QAction* action1 = new QAction("保存");
    menu1->addAction(action1);
    // 写法2
    menu1->addSeparator(); // 添加分隔线
    menu1->addAction("另存为");
    menu1->addSeparator(); // 添加分隔线
    menu1->addAction("打开");
    menu1->addSeparator(); // 添加分隔线

    /*
     * 添加子菜单
     */
    QMenu* menu1_1 = new QMenu("最近打开");
    menu1->addMenu(menu1_1);

    /*
     * 为子菜单添加菜单项
     */
    menu1_1->addAction("./Hello.txt");
    menu1_1->addSeparator(); // 添加分隔线
    menu1_1->addAction("./World.rar");
}

运行结果为:

可以看到, 我们在菜单与菜单间中添加了Separator, 但并未显示, 本质是与系统内置的样式有关;


2.6 菜单项的信号

菜单项作为一个可点击控件, 同样有其对应的信号;

通常最常用的信号为triggered(bool checked=false);

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    
	// ...
    /*
     * 绑定槽函数
     */
    connect(action1, &QAction::triggered, this, &MainWindow::triggeredHandler);
}

void MainWindow::triggeredHandler()
{
    qDebug()<<"保存";
}

运行结果为:


2.7 为菜单, 菜单项添加快捷键

在之前的文章中, 我们采用过ShortCut设置对应的快捷键, 同样的, 我们也可以为菜单/菜单项设置快捷键, 当然可以用ShortCut进行绑定, 但针对菜单而言, 其有更加简便的方式进行操作;

通常只需要在菜单/菜单项添加文本的部分增加一个(&Key)即可;

cpp 复制代码
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("编辑 (&E)");
    QMenu* menu3 = new QMenu("视图 (&V)");

    /*
     * 将菜单设置进菜单栏
     */
    menuBar->addMenu(menu1);
    menuBar->addSeparator(); // 添加分隔线
    menuBar->addMenu(menu2);
    menuBar->addSeparator(); // 添加分隔线
    menuBar->addMenu(menu3);

    /*
     * 创建菜单项
     */
    // 写法1
    QAction* action1 = new QAction("保存 (&S)");
    menu1->addAction(action1);
    menu1->addSeparator(); // 添加分隔线
    // 写法2
    menu1->addAction("另存为 (&A)");
    menu1->addSeparator(); // 添加分隔线
    menu1->addAction("打开 (&O)");
    menu1->addSeparator(); // 添加分隔线

    /*
     * 添加子菜单
     */
    QMenu* menu1_1 = new QMenu("最近打开");
    menu1->addMenu(menu1_1);

    /*
     * 为子菜单添加菜单项
     */
    menu1_1->addAction("./Hello.txt");
    menu1_1->addSeparator(); // 添加分隔线
    menu1_1->addAction("./World.rar");

    connect(action1, &QAction::triggered, this, &MainWindow::triggeredHandler);
}

void MainWindow::triggeredHandler()
{
    qDebug()<<"保存";
}

运行结果为:

当快捷键设置后, 可以通过Alt+对应的快捷键进行使用;


2.7 为菜单, 菜单项设置图标

同样的, 可以为菜单, 菜单项通过setIcon方法对其设置对应的图标, 以增加可用性与增加美观;

可以提前去阿里巴巴矢量图标库中下载对应的Icon并设置QRC资源文件;

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
	// ...
    
     /*
     * 添加Icon
     */
    menu1->setIcon(QIcon(":/file.png"));
    action1->setIcon(QIcon(":/save.png"));
}

运行结果:

可以看到, 在设置Icon后, 菜单中的文字标题将会消失不见, 本质上将会被Icon给顶替, 而这种顶替不一定代表一定消失, 在某些系统下, 这些被Icon代替的标题文字将会以ToolTip存在;

也可以手动为对应的菜单或是菜单项设置ToolTip, 此次不做演示;


3 Tool Bar 工具栏

工具栏通常为菜单栏的简化版, 在许多的应用中, 总是会将常用或者主要的菜单功能放置在工具栏中以方便使用;

这里以轻量级编辑器Notepad--为例:

其中红色部分即为工具栏(QToolBar);

工具栏中所存在的各个Icon即为快捷项QAction;


3.1 创建工具栏

通常情况下, 工具栏在QMainWindow中是没有的, 若是需要工具栏需要手动去创建;

创建工具栏时, 采用new的方式创建并通过addToolBar函数将工具栏设置进QMainWindow中, 或者可以直接调用QMainWindow所给的addToolBar(QString)进行创建;

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /*创建工具栏*/
    QToolBar* toolbar1 = new QToolBar();
    QToolBar* toolbar2 = new QToolBar();

    /*设置工具栏*/
    this->addToolBar(toolbar1);
    this->addToolBar(toolbar2);
}

这里直接采用new的方式并调用addToolBar设置对应的工具栏;

运行结果为:

从运行结果来看, 这段代码并没有报错, 可以成功编译并运行;

本质上在QMainWindow中, 可以存在0~NQToolBar;


3.2 添加快捷项

运行结果中的工具栏显示的并不明显, 本质上与QMenuBar相同, 其没有对应的QAction进行填充, 因此显得比较不明显;

现在分别为两个QToolBar填充对应的QAction;

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /*创建工具栏*/
    QToolBar* toolbar1 = new QToolBar();
    QToolBar* toolbar2 = new QToolBar();

    /*设置工具栏*/
    this->addToolBar(toolbar1);
    this->addToolBar(toolbar2);

    /*创建QAction*/
    QAction* action1 = new QAction("Action1");
    QAction* action2 = new QAction("Action2");
    QAction* action3 = new QAction("Action3");
    QAction* action4 = new QAction("Action4");

    /*设置快捷项*/
    toolbar1->addAction(action1);
    toolbar1->addAction(action2);
    toolbar2->addAction(action3);
    toolbar2->addAction(action4);
}

运行结果为:


3.3 工具栏的浮动与停靠

可以看到, 实际上在工具栏的侧边, 有一个可拖动标识, 表示可以对其进行拖动;

默认情况下, 工具栏支持浮动与停靠;

  • 停靠

    停靠即为停靠在窗口的边界, 边界通常分为上下左右四个边界;

    默认情况下, ToolBar停靠在MainWindow的顶部, 但是可以通过属性设置其可以停靠的位置;

  • 浮动

    当工具栏未停靠在任何一个部分时, 称之为浮动状态;

可以为对应的工具栏设置以下属性:

  • setMoveable - 是否可拖动

    无论是浮动还是拖动停靠四周, 都建立在可拖动的基础上, 当该属性被禁用时, 工具栏将无法拖动;

    通常使用QToolBar::setMoveable(bool)来设置改属性;

    cpp 复制代码
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        /*创建工具栏*/
        QToolBar* toolbar1 = new QToolBar();
        QToolBar* toolbar2 = new QToolBar();
    
        /*设置工具栏*/
        this->addToolBar(toolbar1);
        this->addToolBar(toolbar2);
    
        /*创建QAction*/
        QAction* action1 = new QAction("Action1");
        QAction* action2 = new QAction("Action2");
        QAction* action3 = new QAction("Action3");
        QAction* action4 = new QAction("Action4");
    
        /*设置快捷项*/
        toolbar1->addAction(action1);
        toolbar1->addAction(action2);
        toolbar2->addAction(action3);
        toolbar2->addAction(action4);
    
        /*设置不可拖动*/
        toolbar1->setMovable(false);
        toolbar2->setMovable(false);
    }

    运行结果为:

    从结果来看, 当该属性设置为false时, 可拖动标识消失, 为不可拖动;

  • setFloatable - 是否浮动

    可以使用 setFloatable(bool)来设置工具栏是否可浮动;

    true时表示可浮动, 默认为可浮动状态, false表示无法浮动;

    cpp 复制代码
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        /*创建工具栏*/
        QToolBar* toolbar1 = new QToolBar();
        QToolBar* toolbar2 = new QToolBar();
    
        /*设置工具栏*/
        this->addToolBar(toolbar1);
        this->addToolBar(toolbar2);
    
        /*创建QAction*/
        QAction* action1 = new QAction("Action1");
        QAction* action2 = new QAction("Action2");
        QAction* action3 = new QAction("Action3");
        QAction* action4 = new QAction("Action4");
    
        /*设置快捷项*/
        toolbar1->addAction(action1);
        toolbar1->addAction(action2);
        toolbar2->addAction(action3);
        toolbar2->addAction(action4);
    
        /*设置不可浮动*/
        toolbar1->setFloatable(false);
        toolbar2->setFloatable(false);
    }

    运行结果为:

  • 停靠位置

    停靠位置的设置通常有两种方式进行设置, 一种是在通过addToolBar时进行传参, 另一种方式为通过QToolBar提供的setAllowerAreas进行设置;

    停靠的位置分别为上下左右;

    枚举值 说明
    Qt::LeftToolBarArea 停靠在左侧
    Qt::RightToolBarArea 停靠在右侧
    Qt::TopToolBarArea 停靠在顶部
    Qt::BottomToolBarArea 停靠在底部
    Qt::AllToolBarAreas 上下左右均可停靠(设置默认停靠时不能传这个参数)

    这些枚举值以二进制的顺序进行枚举, 以方便在设置停靠位置时可以通过位运算进行设置(单参多用);

    cpp 复制代码
        enum ToolBarArea {
            LeftToolBarArea = 0x1,
            RightToolBarArea = 0x2,
            TopToolBarArea = 0x4,
            BottomToolBarArea = 0x8,
    
            ToolBarArea_Mask = 0xf,
            AllToolBarAreas = ToolBarArea_Mask,
            NoToolBarArea = 0
        };

    当停靠位置为多个时采用按位或|的方式进行设置;

    1. addToolBar传参(默认停靠位置)

    传参的方式为:

    cpp 复制代码
    addToolBar(Qt::ToolBarArea, QToolBar*)

    第一个参数为位置, 第二个参数为工具栏;

    cpp 复制代码
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        /*创建工具栏*/
        QToolBar* toolbar1 = new QToolBar();
        QToolBar* toolbar2 = new QToolBar();
    
        /*设置工具栏*/
        this->addToolBar(Qt::LeftToolBarArea, toolbar1);
        this->addToolBar(Qt::RightToolBarArea, toolbar2);
    
        /*创建QAction*/
        QAction* action1 = new QAction("Action1");
        QAction* action2 = new QAction("Action2");
        QAction* action3 = new QAction("Action3");
        QAction* action4 = new QAction("Action4");
    
        /*设置快捷项*/
        toolbar1->addAction(action1);
        toolbar1->addAction(action2);
        toolbar2->addAction(action3);
        toolbar2->addAction(action4);
    }

    运行结果为:


    2. setToolBarArea(允许停靠位置)

    该函数用来设置工具栏的允许停靠位置, 传参为上述的枚举值, 当存在多参情况下采用按位或|的形式进行;

    cpp 复制代码
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        /*创建工具栏*/
        QToolBar* toolbar1 = new QToolBar();
        QToolBar* toolbar2 = new QToolBar();
    
        /*设置工具栏*/
        this->addToolBar(toolbar1);
        this->addToolBar(toolbar2);
    
        /*创建QAction*/
        QAction* action1 = new QAction("Action1");
        QAction* action2 = new QAction("Action2");
        QAction* action3 = new QAction("Action3");
        QAction* action4 = new QAction("Action4");
    
        /*设置快捷项*/
        toolbar1->addAction(action1);
        toolbar1->addAction(action2);
        toolbar2->addAction(action3);
        toolbar2->addAction(action4);
    
        /*设置允许停靠位置*/
        toolbar1->setAllowedAreas(Qt::RightToolBarArea|Qt::LeftToolBarArea);
        toolbar2->setAllowedAreas(Qt::RightToolBarArea|Qt::LeftToolBarArea); // 只允许停靠在左侧或是右侧
    }

    运行结果为:


3.4 设置图标

工具栏的快捷项同样可以设置图标, 其设置图标的方式与上文中提到的菜单/菜单项所设置图标的方式如出一辙;

cpp 复制代码
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("保存");
    QAction *action3 = new QAction("另存为");
    toolbar->addActions({action1, action2, action3}); // 采用QList的传参方式

    /*设置图标*/
    action1->setIcon(QIcon(":/open.png"));
    action2->setIcon(QIcon(":/save.png"));
    action3->setIcon(QIcon(":/saveas.png"));
}

运行结果为:

从运行结果可以看到, 在工具栏中对快捷项设置图标, 对应的原文本同样会被Icon所覆盖, 但其对应的文本标题将以ToolTip的形式存在;


4 Status Bar 状态栏

状态栏通常在程序的最下方, 用于显示对应的状态;

Notepad--为例:

状态栏与菜单栏QMenuBar相同, 一个程序中的状态栏至多只能有一个, 且通常情况下, 当勾选UI文件生成后, 对应的将自动生成一个QStatusBar状态栏;


4.1 状态栏的创建

主流的状态栏的创建方式同样分为两种:

  1. QMainWindow提供的statusBar()

    使用该方式创建时, 若是不存在状态栏则创建并设置, 存在则获取;

    cpp 复制代码
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        /*设置状态栏 一*/
        QStatusBar* statusbar = this->statusBar();
    }
  2. new一个QStatusBar对象

    通过new在堆空间中创建一个QStatusBar对象, 并采用setStatusBar()设置进QMainWindow中;

    cpp 复制代码
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
            
        /*设置状态栏 二*/
        QStatusBar* statusbar = new QStatusBar();
        this->setStatusBar(statusbar);
    }

运行结果为:

从结果可以看出, 与QMenuBar行为相同, 当对应的QStatusBar中没有内容时, 将不显示;


4.2 状态栏添加内容

状态栏可以添加任意内容, 包括但不限于, 控件, 文本, 空白占位;

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /*设置状态栏 二*/
    QStatusBar* statusbar = new QStatusBar();
    this->setStatusBar(statusbar);

    /*添加内容*/
    QPushButton *button = new QPushButton("click me", this);
    statusbar->addWidget(button); // 按钮
    QLabel *label = new QLabel("这是StatusBar中的QLabel", this);
    statusbar->addWidget(label); // 标签
    QProgressBar *progress = new QProgressBar(this);
    progress->setValue(60);
    statusbar->addWidget(progress); // 进度条
}

运行结果为:

QStatusBar中设置控件时可以为其设置对应的拉伸系数;

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /*设置状态栏 二*/
    QStatusBar* statusbar = new QStatusBar();
    this->setStatusBar(statusbar);

    /*添加内容*/
    QPushButton *button = new QPushButton("click me", this);
    statusbar->addWidget(button,1/*拉伸系数*/); // 按钮
    QLabel *label = new QLabel("这是StatusBar中的QLabel", this);
    statusbar->addWidget(label,2); // 标签
    QProgressBar *progress = new QProgressBar(this);
    progress->setValue(60);
    statusbar->addWidget(progress,2); // 进度条
}

运行结果为:


4.2.1 从右往左放置

上文中提到的放置方式, 即addWidget为从左往右的放置方式, 除此之外还可以通过由右向左的放置方式进行放置;

通常使用addPermanentWidget进行放置;

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /*设置状态栏 二*/
    QStatusBar* statusbar = new QStatusBar();
    this->setStatusBar(statusbar);

    /*添加内容(从右往左)*/
    QPushButton *button = new QPushButton("click me", this);
    statusbar->addPermanentWidget(button); // 按钮 (从右往左)
    QLabel *label = new QLabel("这是StatusBar中的QLabel", this);
    statusbar->addWidget(label); // 标签 (从左往右)
    QProgressBar *progress = new QProgressBar(this);
    progress->setValue(60);
    statusbar->addWidget(progress); // 进度条 (从左往右)
}

运行结果为:


4.2.2 显示状态信息

除了添加控件以外, QStatusBar可以添加状态信息的显示;

通常采用QStatusBar::showMessage(QString)进行显示;

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /*设置状态栏 二*/
    QStatusBar* statusbar = new QStatusBar();
    this->setStatusBar(statusbar);

    /*显示状态栏信息*/
    statusbar->showMessage("这是状态栏"); // 状态栏信息

    /*添加内容(从右往左)*/
    QPushButton *button = new QPushButton("click me", this);
    statusbar->addPermanentWidget(button); // 按钮
    QLabel *label = new QLabel("这是StatusBar中的QLabel", this);
    statusbar->addPermanentWidget(label); // 标签
    QProgressBar *progress = new QProgressBar(this);
    progress->setValue(60);
    statusbar->addPermanentWidget(progress); // 进度条
}

运行结果为:

除此之外, 可以为这个状态栏信息进行定时, 即显示多久, 单位为ms;

cpp 复制代码
    /*显示状态栏信息*/
    statusbar->showMessage("这是状态栏", 3000/*设置timeout*/); // 状态栏信息

运行结果为:

(这里不是循环显示, 循环的是gif不是程序 - orz)

可以看到在一定时间后, Tips提示将会消失;

其次是当一个程序的StatusBar中存在控件内容和状态信息时, 需要注意他们的位置信息与前后顺序, 否则将会出现显示错误, 由于这段代码显示状态信息时对应的控件是由右向左进行插入, 而若是从左往右插入, 将会与状态信息发生冲突;

  • 情况一

    cpp 复制代码
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        /*获取状态栏*/
        QStatusBar* statusbar = this->statusBar();
    
        /*定义控件*/
        QLabel *label = new QLabel("这是一个QLabel");
        QPushButton *button = new QPushButton("这是一个Button");
    
        /*情况 一*/
        statusbar->showMessage("这是showMessage显示信息");
        statusbar->addWidget(button);
        statusbar->addWidget(label);
    }

    运行结果为:

    控件由左向右插入时, 状态信息先于控件显示, 控件被覆盖;

  • 情况二

    cpp 复制代码
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        /*获取状态栏*/
        QStatusBar* statusbar = this->statusBar();
    
        /*定义控件*/
        QLabel *label = new QLabel("这是一个QLabel");
        QPushButton *button = new QPushButton("这是一个Button");
    
        /*情况 二*/
        statusbar->addWidget(button);
        statusbar->addWidget(label);
        statusbar->showMessage("这是showMessage显示信息");
    }

    运行结果为:

    控件由左向右插入时, 控件先于状态信息插入, UI显示错乱;

  • 情况三

    cpp 复制代码
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        /*获取状态栏*/
        QStatusBar* statusbar = this->statusBar();
    
        /*定义控件*/
        QLabel *label = new QLabel("这是一个QLabel");
        QPushButton *button = new QPushButton("这是一个Button");
    
        /*情况 三*/
        statusbar->showMessage("这是showMessage显示信息");
        statusbar->addPermanentWidget(button);
        statusbar->addPermanentWidget(label);
    }

    运行结果为:

    控件由右向左插入时, 状态信息先于控件显示, 无影响;

    且当showMessage调用时, 控件由右向左插入, 无论其先后顺序, 均无影响;

由此得知, 当需要调用showMessage与控件并存时, 控件需要由右向左插入;

相关推荐
q***783732 分钟前
SQL实现md5加密方法
数据库·sql
APIshop35 分钟前
Python 零基础写爬虫:一步步抓取商品详情(超细详解)
开发语言·爬虫·python
q***614144 分钟前
Spring中Aware的用法以及实现
java·数据库·spring
红树林071 小时前
渗透测试之sql注入--报错注入
数据库·sql·安全·web安全
AI科技星1 小时前
为什么宇宙无限大?
开发语言·数据结构·经验分享·线性代数·算法
菜鸟小九1 小时前
mysql(锁)
数据库·mysql·oracle
c***42101 小时前
【Sql Server】随机查询一条表记录,并重重温回顾下自定义函数的封装和使用
数据库·性能优化
Appreciate(欣赏)1 小时前
JAVA使用poi类读取xlxs文件内容拼接成添加数据SQL
java·开发语言·sql
oioihoii2 小时前
性能提升11.4%!C++ Vector的reserve()方法让我大吃一惊
开发语言·c++