[Qt]控件

news2024/11/24 13:42:28

文章摘于 爱编程的大丙

文章目录

  • 1. 按钮类型控件
    • 1.1 按钮基类 QAbstractButton
      • 1.1.1 标题和图标
      • 1.1.2 按钮的 Check 属性
      • 1.1.3 信号
      • 1.1.4 槽函数
    • 1.2 QPushButton
      • 1.2.1 常用API
      • 1.2.2 按钮的使用
    • 1.3 QToolButton
      • 1.3.1 常用API
      • 1.3.2 按钮的使用
    • 1.4 QRadioButton
      • 1.4.1 常用API
      • 1.4.2 按钮的使用
    • 1.5 QCheckBox
      • 1.5.1 常用API
      • 1.5.2 按钮的使用
  • 2. 容器类型控件
    • 2.1 QWidget
    • 2.2 Frame
      • 2.2.1 相关API
      • 2.2.2 属性设置
    • 2.3 Group Box
      • 2.3.1 相关API
      • 2.3.2 属性设置
    • 2.4 Scroll Area
      • 2.4.1 相关API
      • 2.4.2 属性设置
      • 2.4.3 窗口的动态添加和删除
    • 2.5 Tool Box
      • 2.5.1 相关API
      • 2.5.2 属性设置
    • 2.6 Tab Widget
      • 2.6.1 相关API
      • 2.6.2 属性设置
      • 2.6.3 控件使用
    • 2.7 Stacked Widget
      • 2.7.1 相关API
      • 2.7.2 属性设置
      • 2.7.3 控件使用


1. 按钮类型控件

1.1 按钮基类 QAbstractButton

在QT中为我们提供了可以直接使用的按钮控件, 如下图。这些按钮种类虽然繁多, 但是它们都拥有相同的父类QAbstractButton。这些子类按钮的大部分属性都是从这个基类继承的,因此搞明白这个类为我们提供的相关功能还是非常重要的。
其中Dialog Button Box比较特殊不是一个单一控件, 它是两个QPushButton的组合并且水平排列,这个不能作为一个新控件来研究。

在这里插入图片描述

这些按钮控件之间的继承关系如下图:

在这里插入图片描述

介绍一下QAbstractButton中的一些常用API


1.1.1 标题和图标

// 参数text的内容显示到按钮上
void QAbstractButton::setText(const QString &text);
// 得到按钮上显示的文本内容, 函数的返回就是
QString QAbstractButton::text() const;

// 得到按钮设置的图标
QIcon icon() const;
// 给按钮设置图标
void setIcon(const QIcon &icon);

// 得到按钮图标大小
QSize iconSize() const
// 设置按钮图标的大小
[slot]void setIconSize(const QSize &size);

1.1.2 按钮的 Check 属性

对应按钮来说, 一般有三种常见状态, 分别为: Normal, Hover, Pressed

  • Normal: 普通状态, 没有和鼠标做任何接触
  • Hover: 悬停状态, 鼠标位于按钮之上, 但是并未按下
  • Pressed: 按压状态,鼠标键在按钮上处于按下状态

默认情况下, 鼠标在按钮上按下, 按钮从 Normal 切换到 Pressed状态, 鼠标释放, 按钮Pressed恢复到Normal状态。
当我们给按钮设置了 check 属性之后,情况就有所不同了, 在按钮上释放鼠标键, 按钮依然会处在 Pressed状态, 再次点击按钮, 按钮才能恢复到 Normal 状态。具有check属性的按钮就相当于一个开关,每点击一次才能实现一次状态的切换。

// 判断按钮是否设置了checkable属性, 如果设置了点击按钮, 按钮一直处于选中状态
// 默认这个属性是关闭的, not checkable
bool QAbstractButton::isCheckable() const;
// 设置按钮的checkable属性
// 参数为true: 点击按钮, 按钮被选中, 松开鼠标, 按钮不弹起
// 参数为false: 点击按钮, 按钮被选中, 松开鼠标, 按钮弹起
void QAbstractButton::setCheckable(bool);

    
// 判断按钮是不是被按下的选中状态
bool QAbstractButton::isChecked() const;
// 设置按钮的选中状态: true-选中, false-没选中
// 设置该属性前, 必须先进行 checkable属性的设置
void QAbstractButton::setChecked(bool);

1.1.3 信号

这些信号都按钮被点击之后发射出来的, 只是在细节上有细微的区别, 其中最常用的是 clicked()
通过鼠标的不同瞬间状态可以发射出pressed()released() 信号, 如果鼠标设置了 check 属性, 一般通过toggled()信号判断当前按钮是选中状态还是非选中状态。

/*
当按钮被激活时(即,当鼠标光标在按钮内时按下然后释放),当键入快捷键时,或者当click()或animateClick()被调用时,这个信号被发出。值得注意的是,如果调用setDown()、setChecked()或toggle(),则不会触发此信号。
*/
[signal] void QAbstractButton::clicked(bool checked = false);
// 在按下按钮的时候发射这个信号
[signal] void QAbstractButton::pressed();
// 在释放这个按钮的时候发射直观信号
[signal] void QAbstractButton::released();
// 每当可检查按钮改变其状态时,就会发出此信号。checked在选中按钮时为true,在未选中按钮时为false。
[signal] void QAbstractButton::toggled(bool checked);

1.1.4 槽函数

// 执行一个动画点击:按钮被立即按下,并在毫秒后释放(默认是100毫秒)。
[slot] void QAbstractButton::animateClick(int msec = 100);
// 执行一次按钮点击, 相当于使用鼠标点击了按钮
[slot] void QAbstractButton::click();

// 参考 1.2 中的函数介绍
[slot] void QAbstractButton::setChecked(bool);
// 设置按钮上图标大小
[slot]void setIconSize(const QSize &size);
// 切换可检查按钮的状态。 checked <==> unchecked
[slot] void QAbstractButton::toggle();

了解了基类提供的功能之后, 下边着重给大家介绍一下按钮组中常用的几这个按钮控件: QPushButton, QToolButton, QRadioButton, QCheckBox


1.2 QPushButton

1.2.1 常用API

这种类型的按钮是Qt按钮中使用频率最高的一个, 对这个类进行操作, 大部分时候都需要使用它从父类继承过来的那些 API。
QPushButton类中, 比较常用的一些API函数如下:

// 构造函数
/*
参数:
    - icon: 按钮上显示的图标
    - text: 按钮上显示的标题
    - parent: 按钮的父对象, 可以不指定
*/
QPushButton::QPushButton(const QIcon &icon, const QString &text, QWidget *parent = nullptr);
QPushButton::QPushButton(const QString &text, QWidget *parent = nullptr);
QPushButton::QPushButton(QWidget *parent = nullptr);

// 判断按钮是不是默认按钮
bool isDefault() const;
// 一般在对话框窗口中使用, 将按钮设置为默认按钮, 自动关联 Enter 键 
void setDefault(bool);

/*
将弹出菜单菜单与此按钮关联起来。这将把按钮变成一个菜单按钮,
在某些样式中会在按钮文本的右边产生一个小三角形。
*/
void QPushButton::setMenu(QMenu *menu);

/*
显示(弹出)相关的弹出菜单。如果没有这样的菜单,这个函数什么也不做。
这个函数直到弹出菜单被用户关闭后才返回。
*/
[slot] void QPushButton::showMenu();

