按钮

Qt中按钮有多种形式,但是按钮都有共同的抽象基类QAbstractButton,该类提供了按钮的通用功能。按钮的继承图如下:

QAbstractButton

抽象按钮提供如下常用函数

//按钮是否被选中(即是否处于选中状态),只有可选中按钮才能被选中。默认未被选中
bool isChecked() const; 
//设置按钮是否选中
void setChecked(bool);

//isDown用于获取按钮当前是否处于 "按下状态"(视觉上显示为被按下的样子)。
//返回true表示按钮当前显示为按下状态,false则表示未按下(默认状态)。   
bool isDown()const;
//setDown用于手动设置按钮的 "按下状态"。传入true会强制按钮显示为按下的视觉效果,
//传入false则恢复正常未按下的视觉效果。
void setDown(bool);

//按钮上显示的图标,
QIcon icon() const; 
void setIcon(const QIcon &);

//按钮上显示的图标的大小。默认大小由GUI样式定义。这是图标的最大大小,较小的图标不会被放大。
QSize iconSize() const; 
void setIconSize(const QSize);

//此方法用于设置按钮的文本内容
void setText(const QString &text);
//此方法用于获取按钮当前的文本内容
QString text() const;

抽象按钮提供如下信号

//鼠标点击按钮然后释放时会发送此信号,注意:按钮释放时才会发送。
//若按钮是可选中的,当按钮被选中时,参数checked为true,若按钮未被选中,则为false。
[signals] void clicked(bool checked = false);

//按下按钮时发送此信号
[signals] void pressed();
//释放按钮时发送此信号
[signals] void released();

//每当可选中按钮切换状态时,都会发送此信号。若按钮被选中,则参数checked为true,若按钮被取消选中,则为false。
[signals] void toggled(bool checked);

按钮的可选中模式

在 Qt 中,按钮的 “可选中模式”(Checkable Mode)是QPushButton的一种特殊状态,开启后按钮会具备 **“选中” 和 “未选中” 两种持久状态 **,类似开关或复选框的交互逻辑。这种模式让按钮从 “一次性点击触发” 变为 “状态切换控件”,非常适合需要保存用户选择状态的场景。

一、如何开启可选中模式

通过 setCheckable(bool) 方法开启或关闭,默认值为 false(普通模式):

QPushButton* btn = new QPushButton("开关按钮");
btn->setCheckable(true); // 开启可选中模式

开启后,按钮会在点击时自动切换 “选中” 和 “未选中” 状态,且状态会被保留(除非再次点击或通过代码修改)。

二、核心特性与相关方法

1. 状态获取与设置

  • isChecked():返回当前是否处于 “选中状态”(true 表示选中,false 表示未选中)。
  • setChecked(bool):手动设置按钮的选中状态(true 强制选中,false 强制取消选中)。

示例:

// 手动设置为选中状态
btn->setChecked(true);
qDebug() << "当前状态:" << (btn->isChecked() ? "选中" : "未选中"); // 输出"选中"

2. 视觉反馈

开启可选中模式后,按钮的外观会随状态变化:

  • 选中时:通常显示为 “按下并保持” 的视觉效果(具体样式依赖系统主题或自定义样式)。
  • 未选中时:恢复正常按钮外观。

这种视觉差异让用户能直观判断当前状态。

3. 信号与状态联动

可选中模式下,按钮会发出两个关键信号:

  • clicked(bool checked):点击并释放按钮时触发,参数 checked 表示当前选中状态(true 为选中,false 为未选中)。
  • toggled(bool checked):状态发生变化时立即触发(无论通过点击还是代码修改),参数 checked 为变化后的状态。

示例(信号连接):

// 点击时响应(与clicked信号关联)
connect(btn, &QPushButton::clicked, [=](bool checked) {
    if (checked) {
        qDebug() << "点击后变为选中状态";
    } else {
        qDebug() << "点击后变为未选中状态";
    }
});

// 状态变化时响应(与toggled信号关联)
connect(btn, &QPushButton::toggled, [=](bool checked) {
    if (checked) {
        qDebug() << "状态变为选中(可能是点击或代码设置)";
    } else {
        qDebug() << "状态变为未选中(可能是点击或代码设置)";
    }
});

两者的区别:clicked 仅在用户点击时触发,toggled 则在任何情况下(点击、代码调用 setChecked() 等)状态变化时都会触发。

三、与普通模式的核心区别

特性普通模式(setCheckable(false))可选中模式(setCheckable(true))
状态保存无持久状态,点击后立即恢复有 “选中 / 未选中” 两种持久状态
视觉反馈点击时短暂显示按下效果选中时持续显示按下效果
信号参数clicked() 无参数(或默认 false)clicked(bool) 携带当前选中状态
典型用途触发一次性操作(如 “确定”“提交”)切换功能开关(如 “静音”“全屏”)

四、使用场景

