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

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

介绍一下QAbstractButton
中的一些常用API
1.1.1 标题和图标
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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
属性的按钮就相当于一个开关,每点击一次才能实现一次状态的切换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
bool QAbstractButton::isCheckable() const;
void QAbstractButton::setCheckable(bool);
bool QAbstractButton::isChecked() const;
void QAbstractButton::setChecked(bool);
|
1.1.3 信号
这些信号都按钮被点击之后发射出来的, 只是在细节上有细微的区别, 其中最常用的是 clicked()
通过鼠标的不同瞬间状态可以发射出pressed()
和 released()
信号, 如果鼠标设置了 check
属性, 一般通过toggled()
信号判断当前按钮是选中状态还是非选中状态。
1 2 3 4 5 6 7 8 9 10
|
[signal] void QAbstractButton::clicked(bool checked = false);
[signal] void QAbstractButton::pressed();
[signal] void QAbstractButton::released();
[signal] void QAbstractButton::toggled(bool checked);
|
1.1.4 槽函数
1 2 3 4 5 6 7 8 9 10 11
| [slot] void QAbstractButton::animateClick(int msec = 100);
[slot] void QAbstractButton::click();
[slot] void QAbstractButton::setChecked(bool);
[slot]void setIconSize(const QSize &size);
[slot] void QAbstractButton::toggle();
|
了解了基类提供的功能之后, 下边着重给大家介绍一下按钮组中常用的几这个按钮控件: QPushButton
, QToolButton
, QRadioButton
, QCheckBox
。
1.2.1 常用API
这种类型的按钮是Qt按钮中使用频率最高的一个, 对这个类进行操作, 大部分时候都需要使用它从父类继承过来的那些 API。
在QPushButton
类中, 比较常用的一些API函数如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
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;
void setDefault(bool);
void QPushButton::setMenu(QMenu *menu);
[slot] void QPushButton::showMenu();
|
1.2.2 按钮的使用
通过API的介绍, 我们可以知道, 使用QPushButton
这种类型的按钮, 有三种使用方式:
- 作为普通按钮, 可以显示文本信息和图标
- 设置check属性, 使其可以处于持续的被选中状态
- 关联一个菜单, 点击按钮菜单弹出
具体操作可以参考如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this);
ui->normalBtn->setText("我是小猪佩奇"); ui->normalBtn->setIcon(QIcon(":/Peppa-Pig.png")); ui->normalBtn->setIconSize(QSize(30, 30)); connect(ui->normalBtn, &QPushButton::clicked, this, [=]() { qDebug() << "我是一个普通按钮, 图标是小猪佩奇..."; });
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.1 常用API
这个类也是一个常用按钮类, 使用方法和功能跟QPushButton
基本一致, 只不过在对于关联菜单这个功能点上, QToolButton
类可以设置弹出的菜单的属性, 以及在显示图标的时候可以设置更多的样式, 可以理解为是一个增强版的QPushButton
。
和QPushButton
类相同的是, 操作这个按钮使用的大部分函数都是从父类QAbstractButton
继承过来的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| QToolButton::QToolButton(QWidget *parent = nullptr);
void QToolButton::setMenu(QMenu *menu);
QMenu *QToolButton::menu() const;
void setPopupMode(QToolButton::ToolButtonPopupMode mode);
QToolButton::ToolButtonPopupMode popupMode() const;
void setArrowType(Qt::ArrowType type);
Qt::ArrowType arrowType() const;
[slot] void QToolButton::setDefaultAction(QAction *action);
QAction *QToolButton::defaultAction() const;
[slot] void QToolButton::setToolButtonStyle(Qt::ToolButtonStyle style);
Qt::ToolButtonStyle toolButtonStyle() const;
[slot] void QToolButton::showMenu();
|
1.3.2 按钮的使用
通过API的介绍, 我们可以知道, 使用QToolButton这种类型的按钮
- 作为普通按钮, 可以显示文本信息和图标
- 按钮的图标可以使用不同的方式设置, 并且制定图标和文本信息的显示模式
- 设置check属性, 使其可以处于持续的被选中状态
- 关联一个菜单, 点击按钮菜单弹出, 并且可以设置菜单的弹出方式
具体操作可以参考如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this);
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* 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);
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);
ui->popmenu->setPopupMode(QToolButton::MenuButtonPopup); connect(ui->popmenu, &QToolButton::clicked, this, [=]() { qDebug() << "我是popMenu按钮, 好痒呀..."; }); }
|
QRadioButton
是Qt提供的单选按钮, 一般都是以组的方式来使用(多个按钮中同时只能选中其中一个
)。操作这个按钮使用的大部分函数都是从父类继承过来的, 它的父类是QAbstractButton
。
关于单选按钮的使用我们还需要注意一点, 如果单选按钮被选中, 再次点击这个按钮选中状态是不能被取消的。
1.4.1 常用API
这个类混的很失败, 一直生活在父类的阴影之下, 没有什么作为, 在官方的帮助文档中, 处理构造函数就没有再提供其他可用的 API
1 2 3 4 5 6 7 8
|
QRadioButton::QRadioButton(const QString &text, QWidget *parent = nullptr); QRadioButton::QRadioButton(QWidget *parent = nullptr);
|
1.4.2 按钮的使用
单选按钮一般是以组的形式来使用的, 如果在一个窗口中需要有多个单选按钮组, 应该如何处理呢?
在同一窗口中, Qt会认为所有的单选按钮都属于同一组, 如果需要多个单选按钮组, 应该将他们放到不同的子窗口中。

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