1.2.2 按钮的使用

通过API的介绍, 我们可以知道, 使用QPushButton这种类型的按钮, 有三种使用方式:

  • 作为普通按钮, 可以显示文本信息和图标
  • 设置check属性, 使其可以处于持续的被选中状态
  • 关联一个菜单, 点击按钮菜单弹出

具体操作可以参考如下代码:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 普通按钮, 没有checked属性
    ui->normalBtn->setText("我是小猪佩奇");
    ui->normalBtn->setIcon(QIcon(":/Peppa-Pig.png"));
    ui->normalBtn->setIconSize(QSize(30, 30));
    connect(ui->normalBtn, &QPushButton::clicked, this, [=]()
    {
         qDebug() << "我是一个普通按钮, 图标是小猪佩奇...";
    });

    // 有checked属性的按钮
    ui->checkedBtn->setCheckable(true);
    connect(ui->checkedBtn, &QPushButton::toggled, this, [=](bool bl)
    {
         qDebug() << "我是一个checked按钮, 当前状态为:" << bl;
    });

    // 关联菜单
    ui->menuBtn->setText("你喜欢哪种美女?");
    QMenu* menu = new QMenu;
    QAction* act = menu->addAction("可爱的");
    menu->addAction("粘人的");
    menu->addAction("胸大的");
    menu->addAction("屁股翘的");
    ui->menuBtn->setMenu(menu);
    connect(act, &QAction::triggered, this, [=]{
        qDebug() << "我是一个可爱的女人, 今晚约吗?";
    });
}

1.3 QToolButton

1.3.1 常用API

这个类也是一个常用按钮类, 使用方法和功能跟QPushButton基本一致, 只不过在对于关联菜单这个功能点上, QToolButton类可以设置弹出的菜单的属性, 以及在显示图标的时候可以设置更多的样式, 可以理解为是一个增强版的QPushButton
QPushButton类相同的是, 操作这个按钮使用的大部分函数都是从父类QAbstractButton继承过来的。

/ 构造函数 /
QToolButton::QToolButton(QWidget *parent = nullptr);

/// 公共成员函数 ///
/*
    1. 将给定的菜单与此工具按钮相关联。
    2. 菜单将根据按钮的弹出模式显示。
    3. 菜单的所有权没有转移到“工具”按钮(不能建立父子关系)
*/
void QToolButton::setMenu(QMenu *menu);
// 返回关联的菜单,如果没有定义菜单,则返回nullptr。
QMenu *QToolButton::menu() const;

/*
弹出菜单的弹出模式是一个枚举类型: QToolButton::ToolButtonPopupMode, 取值如下:
    - QToolButton::DelayedPopup: 
        - 延时弹出, 按压工具按钮一段时间后才能弹出, 比如:浏览器的返回按钮
        - 长按按钮菜单弹出, 但是按钮的 clicked 信号不会被发射
    - QToolButton::MenuButtonPopup: 
        - 在这种模式下,工具按钮会显示一个特殊的箭头,表示有菜单。
	- 当按下按钮的箭头部分时,将显示菜单。按下按钮部分发射 clicked 信号
    - QToolButton::InstantPopup: 
        - 当按下工具按钮时,菜单立即显示出来。
        - 在这种模式下,按钮本身的动作不会被触发(不会发射clicked信号
*/
// 设置弹出菜单的弹出方式
void setPopupMode(QToolButton::ToolButtonPopupMode mode);
// 获取弹出菜单的弹出方式
QToolButton::ToolButtonPopupMode popupMode() const;

/*
QToolButton可以帮助我们在按钮上绘制箭头图标, 是一个枚举类型, 取值如下: 
    - Qt::NoArrow: 没有箭头
    - Qt::UpArrow: 箭头向上
    - Qt::DownArrow: 箭头向下
    - Qt::LeftArrow: 箭头向左
    - Qt::RightArrow: 箭头向右
*/
// 显示一个箭头作为QToolButton的图标。默认情况下,这个属性被设置为Qt::NoArrow。
void setArrowType(Qt::ArrowType type);
// 获取工具按钮上显示的箭头图标样式
Qt::ArrowType arrowType() const;

/ 槽函数 /
// 给按钮关联一个QAction对象, 主要目的是美化按钮
[slot] void QToolButton::setDefaultAction(QAction *action);
// 返回给按钮设置的QAction对象
QAction *QToolButton::defaultAction() const;

/*
图标的显示样式是一个枚举类型->Qt::ToolButtonStyle, 取值如下:
    - Qt::ToolButtonIconOnly: 只有图标, 不显示文本信息
    - Qt::ToolButtonTextOnly: 不显示图标, 只显示文本信息
    - Qt::ToolButtonTextBesideIcon: 文本信息在图标的后边显示
    - Qt::ToolButtonTextUnderIcon: 文本信息在图标的下边显示
    - Qt::ToolButtonFollowStyle: 跟随默认样式(只显示图标)
*/
// 设置的这个属性决定工具按钮是只显示一个图标、只显示文本,还是在图标旁边/下面显示文本。
[slot] void QToolButton::setToolButtonStyle(Qt::ToolButtonStyle style);
// 返回工具按钮设置的图标显示模式
Qt::ToolButtonStyle toolButtonStyle() const;


// 显示相关的弹出菜单。如果没有这样的菜单,这个函数将什么也不做。这个函数直到弹出菜单被用户关闭才会返回。
[slot] void QToolButton::showMenu();

1.3.2 按钮的使用

通过API的介绍, 我们可以知道, 使用QToolButton这种类型的按钮

  • 作为普通按钮, 可以显示文本信息和图标
  • 按钮的图标可以使用不同的方式设置, 并且制定图标和文本信息的显示模式
  • 设置check属性, 使其可以处于持续的被选中状态
  • 关联一个菜单, 点击按钮菜单弹出, 并且可以设置菜单的弹出方式