可选中模式适合需要 “保存用户选择状态” 的场景,例如:

  • 功能开关:如 “静音模式”“自动刷新” 按钮,点击一次开启,再点关闭。
  • 选项标记:如 “加粗”“ italic ” 等文本格式按钮,选中表示启用该格式。
  • 状态切换:如 “夜间模式 / 日间模式” 切换按钮,选中对应夜间模式。

总结

“可选中模式” 是 Qt 按钮的一种增强功能,通过 setCheckable(true) 开启后,按钮从 “瞬时触发” 变为 “状态保存” 的交互控件。核心是利用 isChecked() 获取状态、setChecked() 控制状态,以及通过 toggled 或 clicked 信号响应状态变化,非常适合实现开关类交互逻辑。

QPushButton命令按钮

是最基础的按钮,该按钮可以被鼠标点击,是可点击按钮的核心控件,它是用户界面中最常用的交互元素之一。

常用函数

//这是构造函数,用于创建一个带有图标、指定文本和父对象的按钮
QPushButton(const QIcon &icon, const QString &text, QWidget *parent = nullptr);

//这是构造函数,用于创建一个带有指定文本和父对象的按钮。
QPushButton(const QString &text, QWidget *parent = nullptr);

//这是构造函数,用于创建一个带有父对象的按钮。
QPushButton(QWidget *parent = nullptr);

//设置按钮是否为平面样式
void setFlat(bool flat)

//检查按钮当前是否为平面样式
bool isFlat() const

//显示按钮,使其可见。
[slot] void QWidget::show();
常用辅助函数
move(int x, int y)手动指定按钮位于父窗口中的位置。
setGeometry(int x, int y, int w, int h)同时指定按钮的尺寸和位置
adjustSize()根据按钮上要显示的内容,自动调整按钮的大小
setDisabled(bool disable)指定按钮是否可以被按下。当 disable 值为 true 时,表示按钮不能被按下,即禁用按钮的功能
使用示例
#include "widget.h"

#include <QPushButton>
#include <QDebug>

Widget::Widget(QWidget *parent)
: QWidget(parent)
{
    //创建普通按钮(命令按钮)
    QPushButton *btn1 = new QPushButton;
    //设置父亲(这样可以显示出来,也可以靠对象树回收)
    btn1->setParent(this);
    //设置按钮的显示文本
    btn1->setText("测试按钮1");
    //移动按钮显示的位置
    btn1->move(100, 100);
    //设置按钮的大小(宽、高)
    btn1->resize(200, 100);
    //添加资源图表
    btn1->setIcon(QIcon(":/Image/1.png"));
    
    //添加菜单
    QMenu *menu = new QMenu(this);
    menu->addAction("选项1");
    menu->addAction("选项2");
    btn1->setMenu(menu);  //点击按钮右侧箭头显示菜单

    //添加信号与槽
    connect(btn1, &QPushButton::clicked, [=](){
        qDebug() << btn1->text();
        qDebug() << "按钮1的横坐标:" << btn1->x()
                 << ",纵坐标:" << btn1->y();
    });

    //创建普通按钮(命令按钮),并执行文本与父亲
    QPushButton *btn2 = new QPushButton("测试按钮2", this);
    //移动按钮显示的位置
    btn2->move(350, 100);
    //设置按钮的大小(宽、高)
    btn2->resize(200, 100);
    //设置扁平
    btn2->setFlat(true);

}
显示结果

添加资源文件

在Qt项目中经常会使用资源文件,所以就需要添加资源文件,以图片为例,添加的步骤如下:

  • 右键项目-> Add New(添加新文件)->Qt->Qt Resource File(Qt资源文件),然后给资源文件取名,如果文件名叫res,就会生成res.qrc;

  • 点击项目下的任何一个文件,右键,然后选择"Show in Explorer"打开项目路径,将事先图片文件夹拷贝到项目路径下;

  • 点击Resources下的res.qrc,右键"Open in Edit",点击"Add Prefix"添加前缀(可以修改默认前缀),点击"Add Files"添加资源文件到项目,点击"Build"(左下角的锤子图标),这样就可以在项目"Resources"资源文件夹下看到新添加的所有图片,资源文件添加成功;

  • 后续代码中使用资源文件就可以使用 “冒号 + 前缀名 + 文件名”形式即可。

QToolButton工具按钮

QToolButton类提供了用于命令或选项可以快速访问的按钮,通常可以用在QToolBar里面。QToolButton通常只显示一个图标而不显示文本标签(尽管也可以显示文本),并且通常没有边框,在鼠标悬停和按下时的视觉反馈较轻。

//使用指定的父窗口创建一个默认的QToolButton实例
QToolButton(QWidget *parent = nullptr);
    
//设置是否在鼠标指向按钮时自动凸起
void setAutoRaise(bool enable);

//检查按钮是否在鼠标指向时自动凸起
bool autoRaise() const;

//获取工具按钮的弹出菜单模式。
QToolButton::ToolButtonPopupMode popupMode() const;
//枚举:
//ToolButtonPopupMode:枚举类型,定义了工具按钮的弹出菜单模式:
//QToolButton::DelayedPopup:默认模式,长按按钮后延迟弹出菜单。
//QToolButton::MenuButtonPopup:点击按钮箭头图标后立即弹出菜单。
//QToolButton::InstantPopup:点击按钮后立即弹出菜单。