如果我们使用鼠标点击了某个单选按钮, 按钮还是会发射出 clicked()
信号, 简单的按钮测试代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| void MainWindow::on_redio_996_clicked() { qDebug() << "996"; }
void MainWindow::on_radio_nosalary_clicked() { qDebug() << "没有加班费"; }
void MainWindow::on_radio_nogirl_clicked() { qDebug() << "公司没有妹子..."; }
void MainWindow::on_radio_notbeautiful_clicked(bool checked) { qDebug() << "前台小姐姐不好看!!!"; }
|
1.5 QCheckBox
QCheckBox
是Qt中的复选框按钮, 可以单独使用, 也可以以组的方式使用(同一组可以同时选中多个), 当复选按钮被选中, 再次点击之后可以取消选中状态, 这一点和单选按钮是不同的。
操作这个按钮使用的大部分函数都是从父类继承过来的, 它的父类是QAbstractButton
。
1.5.1 常用API
我们对复选框按钮操作的时候, 可以设置选中和未选中状态, 并且还可以设置半选中状态, 这种半选中状态一般需要当前复选框按钮下还有子节点,类似一树状结构。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
QCheckBox::QCheckBox(const QString &text, QWidget *parent = nullptr); QCheckBox::QCheckBox(QWidget *parent = nullptr);
bool isTristate() const;
void setTristate(bool y = true);
void QCheckBox::setCheckState(Qt::CheckState state);
Qt::CheckState QCheckBox::checkState() const;
|
1 2 3
|
[signal] void QCheckBox::stateChanged(int state);
|
1.5.2 按钮的使用
下面针对于复选框按钮的三种状态, 为大家展示一下对应的操作流程, 首先第一步搭建一个有树状关系的界面:

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

第二步, 在窗口类的头文件中添加槽函数, 槽函数处理复选框按钮的状态变化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 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; };
|
第三步, 在源文件中添加处理逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
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 ++; } else { m_number --; }
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. 容器类型控件
关于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, 一般是不在程序中调用的, 但是还是给大家介绍一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
Shape frameShape() const;
void setFrameShape(Shape);
Shadow frameShadow() const;
void setFrameShadow(Shadow);
int lineWidth() const;
void setLineWidth(int);
int midLineWidth() const;
void setMidLineWidth(int);
|
2.2.2 属性设置
这个类的属性并不多, 都是关于边框的设置的。

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

2.3 Group Box
QGroupBox
类的基类是QWidget
, 在这种类型的窗口中可以绘制边框、给窗口指定标题, 并且还支持显示复选框。
2.3.1 相关API
关于这个类的API不常用, 下面给大家介绍一下在编码过程中可能会用到的一些:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| 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 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函数, 只能在属性窗口中设置, 它控制的是窗口边框的绘制方式, 如果打开该属性, 组框的边框就消失了, 效果如下:

QScrollArea
这种类型的容器, 里边可以放置一些窗口控件, 当放置的窗口控件大于当前区域导致无法全部显示的时候, 滚动区域容器会自动添加相应的滚动条(水平方向或者垂直方向), 保证放置到该区域中的所有窗口内容都可以正常显示出来。
对于使用者不需要做太多事情, 只需要把需要显示的窗口放到滚动区域中就行了。
2.4.1 相关API
在某些特定环境下, 我们需要动态的往滚动区域内部添加要显示的窗口, 或者动态的将显示的窗口移除, 这时候就必须要调用对应的API函数来完成这部分操作了。主要API有两个 添加 - setWidget()
, 移除 - takeWidget()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| QScrollArea::QScrollArea(QWidget *parent = Q_NULLPTR);
void QScrollArea::setWidget(QWidget *widget);
QWidget *QScrollArea::takeWidget();
Qt::Alignment alignment() const;
void setAlignment(Qt::Alignment);
bool widgetResizable() const;
void setWidgetResizable(bool resizable);
|
2.4.2 属性设置
关于滚动区域, 其属性窗口提供的属性一般不需要设置, 因为一般情况下即便是设置了也看不到效果

2.4.3 窗口的动态添加和删除
关于窗口的滚动区域对象创建有两种方式, 第一种比较简单在编辑页面直接拖拽一个控件到UI界面, 然后布局即可。第二种方式是在程序中通过new
操作创建一个实例对象, 然后通过通过代码的方式将其添加到窗口的某个布局中, 相对来说要麻烦一点。
下面通过第一种方式,演示一下如果往滚动区域中添加多个子窗口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| 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)
添加一个子窗口, 如果要添加多个可使用布局的方式来实现
QToolBox
工具箱控件, 可以存储多个子窗口, 该控件可以实现类似QQ的抽屉效果, 每一个抽屉都可以设置图标和标题, 并且对应一个子窗口, 通过抽屉按钮就可以实现各个子窗口显示的切换。
2.5.1 相关API
这个类对应的API函数相对较多, 一部分是控件属性对应的属性设置函数, 一部分是编程过程中可能会用的到的,理解为主吧, 知道有这么函数即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| QToolBox::QToolBox(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
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);
void QToolBox::removeItem(int index);
void QToolBox::setItemEnabled(int index, bool enabled);
void QToolBox::setItemIcon(int index, const QIcon &icon);
void QToolBox::setItemText(int index, const QString &text);
void QToolBox::setItemToolTip(int index, const QString &toolTip);
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;
QWidget *QToolBox::currentWidget() const;
int QToolBox::indexOf(QWidget *widget) const;
int QToolBox::count() const;
[signal] void QToolBox::currentChanged(int index);
[slot] void QToolBox::setCurrentIndex(int index);
[slot] void QToolBox::setCurrentWidget(QWidget *widget);
|
2.5.2 属性设置
关于这个容器控件的属性远比上边介绍的API要少