具体操作可以参考如下代码:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 普通按钮, 没有checked属性
    ui->normalBtn->setText("我是个屌丝");
    ui->normalBtn->setIconSize(QSize(50, 50));
    ui->normalBtn->setIcon(QIcon(":/mario.png"));
    connect(ui->normalBtn, &QToolButton::clicked, this, [=]()
    {
         qDebug() << "我是一个普通按钮, 是一个屌丝...";
    });
    // 设置图标和文本的显示模式
    ui->normalBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
    // 基于QAction的方式给按钮设置图标和文本信息
    QAction* actBtn = new QAction(QIcon(":/mushroom_life.png"), "奥利给");
    ui->actionBtn->setDefaultAction(actBtn);
    connect(ui->actionBtn, &QToolButton::triggered, this, [=](QAction* act)
    {
        act->setText("我是修改之后的马里奥...");
        act->setIcon(QIcon(":/mario.png"));
    });
    // 设置图标和文本的显示模式
    ui->actionBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
    
    // 基于自带样式, 给按钮设置箭头图标
    ui->arrowBtn->setArrowType(Qt::UpArrow);
    ui->arrowBtn->setText("向上");
    // 设置图标和文本的显示模式
    ui->arrowBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);


    // 有checked属性的按钮
    ui->checkedBtn->setCheckable(true);
    connect(ui->checkedBtn, &QToolButton::toggled, this, [=](bool bl)
    {
         qDebug() << "我是一个checked按钮, 当前状态为:" << bl;
    });

    // 关联菜单
    ui->menuBtn->setText("你喜欢哪种美女?");
    QMenu* menu = new QMenu;
    QAction* act = menu->addAction("可爱的");
    menu->addAction("粘人的");
    menu->addAction("胸大的");
    menu->addAction("屁股翘的");
    ui->menuBtn->setMenu(menu);
    connect(act, &QAction::triggered, this, [=]{
        qDebug() << "我是一个可爱的女人, 今晚约吗?";
    });

    ui->popmenu->setMenu(menu);
    /*
    弹出菜单的弹出模式是一个枚举类型: QToolButton::ToolButtonPopupMode, 取值如下:
      - QToolButton::DelayedPopup: 
          - 延时弹出, 按压工具按钮一段时间后才能弹出, 比如:浏览器的返回按钮
          - 长按按钮菜单弹出, 但是按钮的 clicked 信号不会被发射
      - QToolButton::MenuButtonPopup: 
          - 在这种模式下,工具按钮会显示一个特殊的箭头,表示有菜单。
	  - 当按下按钮的箭头部分时,将显示菜单。按下按钮部分发射 clicked 信号
      - QToolButton::InstantPopup: 
          - 当按下工具按钮时,菜单立即显示出来。
          - 在这种模式下,按钮本身的动作不会被触发(不会发射clicked信号
    */
    ui->popmenu->setPopupMode(QToolButton::MenuButtonPopup);
    // 测试关联了菜单的按钮是否会发射clicked信号
    connect(ui->popmenu, &QToolButton::clicked, this, [=]()
    {
        qDebug() << "我是popMenu按钮, 好痒呀...";
    });
}

1.4 QRadioButton

QRadioButton是Qt提供的单选按钮, 一般都是以组的方式来使用(多个按钮中同时只能选中其中一个)。操作这个按钮使用的大部分函数都是从父类继承过来的, 它的父类是QAbstractButton
关于单选按钮的使用我们还需要注意一点, 如果单选按钮被选中, 再次点击这个按钮选中状态是不能被取消的。

1.4.1 常用API

这个类混的很失败, 一直生活在父类的阴影之下, 没有什么作为, 在官方的帮助文档中, 处理构造函数就没有再提供其他可用的 API

// 构造函数
/*
参数:
    - text: 按钮上显示的标题
    - parent: 按钮的父对象
*/
QRadioButton::QRadioButton(const QString &text, QWidget *parent = nullptr);
QRadioButton::QRadioButton(QWidget *parent = nullptr);

1.4.2 按钮的使用

单选按钮一般是以组的形式来使用的, 如果在一个窗口中需要有多个单选按钮组, 应该如何处理呢?
在同一窗口中, Qt会认为所有的单选按钮都属于同一组, 如果需要多个单选按钮组, 应该将他们放到不同的子窗口中。

在这里插入图片描述

通过上图可以看到有两个单选按钮组, 在制作的时候分别将单选按钮放到了不同的容器窗口(组框)中,这样就被人为分隔为两组了。

在这里插入图片描述

如果我们使用鼠标点击了某个单选按钮, 按钮还是会发射出 clicked()信号, 简单的按钮测试代码如下所示:

void MainWindow::on_redio_996_clicked()
{
    qDebug() << "996";
}

void MainWindow::on_radio_nosalary_clicked()
{
    qDebug() << "没有加班费";
}

void MainWindow::on_radio_nogirl_clicked()
{
    qDebug() << "公司没有妹子...";
}

// clicked 信号传递的参数可以接收, 也可以不接收 
// 这个参数对应这中类型的按钮没啥用
void MainWindow::on_radio_notbeautiful_clicked(bool checked)
{
    qDebug() << "前台小姐姐不好看!!!";
}

1.5 QCheckBox

QCheckBox是Qt中的复选框按钮, 可以单独使用, 也可以以组的方式使用(同一组可以同时选中多个), 当复选按钮被选中, 再次点击之后可以取消选中状态, 这一点和单选按钮是不同的。
操作这个按钮使用的大部分函数都是从父类继承过来的, 它的父类是QAbstractButton


1.5.1 常用API

我们对复选框按钮操作的时候, 可以设置选中和未选中状态, 并且还可以设置半选中状态, 这种半选中状态一般需要当前复选框按钮下还有子节点,类似一树状结构。

  • 公共成员函数
// 构造函数
/*
参数:
    - text: 按钮上显示的文本信息
    - parent: 按钮的父对象
*/
QCheckBox::QCheckBox(const QString &text, QWidget *parent = nullptr);
QCheckBox::QCheckBox(QWidget *parent = nullptr);

// 判断当前复选框是否为三态复选框, 默认情况下为两种状态: 未选中, 选中
bool isTristate() const;
// 设置当前复选框为三态复选框: 未选中, 选中, 半选中
void setTristate(bool y = true);

/*
参数 state, 枚举类型 Qt::CheckState:
    - Qt::Unchecked	      --> 当前复选框没有被选中
    - Qt::PartiallyChecked    --> 当前复选框处于半选中状态, 部分被选中(三态复选框)
    - Qt::Checked	      --> 当前复选框处于选中状态
*/
// 设置复选框按钮的状态
void QCheckBox::setCheckState(Qt::CheckState state);
// 获取当前复选框的状态
Qt::CheckState QCheckBox::checkState() const;
  • 信号
// 当复选框的状态改变时,即当用户选中或取消选中复选框时,他的信号就会发出。
// 参数 state 表示的是复选框的三种状态中某一种, 可参考 Qt::CheckState
[signal] void QCheckBox::stateChanged(int state);

1.5.2 按钮的使用

下面针对于复选框按钮的三种状态, 为大家展示一下对应的操作流程, 首先第一步搭建一个有树状关系的界面:

在这里插入图片描述

这些复选框按钮的关系以及 objectName 如下:

在这里插入图片描述

第二步, 在窗口类的头文件中添加槽函数, 槽函数处理复选框按钮的状态变化:

// mainwindow.h
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    // 添加槽函数, 处理复选框按钮状态变化
    void statusChanged(int state);

private:
    Ui::MainWindow *ui;
    int m_number = 0;    // 添加一个计数器, 记录有几个子节点被选中了
};

第三步, 在源文件中添加处理逻辑

// mainwindow.cpp
// 窗口的构造函数
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 设置根节点的三态属性
    ui->wives->setTristate(true);
    // 处理根节点的鼠标点击事件
    connect(ui->wives, &QCheckBox::clicked, this, [=](bool bl)
    {
        if(bl)
        {
            // 子节点全部设置为选中状态
            ui->jianning->setChecked(true);
            ui->fangyi->setChecked(true);
            ui->longer->setChecked(true);
            ui->zengrou->setChecked(true);
            ui->mujianping->setChecked(true);
            ui->shuanger->setChecked(true);
            ui->ake->setChecked(true);
        }
        else
        {
            // 子节点全部设置为非选中状态
            ui->jianning->setChecked(false);
            ui->fangyi->setChecked(false);
            ui->longer->setChecked(false);
            ui->zengrou->setChecked(false);
            ui->mujianping->setChecked(false);
            ui->shuanger->setChecked(false);
            ui->ake->setChecked(false);
        }
    });

    // 处理子节点的状态变化, 对应的槽函数相同
    connect(ui->jianning, &QCheckBox::stateChanged, this, &MainWindow::statusChanged);
    connect(ui->fangyi, &QCheckBox::stateChanged, this, &MainWindow::statusChanged);
    connect(ui->longer, &QCheckBox::stateChanged, this, &MainWindow::statusChanged);
    connect(ui->zengrou, &QCheckBox::stateChanged, this, &MainWindow::statusChanged);
    connect(ui->mujianping, &QCheckBox::stateChanged, this, &MainWindow::statusChanged);
    connect(ui->shuanger, &QCheckBox::stateChanged, this, &MainWindow::statusChanged);
    connect(ui->ake, &QCheckBox::stateChanged, this, &MainWindow::statusChanged);
}