//设置弹出菜单的显示模式,包括延迟弹出(DelayedPopup)、点击箭头立即弹出(MenuButtonPopup)和点击按钮立即弹出(InstantPopup)
void setPopupMode(ToolButtonPopupMode mode):

//设置按钮的样式
//包括仅显示图标(ToolButtonIconOnly)
//仅显示文本(ToolButtonTextOnly)
//文本在图标右侧(ToolButtonTextBesideIcon)
//文本在图标下方(ToolButtonTextUnderIcon)。
void setToolButtonStyle(Qt::ToolButtonStyle style);

//设置按钮是否显示一个箭头,而不是一个正常的图标  
//type的选择:Qt::NoArrow/Qt::UpArrow/Qt::DownArrow/Qt::LeftArrow/Qt::RightArrow
void setArrowType(Qt::ArrowType type);

//设置按钮的弹出菜单。
void QToolButton::setMenu(QMenu *menu)

使用示例

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private slots:
    void onClick();
    void openTest();
    void newTest();
    void onAutoRaiseButtonClicked();
};
#endif // WIDGET_H

widget.cc

#include "widget.h"

#include <QToolBar>
#include <QToolButton>
#include <QDebug>
#include <QMenu>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle("测试工具按钮");
    resize(640, 480);

    //创建基本工具按钮
    QToolButton *toolButton = new QToolButton(this);
    toolButton->move(100, 50);
    toolButton->resize(150, 40);
    toolButton->setText("工具按钮");
    toolButton->setIcon(QIcon(":/Image/wangdao.png"));
    toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);

    connect(toolButton, &QToolButton::clicked, this, &Widget::onClick);

    //创建带菜单栏的工具按钮
    QToolButton *menuBtn = new QToolButton(this);
    menuBtn->move(300, 50);
    menuBtn->resize(150, 40);
    menuBtn->setText("菜单按钮");
    menuBtn->setIcon(QIcon(":/Image/wangdao.png"));
    menuBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);

    QMenu *menu = new QMenu(this);
    menu->addAction("打开", this, &Widget::openTest);
    menu->addAction("新建", this, &Widget::newTest);
    menu->addSeparator();
    menu->addAction("退出", this, &Widget::close);

    menuBtn->setMenu(menu);
    menuBtn->setPopupMode(QToolButton::MenuButtonPopup);

    // 创建自动浮起的工具按钮
    QToolButton *autoRaiseBtn = new QToolButton(this);
    autoRaiseBtn->move(100, 200);
    autoRaiseBtn->resize(150, 80);
    autoRaiseBtn->setText("自动浮起按钮");
    autoRaiseBtn->setIcon(QIcon(":/Image/wangdao.png"));
    autoRaiseBtn->setAutoRaise(true);
    autoRaiseBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
    connect(autoRaiseBtn, &QToolButton::clicked, this, &Widget::onAutoRaiseButtonClicked);
}

Widget::~Widget()
{
}

void Widget::onClick()
{
    qDebug() << "测试点击操作";
}

void Widget::openTest()
{
    qDebug() << "测试打开操作";
}

void Widget::newTest()
{
    qDebug() << "测试新建操作";
}

void Widget::onAutoRaiseButtonClicked()
{
    qDebug() << "自动浮起按钮被点击";
}

显示结果

QRadioButton单选按钮

QRadioButton部件提供了一个带有文本标签的单选框(单选按钮)。可以切换选中(checked)或未选中(unchecked)状态的选项按钮。单选框通常呈现给用户一个“多选一”的选择。也就是说,在一组单选框中,一次只能选中一个单选框。单选框默认开启自动互斥。

//每当一个按钮切换选中或未选中状态时,会发出的toggled()信号
[signal] void QAbstractButton::toggled(bool checked);

使用示例

#include "widget.h"

#include <QRadioButton>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QRadioButton *radio1 = new QRadioButton(this);
    QRadioButton *radio2 = new QRadioButton(this);

    radio1->move(100, 50);
    radio2->move(100, 100);

    radio1->setText("第一个单选按钮");
    radio2->setText("第二个单选按钮");

    radio1->setChecked(true);
    radio2->setChecked(false);

    connect(radio1, &QRadioButton::toggled, [=](){
        qDebug() << "radio1是否被选中 = " << radio1->isChecked();//查看radio1状态是不是选中
    });
}

Widget::~Widget()
{
}

单选按钮特性:默认情况下,同一父对象下的QRadioButton会自动组成 “互斥组”—— 即同一时间只能有一个单选按钮被选中(选中一个会自动取消另一个)。

setChecked(bool)用于设置单选按钮的初始选中状态:

  • 程序运行时,radio1会默认处于 “选中” 状态(圆形按钮内会显示一个圆点)。
  • radio2默认处于 “未选中” 状态。

结果显示