QTabWidget
的一种带标签页的窗口,在这种类型的窗口中可以存储多个子窗口,每个子窗口的显示可以通过对应的标签进行切换。
2.6.1 相关API
介绍的这些API大部分是进行属性设置的, 因此我们可以完全不在程序中使用这些函数, 通属性窗口进行设置, 但是API操作比较灵活, 可以动态的设置相关属性。先来看公共成员函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
| QTabWidget::QTabWidget(QWidget *parent = Q_NULLPTR);
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);
void QTabWidget::removeTab(int index);
int count() const;
void QTabWidget::clear();
int QTabWidget::currentIndex() const;
QWidget *QTabWidget::currentWidget() const;
QWidget *QTabWidget::widget(int index) const;
Qt::TextElideMode QTabWidget::elideMode() const;
void QTabWidget::setElideMode(Qt::TextElideMode);
QSize QTabWidget::iconSize() const
void QTabWidget::setIconSize(const QSize &size)
bool QTabWidget::isMovable() const;
void QTabWidget::setMovable(bool movable);
bool QTabWidget::tabBarAutoHide() const;
void QTabWidget::setTabBarAutoHide(bool enabled);
bool QTabWidget::isTabEnabled(int index) const;
void QTabWidget::setTabEnabled(int index, bool enable);
QIcon QTabWidget::tabIcon(int index) const;
void QTabWidget::setTabIcon(int index, const QIcon &icon);
TabPosition QTabWidget::tabPosition() const;
void QTabWidget::setTabPosition(TabPosition);
TabShape QTabWidget::tabShape() const;
void QTabWidget::setTabShape(TabShape s);
QString QTabWidget::tabText(int index) const;
void QTabWidget::setTabText(int index, const QString &label);
QString QTabWidget::tabToolTip(int index) const;
void QTabWidget::setTabToolTip(int index, const QString &tip);
bool QTabWidget::tabsClosable() const;
void QTabWidget::setTabsClosable(bool closeable);
bool QTabWidget::usesScrollButtons() const;
void QTabWidget::setUsesScrollButtons(bool useButtons);
bool QTabWidget::documentMode() const;
void QTabWidget::setDocumentMode(bool set);
|
信号
1 2 3 4 5 6 7 8 9
| [signal] void QTabWidget::currentChanged(int index);
[signal] void QTabWidget::tabBarClicked(int index)
[signal] void QTabWidget::tabBarDoubleClicked(int index);
[signal] void QTabWidget::tabCloseRequested(int index);
|
槽函数
1 2 3 4
| [slot] void QTabWidget::setCurrentIndex(int index);
[slot] void QTabWidget::setCurrentWidget(QWidget *widget);
|
2.6.2 属性设置
容器类型的控件其大多数情况下都是直接在属性窗口中直接设置, 因为这些属性设置完毕之后, 就无需再做修改了, 程序运行过程中无需做任何变化。下图为大家标注了每个属性对应的功能。

2.6.3 控件使用
关于这个控件的使用, 主要是通过代码的方式演示一下相关信号发射的时机, 再有就是当标签页添加了关闭按钮并点击了该按钮, 如果移除该标签页已经如何将其再次添加到窗口中。
第一步, 在头文件中添加存储已关闭的标签对应的窗口对象
和标签标题的容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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; };
|
第二步在源文件中添加处理动作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| 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); 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, [=]() { ui->tabWidget->addTab(m_widgets.dequeue(), m_names.dequeue()); if(m_widgets.empty()) { ui->addBtn->setDisabled(true); } }); }
|
QStackedWidget
栈类型窗口, 在这种类型的窗口中可以存储多个子窗口, 但是只有其中某一个可以被显示出来, 至于是哪个子窗口被显示, 需要在程序中进行控制,在这种类型的窗口中没有直接切换子窗口的按钮或者标签。
2.7.1 相关API
先来了解一些这个类为我们提供的API, 在这些函数中最常用的就是它的槽函数, 并且名字和 QToolBox
, QTabWidget
两个类提供的槽函数名字相同 分别为 setCurrentIndex(int)
, setCurrentWidget(QWidget*)
用来设置当前显示的窗口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| QStackedWidget::QStackedWidget(QWidget *parent = Q_NULLPTR);
int QStackedWidget::addWidget(QWidget *widget);
int QStackedWidget::insertWidget(int index, QWidget *widget);
void QStackedWidget::removeWidget(QWidget *widget);
int QStackedWidget::count() const;
int QStackedWidget::currentIndex() const;
QWidget *QStackedWidget::currentWidget() const;
QWidget *QStackedWidget::widget(int index) const;
int QStackedWidget::indexOf(QWidget *widget) const;
[signal] void QStackedWidget::currentChanged(int index);
[signal] void QStackedWidget::widgetRemoved(int index);
[slot] void QStackedWidget::setCurrentIndex(int index); [slot] void QStackedWidget::setCurrentWidget(QWidget *widget);
|
2.7.2 属性设置
因为栈类型的窗口容器很简单, 所以对应的属性页很少, 只有两个:

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

关于窗口的切换调用这个类的槽函数就可以了, 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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); }); }
|