// 槽函数
void MainWindow::statusChanged(int state)
{
    if(state == Qt::Checked)
    {
        m_number ++;	// 选中一个子节点, 计数器加1
    }
    else
    {
        m_number --;   // 取消选中一个子节点, 计数器减1
    }

    // 根据计数器值判断根节点是否需要做状态的更新
    if(m_number == 7)
    {
        ui->wives->setCheckState(Qt::Checked);
    }
    else if(m_number == 0)
    {
        ui->wives->setCheckState(Qt::Unchecked);
    }
    else
    {
        ui->wives->setCheckState(Qt::PartiallyChecked);
    }
}

2. 容器类型控件

2.1 QWidget

关于QWidget在前面的章节中已经介绍过了, 这个类是所有窗口类的父类, 可以作为独立窗口使用, 也可以内嵌到其它窗口中使用。
Qt中的所有控件都属于窗口类, 因此这个类也是所有控件类的基类。
如果一个窗口中还有子窗口, 为了让子窗口有序排列, 这时候我们可以选择一个QWidget类型的容器, 将子窗口放到里边, 然后再给这个QWidget类型窗口进行布局操作。
介绍一下关于这个类的一些属性,因为这个类是所有窗口类的基类,因此相关属性比较多

在这里插入图片描述

关于这些属性大部分都有对应的API函数, 在属性名前加 set 即可, 大家可以自己从 QWidget 这个类里边搜索,并仔细阅读关于这些函数的参数介绍。

在Qt中我们除了使用QWidget类型窗口作为容器使用, 也可以根据实际需求选择其他类型的容器, 下面看看具体都有哪些。

在这里插入图片描述

上述容器中, 着重为介绍常用的, 比如:Group Box, Scroll Area, Tool Box, Tab Widget, Stacked Widget, Frame, 关于Dock Widget 已经介绍过, 不在赘述。


2.2 Frame

QFrame就是一个升级版的QWidget, 它继承了QWidget的属性, 并且做了拓展, 这种类型的容器窗口可以提供边框, 并且可以设置边框的样式、宽度以及边框的阴影。


2.2.1 相关API

关于这个类的API, 一般是不在程序中调用的, 但是还是给大家介绍一下

/*
边框形状为布尔类型, 可选项为:
    - QFrame::NoFrame: 没有边框
    - QFrame::Box: 绘制一个框
    - QFrame::Panel: 绘制一个面板,使内容显示为凸起或凹陷
    - QFrame::StyledPanel: 绘制一个外观取决于当前GUI样式的矩形面板。它可以上升也可以下沉。
    - QFrame::HLine: 画一条没有边框的水平线(用作分隔符)
    - QFrame::VLine: 画一条没有边框的垂直线(用作分隔符)
    - QFrame::WinPanel: 绘制一个矩形面板,可以像Windows 2000那样向上或向下移动。
	                指定此形状将线宽设置为2像素。WinPanel是为了兼容而提供的。
	                对于GUI风格的独立性,我们建议使用StyledPanel代替。
*/
// 获取边框形状
Shape frameShape() const;
// 设置边框形状
void setFrameShape(Shape);


/*
Qt中关于边框的阴影(QFrame::Shadow)提供了3种样式, 分别为: 
    - QFrame::Plain: 简单的,朴素的, 框架和内容与周围环境显得水平;
	             使用调色板绘制QPalette::WindowText颜色(没有任何3D效果)
    - QFrame::Raised: 框架和内容出现凸起;使用当前颜色组的明暗颜色绘制3D凸起线
    - QFrame::Sunken: 框架及内容物凹陷;使用当前颜色组的明暗颜色绘制3D凹线
*/
// 获取边框阴影样式
Shadow frameShadow() const;
// 设置边框阴影样式
void setFrameShadow(Shadow);

// 得到边框线宽度
int lineWidth() const;
// 设置边框线宽度, 默认值为1
void setLineWidth(int);

// 得到中线的宽度
int midLineWidth() const;
// 设置中线宽度, 默认值为0, 这条线会影响边框阴影的显示
void setMidLineWidth(int);

2.2.2 属性设置

这个类的属性并不多, 都是关于边框的设置的。

在这里插入图片描述

这个表格显示了一些边框样式线宽以及阴影的组合:

在这里插入图片描述


2.3 Group Box

QGroupBox类的基类是QWidget, 在这种类型的窗口中可以绘制边框、给窗口指定标题, 并且还支持显示复选框。

2.3.1 相关API

关于这个类的API不常用, 下面给大家介绍一下在编码过程中可能会用到的一些:

// 构造函数
QGroupBox::QGroupBox(QWidget *parent = Q_NULLPTR);
QGroupBox::QGroupBox(const QString &title, QWidget *parent = Q_NULLPTR);

// 公共成员函数
bool QGroupBox::isCheckable() const;
// 设置是否在组框中显示一个复选框
void QGroupBox::setCheckable(bool checkable);

/*
关于对齐方式需要使用枚举类型 Qt::Alignment, 其可选项为:
    - Qt::AlignLeft: 左对齐(水平方向)
    - Qt::AlignRight: 右对齐(水平方向)
    - Qt::AlignHCenter: 水平居中
    - Qt::AlignJustify: 在可用的空间内调整文本(水平方向)
	
    - Qt::AlignTop: 上对齐(垂直方向)
    - Qt::AlignBottom: 下对齐(垂直方向)
    - Qt::AlignVCenter: 垂直居中
*/
Qt::Alignment QGroupBox::alignment() const;
// 设置组框标题的对其方式
void QGroupBox::setAlignment(int alignment);

QString QGroupBox::title() const;
// 设置组框的标题
void QGroupBox::setTitle(const QString &title);

bool QGroupBox::isChecked() const;
// 设置组框中复选框的选中状态
[slot] void QGroupBox::setChecked(bool checked);

2.3.2 属性设置

关于组框的属性对应的就是上边介绍的那几个API函数, 属性窗口如下:

在这里插入图片描述

组框中的flat属性没有对应的API函数, 只能在属性窗口中设置, 它控制的是窗口边框的绘制方式, 如果打开该属性, 组框的边框就消失了, 效果如下:

在这里插入图片描述


2.4 Scroll Area

QScrollArea这种类型的容器, 里边可以放置一些窗口控件, 当放置的窗口控件大于当前区域导致无法全部显示的时候, 滚动区域容器会自动添加相应的滚动条(水平方向或者垂直方向), 保证放置到该区域中的所有窗口内容都可以正常显示出来。对于使用者不需要做太多事情, 只需要把需要显示的窗口放到滚动区域中就行了。