QCheckBox复选框

QCheckBox 是 Qt 中用于实现 “复选框” 功能的控件,与单选按钮(QRadioButton)的 “互斥单选” 不同,它允许用户同时选中多个选项,适合需要 “多项选择” 的场景(如 “兴趣爱好”“权限设置” 等)。

QCheckBox 的核心特性

  1. 多选性:同一父对象下的多个 QCheckBox 相互独立,可同时选中或取消,无互斥限制。
  2. 状态:默认支持两种状态(选中 / 未选中),也可开启 “三态模式”(增加 “部分选中” 状态,用于表示子选项部分选中的父选项)。
  3. 信号:提供状态变化的信号,方便监测用户操作。常用函数
//设置复选框的状态是否为三态(tristate),即选中、未选中和其他状态,默认只有两态。
void setTristate(bool y = true);

//当复选框的状态发生改变的时候,会触发该信号
[signal] void QCheckBox::stateChanged(int state)
//state可以取下述值:
//Qt::Unchecked  未选中
//Qt::PartiallyChecked 部分选中
//Qt::Checked  选中

使用示例

class CheckboxDemo : public QWidget {
    Q_OBJECT
public:
    CheckboxDemo(QWidget *parent = nullptr) : QWidget(parent) {
        // 1. 创建布局(垂直排列复选框)
        QVBoxLayout *layout = new QVBoxLayout(this);
        
        // 2. 创建普通复选框(两态:选中/未选中)
        QCheckBox *cb1 = new QCheckBox("足球", this);
        QCheckBox *cb2 = new QCheckBox("篮球", this);
        QCheckBox *cb3 = new QCheckBox("羽毛球", this);
        
        // 3. 设置初始状态(可选)
        cb1->setChecked(true);  // 初始选中“足球”
        cb2->setChecked(false); // 初始未选中“篮球”
        
        // 4. 创建三态复选框(支持“部分选中”状态)
        QCheckBox *triStateCb = new QCheckBox("全选(三态)", this);
        triStateCb->setTristate(true); // 开启三态模式
        triStateCb->setCheckState(Qt::PartiallyChecked); // 初始设为“部分选中”
        
        // 5. 将复选框添加到布局
        layout->addWidget(cb1);
        layout->addWidget(cb2);
        layout->addWidget(cb3);
        layout->addWidget(triStateCb);
        
        // 6. 连接信号与槽(监测状态变化)
        // 普通复选框:toggled 信号(状态切换时触发,参数为是否选中)
        connect(cb1, &QCheckBox::toggled, [=](bool checked) {
            qDebug() << "足球:" << (checked ? "选中" : "未选中");
        });
        
        // 三态复选框:stateChanged 信号(传递状态值,适合三态场景)
        connect(triStateCb, &QCheckBox::stateChanged, [=](int state) {
            QString status;
            switch (state) {
                case Qt::Unchecked:      status = "未选中"; break;
                case Qt::PartiallyChecked: status = "部分选中"; break;
                case Qt::Checked:        status = "全选中"; break;
            }
            qDebug() << "三态复选框状态:" << status;
        });
    }
};

QCommandLinkButton命令链接按钮

用于创建命令链接按钮的控件,它结合了文本标签和按钮的功能,非常适合用于需要较大点击区域或视觉上更加引人注目的操作。通过设置描述文本、命令文本、图标和样式表,可以轻松定制按钮的外观和行为。

常用函数

//构造函数,/构造函数,构造QCommandLinkButton对象,并且显示文本、描述信息以及指定父窗口
QCommandLinkButton(const QString &text, const QString &description, QWidget *parent = nullptr);
//构造函数,构造QCommandLinkButton对象,并且显示文本以及指定父窗口
QCommandLinkButton(const QString &text, QWidget *parent = nullptr);
//使用指定的父窗口创建一个默认的QCommandLinkButton实例
QCommandLinkButton(QWidget *parent = nullptr)

//获取描述信息
QString description() const;
//设置描述信息
void setDescription(const QString &description);

使用示例

#include "widget.h"

#include <QCommandLinkButton>
#include <QUrl>
#include <QDesktopServices>

Widget::Widget(QWidget *parent)
: QWidget(parent)
{
    QCommandLinkButton *clb =
            new QCommandLinkButton("测试命令链接按钮", "点击按钮", this);
    clb->setDescription("用于链接到指定网站");

    clb->move(100, 50);
    clb->resize(300, 100);

    connect(clb, &QCommandLinkButton::clicked, [=](){
        QDesktopServices::openUrl(QUrl("www.baidu.com"));
    });
}
显示结果

QDialogButtonBox对话框按钮

QDialogButtonBox是一个放置按钮的盒子,它允许用户添加按钮,并自动按照当前的桌面环境来选择合适的布局。该类包含很多按钮控件,在窗体(widget)或者对话框(dialog)有多个按钮的时候,为方便管理就可以使用该类成组进行管理。当然也可以自行将按钮添加进QDialogButtonBox,它会会自动为用户的桌面环境使用适当的布局。