2.4.1 相关API

在某些特定环境下, 我们需要动态的往滚动区域内部添加要显示的窗口, 或者动态的将显示的窗口移除, 这时候就必须要调用对应的API函数来完成这部分操作了。主要API有两个 添加 - setWidget(), 移除 - takeWidget()

// 构造函数
QScrollArea::QScrollArea(QWidget *parent = Q_NULLPTR);

// 公共成员函数
// 给滚动区域设置要显示的子窗口widget
void QScrollArea::setWidget(QWidget *widget);
// 删除滚动区域中的子窗口, 并返回被删除的子窗口对象
QWidget *QScrollArea::takeWidget();

/*
关于显示位置的设定, 是一个枚举类型, 可选项为:
    - Qt::AlignLeft: 左对齐
    - Qt::AlignHCenter: 水平居中
    - Qt::AlignRight: 右对齐
    - Qt::AlignTop: 顶部对齐
    - Qt::AlignVCenter: 垂直对其
    - Qt::AlignBottom: 底部对其
*/
// 获取子窗口在滚动区域中的显示位置
Qt::Alignment alignment() const;
// 设置滚动区域中子窗口的对其方式, 默认显示的位置是右上
void setAlignment(Qt::Alignment);

// 判断滚动区域是否有自动调节小部件大小的属性
bool widgetResizable() const;
/*
1. 设置滚动区域是否应该调整视图小部件的大小, 该属性默认为false, 滚动区域按照小部件的默认大小进行显示。
2. 如果该属性设置为true,滚动区域将自动调整小部件的大小,避免滚动条出现在本可以避免的地方,
   或者利用额外的空间。
3. 不管这个属性是什么,我们都可以使用widget()->resize()以编程方式调整小部件的大小,
   滚动区域将自动调整自己以适应新的大小。
*/
void setWidgetResizable(bool resizable);

2.4.2 属性设置

关于滚动区域, 其属性窗口提供的属性一般不需要设置, 因为一般情况下即便是设置了也看不到效果

在这里插入图片描述


2.4.3 窗口的动态添加和删除

关于窗口的滚动区域对象创建有两种方式, 第一种比较简单在编辑页面直接拖拽一个控件到UI界面, 然后布局即可。第二种方式是在程序中通过new操作创建一个实例对象, 然后通过通过代码的方式将其添加到窗口的某个布局中, 相对来说要麻烦一点。
下面通过第一种方式,演示一下如果往滚动区域中添加多个子窗口。

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 创建一个垂直布局对象
    QVBoxLayout* vlayout = new QVBoxLayout;

    for(int i=0; i<11; ++i)
    {
        // 创建标签对象
        QLabel* pic = new QLabel;
        // 拼接图片在资源文件中的路径
        QString name = QString(":/images/%1.png").arg(i+1);
        // 给标签对象设置显示的图片
        pic->setPixmap(QPixmap(name));
        // 设置图片在便签内部的对其方式
        pic->setAlignment(Qt::AlignHCenter);
        // 将标签添加到垂直布局中
        vlayout->addWidget(pic);
    }

    // 创建一个窗口对象
    QWidget* wg = new QWidget;
    // 将垂直布局设置给窗口对象
    wg->setLayout(vlayout);
    // 将带有垂直布局的窗口设置到滚动区域中
    ui->scrollArea->setWidget(wg);
}

关于以上代码做以下说明, 调用setWidget(wg)之后, wg会自动平铺填充满整个滚动区域, 因此:

  • 在程序中调用 void setWidgetResizable(bool resizable);不会有明显效果
  • 在程序中调用 void setAlignment(Qt::Alignment);不会看到任何效果
  • 如果要设置显示的图片的对其方式要设置图片的载体对象即 标签签对象
  • 如果要动态移除滚动区域中的窗口, 直接使用滚动区域对象调用 takeWidget() 即可
  • 滚动区域中只能通过setWidget(wg)添加一个子窗口, 如果要添加多个可使用布局的方式来实现

2.5 Tool Box

QToolBox工具箱控件, 可以存储多个子窗口, 该控件可以实现类似QQ的抽屉效果, 每一个抽屉都可以设置图标和标题, 并且对应一个子窗口, 通过抽屉按钮就可以实现各个子窗口显示的切换。

2.5.1 相关API

这个类对应的API函数相对较多, 一部分是控件属性对应的属性设置函数, 一部分是编程过程中可能会用的到的,理解为主吧, 知道有这么函数即可。

// 构造函数
QToolBox::QToolBox(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());

// 公共成员
/*
addItem(), insertItem()函数相关参数:
    - widget: 添加到工具箱中的选项卡对应的子窗口对象
    - icon: 工具箱新的选项卡上显示的图标
    - text: 工具箱新的选项卡上显示的标题
    - index: 指定在工具箱中插入的新的选项卡的位置
*/
// 给工具箱尾部添加一个选项卡, 每个选项卡在工具箱中就是一个子窗口, 即参数widget
int QToolBox::addItem(QWidget *widget, const QString &text);
int QToolBox::addItem(QWidget *widget, const QIcon &icon, const QString &text);
// 在工具箱的指定位置添加一个选项卡, 即添加一个子窗口
int QToolBox::insertItem(int index, QWidget *widget, const QString &text);
int QToolBox::insertItem(int index, QWidget *widget, const QIcon &icon, 
                         const QString &text);
// 移除工具箱中索引index位置对应的选项卡, 注意: 只是移除对应的窗口对象并没有被销毁
void QToolBox::removeItem(int index);

// 设置索引index位置的选项卡是否可用, 参数 enabled=true为可用, enabled=false为禁用
void QToolBox::setItemEnabled(int index, bool enabled);
// 设置工具箱中index位置选项卡的图标
void QToolBox::setItemIcon(int index, const QIcon &icon);
// 设置工具箱中index位置选项卡的标题
void QToolBox::setItemText(int index, const QString &text);
// 设置工具箱中index位置选项卡的提示信息(需要鼠标在选项卡上悬停一定时长才能显示)
void QToolBox::setItemToolTip(int index, const QString &toolTip);

// 如果位置索引的项已启用,则返回true;否则返回false。
bool QToolBox::isItemEnabled(int index) const;
// 返回位置索引处项目的图标,如果索引超出范围,则返回空图标。
QIcon QToolBox::itemIcon(int index) const;
// 返回位于位置索引处的项的文本,如果索引超出范围,则返回空字符串。
QString QToolBox::itemText(int index) const;
// 返回位于位置索引处的项的工具提示,如果索引超出范围,则返回空字符串。
QString QToolBox::itemToolTip(int index) const;

// 得到当前工具箱中显示的选项卡对应的索引
int QToolBox::currentIndex() const;
// 返回指向当前选项卡对应的子窗口的指针,如果没有这样的项,则返回0。
QWidget *QToolBox::currentWidget() const;
// 返回工具箱中子窗口的索引,如果widget对象不存在,则返回-1
int QToolBox::indexOf(QWidget *widget) const;
// 返回工具箱中包含的项的数量。
int QToolBox::count() const;

// 信号
// 工具箱中当前显示的选项卡发生变化, 该信号被发射, index为当前显示的新的选项卡的对应的索引
[signal] void QToolBox::currentChanged(int index);

// 槽函数
// 通过工具箱中选项卡对应的索引设置当前要显示哪一个选项卡中的子窗口
[slot] void QToolBox::setCurrentIndex(int index);
// 通过工具箱中选项卡对应的子窗口对象设置当前要显示哪一个选项卡中的子窗口
[slot] void QToolBox::setCurrentWidget(QWidget *widget);

2.5.2 属性设置

关于这个容器控件的属性远比上边介绍的API要少

在这里插入图片描述


2.6 Tab Widget

QTabWidget的一种带标签页的窗口,在这种类型的窗口中可以存储多个子窗口,每个子窗口的显示可以通过对应的标签进行切换。

2.6.1 相关API

介绍的这些API大部分是进行属性设置的, 因此我们可以完全不在程序中使用这些函数, 通属性窗口进行设置, 但是API操作比较灵活, 可以动态的设置相关属性。先来看公共成员函数:

// 构造函数
QTabWidget::QTabWidget(QWidget *parent = Q_NULLPTR);

// 公共成员函数
/*
添加选项卡addTab()或者插入选项卡insertTab()函数相关的参数如下:
    - page: 添加或者插入的选项卡对应的窗口实例对象
    - label: 添加或者插入的选项卡的标题
    - icon: 添加或者插入的选项卡的图标
    - index: 将新的选项卡插入到索引index的位置上
*/
int QTabWidget::addTab(QWidget *page, const QString &label);
int QTabWidget::addTab(QWidget *page, const QIcon &icon, const QString &label);
int QTabWidget::insertTab(int index, QWidget *page, const QString &label);
int QTabWidget::insertTab(int index, QWidget *page, 
                          const QIcon &icon, const QString &label);
// 删除index位置的选项卡
void QTabWidget::removeTab(int index);

// 得到选项卡栏中的选项卡的数量
int count() const;
// 从窗口中移除所有页面,但不删除它们。调用这个函数相当于调用removeTab(),直到选项卡小部件为空为止。
void QTabWidget::clear();
// 获取当前选项卡对应的索引
int QTabWidget::currentIndex() const;
// 获取当前选项卡对应的窗口对象地址
QWidget *QTabWidget::currentWidget() const;
// 返回索引位置为index的选项卡页,如果索引超出范围则返回0。
QWidget *QTabWidget::widget(int index) const;

/*
标签上显示的文本样式为枚举类型 Qt::TextElideMode, 可选项为:
    - Qt::ElideLeft: 省略号应出现在课文的开头,例如:.....是的,我很帅。
    - Qt::ElideRight: 省略号应出现在文本的末尾,例如:我帅吗.....。
    - Qt::ElideMiddle: 省略号应出现在文本的中间,例如:我帅.....很帅。
    - Qt::ElideNone: 省略号不应出现在文本中
*/
// 获取标签上显示的文本模式
Qt::TextElideMode QTabWidget::elideMode() const;
// 如何省略标签栏中的文本, 此属性控制在给定的选项卡栏大小没有足够的空间显示项时如何省略项。
void QTabWidget::setElideMode(Qt::TextElideMode);
    
// 得到选项卡上图标的尺寸信息
QSize QTabWidget::iconSize() const
// 设置选项卡上显示的图标大小
void QTabWidget::setIconSize(const QSize &size)

// 判断用户是否可以在选项卡区域内移动选项卡, 可以返回true, 否则返回false
bool QTabWidget::isMovable() const;
// 此属性用于设置用户是否可以在选项卡区域内移动选项卡。默认情况下,此属性为false;
void QTabWidget::setMovable(bool movable);

// 判断选项卡是否可以自动隐藏, 如果可以自动隐藏返回true, 否则返回false
bool QTabWidget::tabBarAutoHide() const;
// 如果为true,则当选项卡栏包含少于2个选项卡时,它将自动隐藏。默认情况下,此属性为false。
void QTabWidget::setTabBarAutoHide(bool enabled);

// 判断index对应的选项卡是否是被启用的, 如果是被启用的返回true, 否则返回false
bool QTabWidget::isTabEnabled(int index) const;
// 如果enable为true,则在索引位置的页面是启用的;否则,在位置索引处的页面将被禁用。
void QTabWidget::setTabEnabled(int index, bool enable);

// 得到index位置的标签对应的图标
QIcon QTabWidget::tabIcon(int index) const;
// 在位置索引处设置标签的图标。
void QTabWidget::setTabIcon(int index, const QIcon &icon);

/*
选项卡标签的位置通过枚举值进行指定, 可使用的选项如下:
	- QTabWidget::North: 北(上), 默认
	- QTabWidget::South: 南(下)
	- QTabWidget::West:	 西(左)
	- QTabWidget::East:  东(右)
*/
// 得到选项卡中显示的标签的位置, 即: 东, 西, 南, 北
TabPosition QTabWidget::tabPosition() const;
// 设置选项卡中标签显示的位置, 默认情况下,此属性设置为North。
void QTabWidget::setTabPosition(TabPosition);

/*
选项卡标签的形状通过枚举值进行指定, 可使用的选项如下:
	- QTabWidget::Rounded: 标签以圆形的外观绘制。这是默认形状
	- QTabWidget::Triangular: 选项卡以三角形外观绘制。
*/
// 获得选项卡标签的形状
TabShape QTabWidget::tabShape() const;
// 设置选项卡标签的形状
void QTabWidget::setTabShape(TabShape s);

// 得到index位置的标签的标题
QString QTabWidget::tabText(int index) const;
// 设置选项卡index位置的标签的标题
void QTabWidget::setTabText(int index, const QString &label);


// 获取index对应的标签页上设置的提示信息
QString QTabWidget::tabToolTip(int index) const;
// 设置选项卡index位置的标签的提示信息(鼠标需要悬停在标签上一定时长才能显示)
void QTabWidget::setTabToolTip(int index, const QString &tip);


// 判断选项卡标签也上是否有关闭按钮, 如果有返回true, 否则返回false
bool QTabWidget::tabsClosable() const;
// 设置选项卡的标签页上是否显示关闭按钮, 该属性默认情况下为false
void QTabWidget::setTabsClosable(bool closeable);


// 判断选项卡栏中是否有滚动按钮, 如果有返回true, 否则返回false
bool QTabWidget::usesScrollButtons() const;
// 设置选项卡栏有许多标签时,它是否应该使用按钮来滚动标签。
// 当一个选项卡栏有太多的标签时,选项卡栏可以选择扩大它的大小,或者添加按钮,让标签在选项卡栏中滚动。
void QTabWidget::setUsesScrollButtons(bool useButtons);

// 判断窗口是否设置了文档模式, 如果设置了返回true, 否则返回false
bool QTabWidget::documentMode() const;
// 此属性保存选项卡小部件是否以适合文档页面的模式呈现。这与macOS上的文档模式相同。
// 不设置该属性, QTabWidget窗口是带边框的, 如果设置了该属性边框就没有了。
void QTabWidget::setDocumentMode(bool set);

信号