容器

QGroupBox组合框

容器控件,主要用于组织和管理一组相关的控件(如按钮、复选框、文本框等),并为这些控件提供一个框架和标题。

使用示例
#include "widget.h"

#include <QGroupBox>
#include <QPushButton>
#include <QRadioButton>
#include <QCheckBox>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QBoxLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //组合框1
    QGroupBox *groupBox1 = new QGroupBox("单选按钮组");
    //创建三个单选按钮
    QRadioButton *radioBtn1 = new QRadioButton("RadisButton1");
    QRadioButton *radioBtn2 = new QRadioButton("RadisButton2");
    QRadioButton *radioBtn3 = new QRadioButton("RadisButton3");

    //设置QGroupBox为垂直布局格式,并将三个单选按钮添加进来
    QVBoxLayout *vBoxLayout1 = new QVBoxLayout;
    vBoxLayout1->addWidget(radioBtn1);
    vBoxLayout1->addWidget(radioBtn2);
    vBoxLayout1->addWidget(radioBtn3);
    groupBox1->setLayout(vBoxLayout1);

    //组合框2:
    QGroupBox *groupBox2 = new QGroupBox("复选按钮组");
    //创建三个单选按钮
    QCheckBox *checkBox1 = new QCheckBox("CheckBox1");
    QCheckBox *checkBox2 = new QCheckBox("CheckBox2");
    QCheckBox *checkBox3 = new QCheckBox("CheckBox3");

    //设置QGroupBox为垂直布局格式,并将三个单选按钮添加进来
    QVBoxLayout *vBoxLayout2 = new QVBoxLayout;
    vBoxLayout2->addWidget(checkBox1);
    vBoxLayout2->addWidget(checkBox2);
    vBoxLayout2->addWidget(checkBox3);
    groupBox2->setLayout(vBoxLayout2);


    //组合框3:
    QGroupBox *groupBox3 = new QGroupBox("组合按钮组");
    //创建三个单选按钮
    QRadioButton *radioBtn11 = new QRadioButton("RadisButton11");
    QRadioButton *radioBtn21 = new QRadioButton("RadisButton21");
    QRadioButton *radioBtn31 = new QRadioButton("RadisButton31");
    QCheckBox *checkBox11 = new QCheckBox("CheckBox11");


    //设置QGroupBox为垂直布局格式,并将三个单选按钮添加进来
    QVBoxLayout *vBoxLayout3 = new QVBoxLayout;
    vBoxLayout3->addWidget(radioBtn11);
    vBoxLayout3->addWidget(radioBtn21);
    vBoxLayout3->addWidget(radioBtn31);
    vBoxLayout3->addWidget(checkBox11);
    groupBox3->setLayout(vBoxLayout3);

    //设置为默认选中
    radioBtn1->setChecked(true);
    checkBox1->setTristate();
    checkBox1->setChecked(true);
    radioBtn11->setChecked(true);
    checkBox11->setChecked(true);

    //将GroupBox控件添加到栅格布局中(多行多列)
    QGridLayout *pGridLayout = new QGridLayout;
    pGridLayout->addWidget(groupBox1, 0, 0, 1, 1);
    pGridLayout->addWidget(groupBox2, 0, 2, 1, 1);
    pGridLayout->addWidget(groupBox3, 1, 1, 1, 1);

    //设置Widget的布局管理器
    setLayout(pGridLayout);
}

显示结果

QScrollArea滚动区域

继承自QAbstractScrollArea类,QScrollArea提供了一个滚动视图的框架,它本身不直接显示内容,而是将内容(通常是一个QWidget或其子类)作为其子项,并通过滚动条来访问这些内容的全部。QScrollArea支持水平和垂直滚动,并且可以根据需要自动调整滚动条的出现。

常用函数
//获取对齐方式
Qt::Alignment alignment() const;
//Qt::Alignment枚举:
//Qt::AlignLeft       左对齐
//Qt::AlignHCenter    水平居中
//Qt::AlignRight      右对齐
//Qt::AlignTop        顶部对齐
//Qt::AlignVCenter    垂直居中
//Qt::AlignBottom     底部对齐

//设置对齐方式
void setAlignment(Qt::Alignment);

//确保滚动区域中的特定区域(通过x, y坐标指定)是可见的,xmargin和ymargin指定了额外边界以确保区域完全可见
void ensureVisible(int x, int y, int xmargin = 50, int ymargin = 50);

//确保部件可见
void ensureWidgetVisible(QWidget *childWidget, int xmargin = 50, int ymargin = 50);

//设置要显示在滚动区域中的小部件,这个小部件将作为滚动区域的内容。
void setWidget(QWidget *widget);

//设置内部小部件是否可以调整大小以填充滚动区域
void setWidgetResizable(bool resizable);

//删除子控件
QWidget *takeWidget();

//返回当前设置在滚动区域中的小部件。
QWidget *widget() const;

//一个布尔值属性,指示是否允许内部小控件(即内容)的大小随滚动区域的大小变化而调整
bool widgetResizable() const;