// 每当当前页索引改变时,就会发出这个信号。参数是新的当前页索引位置,如果没有新的索引位置,则为-1
[signal] void QTabWidget::currentChanged(int index);
// 当用户单击索引处的选项卡时,就会发出这个信号。index指所单击的选项卡,如果光标下没有选项卡,则为-1。
[signal] void QTabWidget::tabBarClicked(int index)
// 当用户双击索引上的一个选项卡时,就会发出这个信号。
// index是单击的选项卡的索引,如果光标下没有选项卡,则为-1。
[signal] void QTabWidget::tabBarDoubleClicked(int index);
// 此信号在单击选项卡上的close按钮时发出。索引是应该被删除的索引。 	
[signal] void QTabWidget::tabCloseRequested(int index);

槽函数

// 设置当前窗口中显示选项卡index位置对应的标签页内容
[slot] void QTabWidget::setCurrentIndex(int index);
// 设置当前窗口中显示选项卡中子窗口widget中的内容
[slot] void QTabWidget::setCurrentWidget(QWidget *widget);

2.6.2 属性设置

容器类型的控件其大多数情况下都是直接在属性窗口中直接设置, 因为这些属性设置完毕之后, 就无需再做修改了, 程序运行过程中无需做任何变化。下图为大家标注了每个属性对应的功能。

在这里插入图片描述


2.6.3 控件使用

关于这个控件的使用, 主要是通过代码的方式演示一下相关信号发射的时机, 再有就是当标签页添加了关闭按钮并点击了该按钮, 如果移除该标签页已经如何将其再次添加到窗口中。

第一步, 在头文件中添加存储已关闭的标签对应的窗口对象标签标题的容器

// mainwindow.h
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    QQueue<QWidget*> m_widgets;	// 存储标签对应的窗口对象
    QQueue<QString> m_names;    // 存储标签标题
};

第二步在源文件中添加处理动作

// mainwindow.cpp
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 点击了标签上的关闭按钮
    connect(ui->tabWidget, &QTabWidget::tabCloseRequested, this, [=](int index)
    {
        // 保存信息
        QWidget* wg = ui->tabWidget->widget(index);
        QString title = ui->tabWidget->tabText(index);
        m_widgets.enqueue(wg);
        m_names.enqueue(title);
        // 移除tab页
        ui->tabWidget->removeTab(index);
        ui->addBtn->setEnabled(true);

    });

    // 当标签被点击了之后的处理动作
    connect(ui->tabWidget, &QTabWidget::tabBarClicked, this, [=](int index)
    {
        qDebug() << "我被点击了一下, 我的标题是: " << ui->tabWidget->tabText(index);
    });

    // 切换标签之后的处理动作
    connect(ui->tabWidget, &QTabWidget::currentChanged, this, [=](int index)
    {
        qDebug() << "当前显示的tab页, 我的标题是: " << ui->tabWidget->tabText(index);
    });

    // 点击添加标签按钮点击之后的处理动作
    connect(ui->addBtn, &QPushButton::clicked, this, [=]()
    {
        // 将被删除的标签页添加到窗口中
        // 1. 知道窗口对象, 窗口的标题
        // 2. 知道添加函数
        ui->tabWidget->addTab(m_widgets.dequeue(), m_names.dequeue());
        if(m_widgets.empty())
        {
            ui->addBtn->setDisabled(true);
        }
    });
}

2.7 Stacked Widget

QStackedWidget 栈类型窗口, 在这种类型的窗口中可以存储多个子窗口, 但是只有其中某一个可以被显示出来, 至于是哪个子窗口被显示, 需要在程序中进行控制,在这种类型的窗口中没有直接切换子窗口的按钮或者标签。

2.7.1 相关API

先来了解一些这个类为我们提供的API, 在这些函数中最常用的就是它的槽函数, 并且名字和 QToolBox, QTabWidget 两个类提供的槽函数名字相同 分别为 setCurrentIndex(int), setCurrentWidget(QWidget*) 用来设置当前显示的窗口。

// 构造函数
QStackedWidget::QStackedWidget(QWidget *parent = Q_NULLPTR);

// 公共成员函数
// 在栈窗口中后边添加一个子窗口, 返回这个子窗口在栈窗口中的索引值(从0开始计数)
int QStackedWidget::addWidget(QWidget *widget);
// 将子窗口widget插入到栈窗口的index位置
int QStackedWidget::insertWidget(int index, QWidget *widget);
// 将子窗口widget从栈窗口中删除
void QStackedWidget::removeWidget(QWidget *widget);

// 返回栈容器窗口中存储的子窗口的个数
int QStackedWidget::count() const;
// 得到当前栈窗口中显示的子窗口的索引
int QStackedWidget::currentIndex() const;
// 得到当前栈窗口中显示的子窗口的指针(窗口地址)
QWidget *QStackedWidget::currentWidget() const;
// 基于索引index得到栈窗口中对应的子窗口的指针
QWidget *QStackedWidget::widget(int index) const;
// 基于子窗口的指针(实例地址)得到其在栈窗口中的索引
int QStackedWidget::indexOf(QWidget *widget) const;

// 信号
// 切换栈窗口中显示子窗口, 该信息被发射出来, index为新的当前窗口对应的索引值
[signal] void QStackedWidget::currentChanged(int index);
// 当栈窗口的子窗口被删除, 该信号被发射出来, index为被删除的窗口对应的索引值
[signal] void QStackedWidget::widgetRemoved(int index);

// 槽函数
// 基于子窗口的index索引指定当前栈窗口中显示哪一个子窗口
[slot] void QStackedWidget::setCurrentIndex(int index);
[slot] void QStackedWidget::setCurrentWidget(QWidget *widget);

2.7.2 属性设置

因为栈类型的窗口容器很简单, 所以对应的属性页很少, 只有两个:

在这里插入图片描述


2.7.3 控件使用

这里主要给大家演示一下QStackedWidget类型的容器中的子窗口如何切换, 如下图所示, 我们在一个栈窗口容器中添加了两个子窗口, 通过两个按钮对这两个窗口进行切换

在这里插入图片描述

关于窗口的切换调用这个类的槽函数就可以了, 代码如下:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 设置默认显示的窗口
    ui->stackedWidget->setCurrentWidget(ui->window1);

    connect(ui->showWin1, &QPushButton::clicked, this, [=]()
    {
	// 切换显示第一个子窗口
        ui->stackedWidget->setCurrentIndex(0);
    });

    connect(ui->showWin2, &QPushButton::clicked, this, [=]()
    {
        // 切换显示第二个子窗口, 调用这两个槽函数中的任何一个都可以
        ui->stackedWidget->setCurrentWidget(ui->window2);
    });
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1009860.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高压电缆护层接地环流及温度在线监测系统

高压电缆的金属护层是电缆的重要组成部分&#xff0c;当缆芯通过电流时&#xff0c;会在金属护层上产生环流&#xff0c;外护套的绝缘状态差、接地不良、金属护层接地方式不正确等等都会引起护套环流异常现象&#xff0c;严重威胁电缆运行安全。 当电缆金属护层环流出现异常时…

FFmpeg入门之Windows/Linux下FFmpeg源码编译

1.源码下载: git clone https://github.com/FFmpeg/FFmpeg.git windows : macos: ubuntu: 2.编译FFmpeg CompilationGuide – FFmpeg windows: 1.下载yasm并安装 : Download - The Yasm Modular Assembler Project 下载后复制到c:/windows 2.下载SDL 3.下载H264/265源码 git…

对缓存穿透、雪崩、击穿的理解,引入分布式锁

缓存实战 1、缓存穿透 先来了解一个小图&#xff0c; 1.1 概念&#xff1a; 缓存穿透指一个一定不存在的数据&#xff0c;由于缓存未命中这条数据&#xff0c;就会去查询数据库&#xff0c;数据库也没有这条数据&#xff0c;所以返回结果是 null。如果每次查询都走数据库&a…

Vue中的动态 Class Style

动态 Class & Style 我们平时可以直接给元素设置静态的 Class 或者是 Style&#xff0c;但是这种方式会带来很多限制&#xff0c;假设我想要内容动态的改变 Class 或者是 Style&#xff0c;通过原生的方式要通过 JavaScript 频繁操作 dom 才能够实现。而在 Vue 中我们无需…

java入坑之注解

一、注解入门 注解&#xff1a;Annotation 从JDK 1.5 引入位于源码中(代码/注释/注解)&#xff0c;使用其他工具进行处理的标签注解用来修饰程序的元素&#xff0c;但不会对被修饰的对象有直接的影响只有通过某种配套的工具才会对注解信息进行访问和处理 主要用途 提供信息给编…

【职场篇】五年游戏开发老兵,我为什么劝你学UE?

我是水曜日鸡&#xff0c;一个在游戏行业摸爬滚打了5年的行业老兵。在Unity和UE4各有两年半的开发经验。曾参与开发了索尼中国之星计划之一的 《硬核机甲》 项目&#xff0c;用的是Unity引擎。目前在上海某大厂参与研发 开放世界项目&#xff0c;用的是UE4引擎。今天我就来终结…

《重构改善代码设计》

文章目录 1.重构的原则2.代码的坏味道3.第一组重构3.1.提炼函数3.2.内联函数3.3.提炼变量3.4.内联变量3.5.修改函数名称3.6.封装变量3.7.变量改名3.8.引入参数对象3.9.函数组合成类3.10.函数组合成变换3.11.拆分阶段 4. 封装4.1. 封装记录4.2. 封装集合4.3. 以对象取代基本类型…

使用cpolar配合Plex搭建私人媒体站

文章目录 1.前言2. Plex网站搭建2.1 Plex下载和安装2.2 Plex网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1.前言 用手机或者平板电脑看视频&#xff0c;已经算是生活中稀松平常的场景了&#xff0c;特别是各…

如何开启Win10虚拟机Hyper-V功能

操作步骤: 使用前提&#xff1a; 1、确保系统是 Windows 10 专业版/企业版/教育版&#xff0c;且必须是64位操作系统才支持。 提示&#xff1a;Win10家庭版不支持hyper-v。 2、使用Hyper-V需要cpu支持虚拟化并处于开启状态。 3、硬件要求及如何验证硬件兼容性&#xff1a; 硬件…

Hive 使用达梦DM8 无法识别 “COMMENT” 问题

将达梦数据库驱动 DmJdbcDriver18-8.1.2.192.jar 导入到 hive 的 lib 文件夹下 修改 hive 配置文件&#xff0c;增加 dm 数据库相关信息 <property><name>javax.jdo.option.ConnectionURL</name><value>jdbc:dm://127.0.0.1:5236?SCHEMAhive</val…

vmware官网下载(VMware workstation 下载与安装)

Oracle RAC 安装配置part1 注册VMware 个人帐号 浏览器打开官方网站 下面是主页&#xff0c;单击Customer connter 单击立即注册 填入相关信息注册完成 需要到您邮件里的激活一下帐号 注册完成 下载VMware Workstation 单击转到CUSTOMER CONNECT (您也可以在主页login…

修饰符的笔记

修饰符 完整的教程参考下面的链接 菜鸟教程-修饰符 下面是我总结的比较精简的内容 常见的修饰符有权限修饰符和非权限修饰符 权限修饰符 权限修饰符就是我们所熟知的 private&#xff0c;public&#xff0c;protect&#xff0c;default&#xff08;什么都不写&#xff0c;默…

华为云云耀云服务器L实例评测|基于华为云云耀云服务器L实例搭建EMQX大规模分布式 MQTT 消息服务器场景体验

文章目录 前言一、&#x1f604;华为云云耀服务器二、&#x1f604;产品实例创建相关1、&#x1f9e8;开通华为云云耀服务器2、&#x1f9e8;创建华为云云耀服务器实例3、&#x1f9e8;终端登录4、&#x1f9e8;华为云云耀云服务器密码重置 三、&#x1f604;安装开源产品EMQX四…

python diffusers StableDiffusionXLPipeline 离线使用

下载sd_xl_base_1.0.safetensors https://huggingface.co/runwayml/stable-diffusion-v1-5/tree/main 我这下载后放到项目 models 里 model_path "./models/v1-5-pruned-emaonly.safetensors" # model_path "./models/v1-5-pruned.safetensors" # model…

人工智能创业,2023爆火风口项目:实景无人直播帮实体店精准获客

软件图片素材来自于公众号&#xff1a;生财风暴 关注进行领取价值1000元的采集软件&#xff0c;和呆头鹅批量剪辑和矩阵管理系统演示 把AI和直播结合在一起的实景自动直播你知道吗&#xff1f;如果提起人工智能创业项目啊&#xff0c;你还只知道CHHGPP的话&#xff0c;那不妨把…

光伏浪涌保护器综合应用工程方案

光伏浪涌保护器是一种用于保护光伏发电系统中的设备和线路免受雷电或其他瞬态过电压的影响的装置。光伏发电系统由于其分布式、室外、大面积等特点&#xff0c;容易受到雷电直击或感应&#xff0c;导致系统内部产生高能量的浪涌电流和电压&#xff0c;从而损坏光伏组件、逆变器…

竞赛选题 基于大数据的时间序列股价预测分析与可视化 - lstm

文章目录 1 前言2 时间序列的由来2.1 四种模型的名称&#xff1a; 3 数据预览4 理论公式4.1 协方差4.2 相关系数4.3 scikit-learn计算相关性 5 金融数据的时序分析5.1 数据概况5.2 序列变化情况计算 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &…

【Git】Git 快照 Snapshot

Git 快照 Snapshot 在对 Git 基础的学习过程中&#xff0c;我们了解了 Git 仓库的基本结构&#xff1a; 工作目录暂存区版本库&#xff0c;即 .git 仓库 下面我们就通过一次修改、暂存以及提交的工作流程&#xff0c;来理解快照&#xff08;Snapshot&#xff09;的概念。 现…

基于Docker的JMeter分布式压测实战讲解

一个JMeter实例可能无法产生足够的负载来对你的应用程序进行压力测试。如本网站所示&#xff0c;一个JMeter实例将能够控制许多其他的远程JMeter实例&#xff0c;并对你的应用程序产生更大的负载。JMeter使用Java RMI[远程方法调用]来与分布式网络中的对象进行交互。JMeter主站…

Linux:基础开发工具之Makefile和缓冲区的基本概念

文章目录 动静态库自动化构建代码缓冲区 动静态库 首先要知道什么是链接&#xff1a; C程序中&#xff0c;并没有定义printf的函数实现,且在预编译中包含的stdio.h中也只有该函数的声明,而没有定义函数的实现 系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没…