//这两个属性控制水平和垂直滚动条的策略
void QAbstractScrollArea::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy);
void QAbstractScrollArea::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy);
//Qt::ScrollBarPolicy枚举:
//Qt::ScrollBarAlwaysOff     永不显示
//Qt::ScrollBarAlwaysOn      始终显示
//Qt::ScrollBarAsNeeded      根据需要显示

使用示例

#include "widget.h"

#include <QLabel>
#include <QScrollArea>
#include <QGridLayout>
#include <QImage>

Widget::Widget(QWidget *parent)
: QWidget(parent)
{
    QLabel *label = new QLabel;
    //填充比例
    label->setScaledContents(true);

    QImage imag(":/Image/1.png");
    label->setPixmap(QPixmap::fromImage(imag));

    QScrollArea *scrollArea = new QScrollArea;

    scrollArea->setAlignment(Qt::AlignCenter);
   // scrollArea->setWidgetResizable(true);
    scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    scrollArea->setWidget(label);

    QGridLayout *gl = new QGridLayout;
    gl->addWidget(scrollArea);

    setLayout(gl);
}

显示结果

QTabWidget标签小控件

QTabWidget 是 Qt 中用于实现 “多标签页” 界面的控件,它能将多个相关但不同的内容区域组织在同一个窗口中,用户通过点击标签切换不同内容,非常适合需要分类展示信息的场景(如浏览器标签页、软件设置面板、数据分类展示等)。

一、QTabWidget 核心特性

  1. 标签页管理:可动态添加、移除、切换标签页。
  2. 灵活布局:标签可显示在窗口的上、下、左、右四个方向。
  3. 交互功能:支持标签关闭按钮、图标显示、快捷键切换等。
  4. 信号响应:提供标签切换、关闭等事件的信号,方便处理用户操作。

二、基本用法(代码示例)

下面通过一个完整示例展示 QTabWidget 的创建、标签页添加、属性设置和信号响应:

class TabWidgetDemo : public QWidget {
    Q_OBJECT
public:
    TabWidgetDemo(QWidget *parent = nullptr) : QWidget(parent) {
        // 1. 创建 QTabWidget 实例
        QTabWidget *tabWidget = new QTabWidget(this);
        
        // 2. 设置标签位置(可选:Top/ Bottom/ Left/ Right,默认 Top)
        tabWidget->setTabPosition(QTabWidget::North); // 标签在顶部(North)
        
        // 3. 允许标签页关闭(可选)
        tabWidget->setTabsClosable(true); // 每个标签显示关闭按钮(×)
        
        // 4. 创建标签页内容(每个标签页是一个 QWidget,可添加任意控件)
        // 标签页 1:基本信息
        QWidget *tab1 = new QWidget();
        QVBoxLayout *layout1 = new QVBoxLayout(tab1);
        layout1->addWidget(new QLabel("姓名:张三", this));
        layout1->addWidget(new QLabel("年龄:25", this));
        
        // 标签页 2:设置选项
        QWidget *tab2 = new QWidget();
        QVBoxLayout *layout2 = new QVBoxLayout(tab2);
        layout2->addWidget(new QCheckBox("开启通知", this));
        layout2->addWidget(new QCheckBox("自动保存", this));
        layout2->addWidget(new QPushButton("应用设置", this));
        
        // 标签页 3:备注信息
        QWidget *tab3 = new QWidget();
        QVBoxLayout *layout3 = new QVBoxLayout(tab3);
        layout3->addWidget(new QLabel("这是一个标签页示例", this));
        
        // 5. 向 QTabWidget 添加标签页(参数:标签页控件、标签文本)
        tabWidget->addTab(tab1, "基本信息");       // 添加标签页1
        tabWidget->addTab(tab2, "设置");           // 添加标签页2
        tabWidget->addTab(tab3, "备注");           // 添加标签页3
        
        // 6. 设置默认显示的标签页(可选,默认第0个)
        tabWidget->setCurrentIndex(0); // 初始显示第一个标签页(索引从0开始)
        
        // 7. 窗口布局(将 QTabWidget 放入主窗口)
        QVBoxLayout *mainLayout = new QVBoxLayout(this);
        mainLayout->addWidget(tabWidget);
        setLayout(mainLayout);
        resize(400, 300); // 设置窗口大小
        
        // 8. 连接信号与槽(响应标签操作)
        // 标签切换时触发(参数:新标签页的索引)
        connect(tabWidget, &QTabWidget::currentChanged, [=](int index) {
            qDebug() << "切换到标签页:" << index << "(标题:" << tabWidget->tabText(index) << ")";
        });
        
        // 标签关闭按钮被点击时触发(参数:要关闭的标签页索引)
        connect(tabWidget, &QTabWidget::tabCloseRequested, [=](int index) {
            qDebug() << "关闭标签页:" << index;
            tabWidget->removeTab(index); // 移除标签页
        });
    }
};

三、关键知识点解析

1. 核心操作方法
  • 添加标签页:addTab(QWidget *page, const QString &label)
    向标签控件添加一个标签页,page 是标签页内容(QWidget 或派生类),label 是标签显示的文本。
    也可添加图标:addTab(page, QIcon("icon.png"), "标签名")。

  • 切换标签页:setCurrentIndex(int index)
    通过索引(从 0 开始)设置当前显示的标签页,例如 setCurrentIndex(1) 显示第二个标签页。

  • 移除标签页:removeTab(int index)
    移除指定索引的标签页(注意:需手动管理标签页控件的内存,若标签页无父对象,移除后需手动删除)。

  • 获取标签页信息:

    • count():返回标签页总数。
    • currentIndex():返回当前显示的标签页索引。
    • tabText(int index):返回指定标签页的文本。
2. 常用属性设置
  • 标签位置:setTabPosition(TabPosition)
    可选值:QTabWidget::North(顶部,默认)、South(底部)、West(左侧)、East(右侧)。

  • 标签关闭按钮:setTabsClosable(bool)
    设为 true 时,每个标签会显示关闭按钮(×),点击后触发 tabCloseRequested 信号。

  • 标签可移动:setMovable(bool)
    设为 true 时,用户可拖动标签调整顺序。

3. 重要信号
  • currentChanged(int index):
    当标签页切换时触发,index 是新显示的标签页索引(-1 表示无标签页)。常用于切换标签时加载数据或更新界面。

  • tabCloseRequested(int index):
    当标签的关闭按钮被点击时触发,index 是要关闭的标签页索引。需在槽函数中调用 removeTab(index) 完成关闭。

四、与其他控件的配合

QTabWidget 的核心是 “标签页容器”,每个标签页(QWidget)可自由添加其他控件(按钮、输入框、表格等),并通过布局管理器(QVBoxLayout、QHBoxLayout 等)组织布局,灵活性极高。

例如,在标签页中添加表格:

QWidget *tableTab = new QWidget();
QVBoxLayout *layout = new QVBoxLayout(tableTab);
QTableWidget *table = new QTableWidget(5, 3, this); // 5行3列表格
layout->addWidget(table);
tabWidget->addTab(tableTab, "数据表格");

五、适用场景

  • 多分类信息展示(如用户信息、订单信息、日志信息分标签展示)。
  • 软件功能模块划分(如编辑器的 “编辑”“预览”“设置” 标签)。
  • 类似浏览器的多页面管理(每个标签对应一个网页)。

总结

QTabWidget 是 Qt 中组织复杂界面的高效工具,通过标签页将内容分类,既节省空间又提升用户体验。核心是掌握 addTab 添加标签页、setCurrentIndex 切换标签,以及利用 currentChanged 信号响应切换事件,结合布局管理器可创建灵活多样的多标签界面。

QDockWidget停靠窗体部件

QDockWidget 是 Qt 中用于创建 “可停靠窗体” 的控件,它允许用户将窗口拖动到主窗口的边缘(顶部、底部、左侧、右侧)停靠,也可以脱离主窗口成为独立的浮动窗口。这种灵活性使其非常适合作为工具面板、属性窗口、日志输出等辅助功能区域,常见于 IDE、图像编辑软件等复杂应用中。

一、QDockWidget 核心特性

  1. 可停靠性:可停靠在主窗口(QMainWindow)的四周,或与其他停靠窗口组合。
  2. 浮动状态:支持从主窗口脱离,成为独立的浮动窗口(可自由拖动位置)。
  3. 可关闭 / 隐藏:用户可暂时关闭或隐藏,需要时重新显示。
  4. 与主窗口集成:通常配合 QMainWindow 使用,与中央部件(central widget)形成主 - 辅布局。

二、基本用法(代码示例)

下面通过示例展示 QDockWidget 的创建、配置及与主窗口的集成:

class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
        // 1. 设置主窗口标题和大小
        setWindowTitle("QDockWidget 示例");
        resize(800, 600);
        
        // 2. 创建中央部件(主窗口的核心内容区域)
        QTextEdit *centralText = new QTextEdit("这是中央内容区域", this);
        setCentralWidget(centralText); // QMainWindow 必须设置中央部件
        
        // 3. 创建左侧停靠窗口(工具面板)
        QDockWidget *leftDock = new QDockWidget("工具面板", this);
        // 设置停靠窗口的内容(可添加任意控件)
        QWidget *leftContent = new QWidget();
        QVBoxLayout *leftLayout = new QVBoxLayout(leftContent);
        leftLayout->addWidget(new QPushButton("工具按钮 1", this));
        leftLayout->addWidget(new QPushButton("工具按钮 2", this));
        leftLayout->addStretch(); // 拉伸项,使按钮靠上排列
        leftDock->setWidget(leftContent); // 设置停靠窗口的内容部件
        
        // 4. 创建右侧停靠窗口(属性面板)
        QDockWidget *rightDock = new QDockWidget("属性面板", this);
        QWidget *rightContent = new QWidget();
        QVBoxLayout *rightLayout = new QVBoxLayout(rightContent);
        rightLayout->addWidget(new QPushButton("属性设置 A", this));
        rightLayout->addWidget(new QPushButton("属性设置 B", this));
        rightDock->setWidget(rightContent);
        
        // 5. 配置停靠窗口的特性
        // 左侧停靠窗口:只允许停靠在左侧或右侧
        leftDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
        // 右侧停靠窗口:允许关闭、浮动、停靠(默认支持所有特性)
        rightDock->setFeatures(QDockWidget::DockWidgetClosable |  // 可关闭
                               QDockWidget::DockWidgetFloatable | // 可浮动
                               QDockWidget::DockWidgetMovable);   // 可移动
        
        // 6. 将停靠窗口添加到主窗口
        addDockWidget(Qt::LeftDockWidgetArea, leftDock);  // 初始停靠在左侧
        addDockWidget(Qt::RightDockWidgetArea, rightDock); // 初始停靠在右侧
        
        // 7. 连接信号与槽(监测停靠状态变化)
        // 当停靠位置改变时触发(参数:新的停靠区域)
        connect(leftDock, &QDockWidget::dockLocationChanged, [=](Qt::DockWidgetArea area) {
            QString areaStr;
            switch (area) {
                case Qt::LeftDockWidgetArea:  areaStr = "左侧"; break;
                case Qt::RightDockWidgetArea: areaStr = "右侧"; break;
                case Qt::TopDockWidgetArea:   areaStr = "顶部"; break;
                case Qt::BottomDockWidgetArea: areaStr = "底部"; break;
                default: areaStr = "未知";
            }
            qDebug() << "左侧停靠窗口移动到:" << areaStr;
        });
        
        // 当浮动状态变化时触发(参数:是否为浮动状态)
        connect(rightDock, &QDockWidget::topLevelChanged, [=](bool isFloating) {
            qDebug() << "右侧停靠窗口" << (isFloating ? "变为浮动状态" : "变为停靠状态");
        });
    }
};

三、关键知识点解析

1. 与 QMainWindow 的配合

QDockWidget 通常必须在 QMainWindow 中使用,因为只有 QMainWindow 提供了停靠区域管理。QMainWindow 的布局结构包括:

  • 中央部件(central widget):主内容区域,通过 setCentralWidget() 设置(必须存在)。
  • 停靠区域:分布在中央部件的上、下、左、右(Qt::TopDockWidgetArea 等枚举)。
2. 核心配置方法
  • 设置内容:setWidget(QWidget *widget)
    为停靠窗口设置内容部件(可以是任意 QWidget 派生类,如包含按钮、输入框的自定义部件)。

  • 限制停靠区域:setAllowedAreas(Qt::DockWidgetAreas areas)
    限制停靠窗口可停靠的位置,例如:

    // 只允许停靠在顶部或底部
    dock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
    
  • 设置功能特性:setFeatures(DockWidgetFeatures features)
    控制停靠窗口的交互功能,常用值:

    • QDockWidget::DockWidgetClosable:允许关闭(默认允许)。
    • QDockWidget::DockWidgetFloatable:允许浮动(默认允许)。
    • QDockWidget::DockWidgetMovable:允许移动(默认允许)。
    • QDockWidget::NoDockWidgetFeatures:禁用所有功能(固定位置,不可关闭 / 浮动)。
3. 重要信号
  • dockLocationChanged(Qt::DockWidgetArea area):
    当停靠窗口的停靠区域改变时触发(如从左侧移到右侧),area 为新的停靠区域。

  • topLevelChanged(bool isFloating):
    当停靠窗口的浮动状态改变时触发,isFloating 为 true 表示变为浮动窗口,false 表示变为停靠状态。

  • visibilityChanged(bool visible):
    当停靠窗口显示 / 隐藏状态改变时触发,可用于在窗口显示时加载数据。

4. 停靠窗口的操作

用户可通过以下方式操作停靠窗口:

  • 拖动标题栏:移动到其他停靠区域或拖出成为浮动窗口。
  • 双击标题栏:快速切换 “停靠” 与 “浮动” 状态(若允许浮动)。
  • 关闭按钮(×):隐藏窗口(可通过主窗口的 “视图” 菜单重新显示)。

四、适用场景

  • 工具面板:如图像编辑软件中的 “画笔工具”“颜色选择器” 等。
  • 属性窗口:如 IDE 中显示选中控件属性的面板。
  • 日志 / 信息输出:如调试工具的日志窗口,可停靠或浮动查看。
  • 辅助功能区:如文本编辑器的 “大纲”“导航” 面板。

总结

QDockWidget 是构建灵活界面的重要控件,其核心价值在于 “可停靠 + 可浮动” 的双重特性,既能与主窗口紧密集成,又能根据用户需求灵活调整位置。使用时需注意与 QMainWindow 配合,通过 setWidget() 设置内容,setAllowedAreas() 限制停靠区域,并利用 dockLocationChanged 等信号响应状态变化,从而实现高效的辅助功能布局。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