VS2017+QT实现折叠/展开布局功能

1.预实现功能

学习Qt已经有一小段时间了,但是发现做过的东西总是会忘记,所以打算不定时写几篇博文,算记录自己的学习过程,也算和大家分享一下经验,也希望大家指正错误,相互学习。

1.1功能分析

应最近项目需求,需要使用Qt实现一个折叠和展开布局的功能,具体功能类似于PPT等主流软件DockWidget中项目的布局样式,通过点击按钮来控制布局的展开和折叠。
在这里插入图片描述
起初,打算使用Qt自带的QToolBox来实现这一功能,但实际结果并不能符合预期要求,ToolBox会默认展开一组不能完全折叠,而且会改变布局,看起来十分突兀,具体效果参见博文QToolBox实现QQ好友列表功能
然后,打算借以往项目经验,使用删除和重建布局的方式来伪实现折叠和展开效果,发现效果并不理想,并且会导致布局中的数据在向主窗口进行信号发送和连接时很容易报错。
最后,发现借助QWidget类本身自带的方法setVisible(bool),就可以实现想要的功能,参考博文用Qt实现QQ好友列表界面伸缩功能

2.功能实现

2.1LockerButton

LockerButton.h

/*
* @file                 LockerButton.h
* @brief                抽屉式Widget控件显隐按钮
* @auther               Tree
* @version              0.0
* @date                 2019.12.31
* @copyright
*/

#ifndef LOCKER_BUTTON_H
#define LOCKER_BUTTON_H

#include <QWidget>
#include <QPushButton>

class QLabel;

class LockerButton : public QPushButton
{
    Q_OBJECT
public:
    /// @brief 构造方法
    explicit LockerButton(QWidget* parent = nullptr);

    /// @brief SetImageLabel
    /// 设置按钮图标
    void SetImageLabel(const QPixmap &pixmap);

    /// @brief SetTextLabel
    /// 设置按钮文字
    void SetTextLabel(QString text);

    /// @brief GetImageHandle
    /// 返回m_imageLabel
    QLabel* GetImageHandle();

    /// @brief GetImageHandle
    /// 返回m_textLabel
    QLabel* GetTextHandle();

private:
    // 按钮图标
    QLabel* m_imageLabel;
    // 按钮文字
    QLabel* m_textLabel;
};

#endif // LOCKER_BUTTON_H

LockerButton.cpp

#include "LockerButton.h"

#include <QLabel>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QDoubleValidator>

LockerButton::LockerButton(QWidget* parent)
    : QPushButton(parent)
{
    m_imageLabel = new QLabel;
    m_imageLabel->setFixedWidth(20);
    m_imageLabel->setScaledContents(true);
    m_imageLabel->setStyleSheet("QLabel{background-color:transparent;}");

    m_textLabel = new QLabel;
    m_textLabel->setStyleSheet("QLabel{background-color:transparent;}");

    QHBoxLayout* mainLayout = new QHBoxLayout;
    mainLayout->addWidget(m_imageLabel);
    mainLayout->addWidget(m_textLabel);
    mainLayout->setMargin(0);
    mainLayout->setSpacing(0);
    this->setLayout(mainLayout);
}

void LockerButton::SetImageLabel(const QPixmap &pixmap)
{
    m_imageLabel->setPixmap(pixmap);
}

void LockerButton::SetTextLabel(QString text)
{
    m_textLabel->setText(text);
}

QLabel* LockerButton::GetImageHandle()
{
    return m_imageLabel;
}

QLabel* LockerButton::GetTextHandle()
{
    return m_textLabel;
}


2.2LockerWidget

LockerWidget.h

/*
* @file                 LockerWidget.h
* @brief                抽屉式Widget
* @auther               Tree
* @version              0.0
* @date                 2019.12.31
* @copyright
*/

#ifndef LOCKER_WIDGET_H
#define LOCKER_WIDGET_H

#include "LockerButton.h"

#include <QWidget>
#include <QLabel>

class LockerWidget : public QWidget
{
    Q_OBJECT
public:
    /// @brief 构造方法
    explicit LockerWidget(QWidget* parent = nullptr);

private:
    void SetUpUI();
    LockerButton* m_sizeButton;
    LockerButton* m_positionButton;
    QWidget* m_sizeWidget;
    QWidget* m_positionWidget;
    quint8 m_sizeList;
    quint8 m_positionList;
};

#endif // LOCKER_WIDGET_H

LockerWidget.cpp

#include "LockerWidget.h"

#include <QLineEdit>
#include <QDoubleValidator>
#include <QPixmap>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QDoubleSpinBox>

LockerWidget::LockerWidget(QWidget* parent)
    : QWidget(parent), m_sizeList(0), m_positionList(0)
{
    SetUpUI();
}

void LockerWidget::SetUpUI()
{
    this->resize(300, 600);

    m_sizeButton = new LockerButton;
    m_sizeButton->setObjectName("LockerButton");
    m_sizeButton->SetTextLabel(u8"大小");
    m_sizeButton->SetImageLabel(QPixmap(":/Dialog/Resources/Collapse.png"));
    m_sizeButton->setStyleSheet("#LockerButton{background-color:transparent}"
        "#LockerButton:hover{background-color:rgba(195,195,195,0.4)}"
        "#LockerButton:pressed{background-color:rgba(127,127,127,0.4)}");

    m_positionButton = new LockerButton;
    m_positionButton->setObjectName("LockerButton");
    m_positionButton->SetTextLabel(u8"替换文字");
    m_positionButton->SetImageLabel(QPixmap(":/Dialog/Resources/Collapse.png"));
    m_positionButton->setStyleSheet("#LockerButton{background-color:transparent}"
        "#LockerButton:hover{background-color:rgba(195,195,195,0.4)}"
        "#LockerButton:pressed{background-color:rgba(127,127,127,0.4)}");

    // Size Widget
    m_sizeWidget = new QWidget;
    m_sizeWidget->setParent(this);
    m_sizeWidget->setFixedHeight(100);
    m_sizeWidget->setVisible(false);

    QLabel* sizeLabel = m_sizeButton->GetTextHandle();
    sizeLabel->setStyleSheet("QLabel{color:rgba(183,71,42,1)}");
    sizeLabel->setFont(QFont("大小", 10, QFont::Black));

    QLabel* heightLabel = new QLabel(u8"高度");
    QLabel* spinLabel = new QLabel(u8"旋转");

    QDoubleSpinBox* heightSpinBox = new QDoubleSpinBox;
    heightSpinBox->setSuffix(u8"厘米");
    heightSpinBox->setFixedWidth(120);
    QDoubleSpinBox* spinSpinBox = new QDoubleSpinBox;
    spinSpinBox->setSuffix(u8"°");
    spinSpinBox->setFixedWidth(120);

    // Position Widget
    m_positionWidget = new QWidget;
    m_positionWidget->setParent(this);
    m_positionWidget->setFixedHeight(100);
    m_positionWidget->setVisible(false);

    QLabel* positionLabel = m_positionButton->GetTextHandle();
    positionLabel->setStyleSheet("QLabel{color:rgba(183,71,42,1)}");
    positionLabel->setFont(QFont("大小", 10, QFont::Black));

    QLabel* titleLabel = new QLabel(u8"标题");
    QLabel* descriptionLabel = new QLabel(u8"说明");

    QLineEdit* titleEdit = new QLineEdit;
    QLineEdit* descriptionEdit = new QLineEdit;

    QGridLayout* sizeLayout = new QGridLayout;
    sizeLayout->addWidget(heightLabel, 0, 0);
    sizeLayout->addWidget(heightSpinBox, 0, 1);
    sizeLayout->addWidget(spinLabel, 1, 0);
    sizeLayout->addWidget(spinSpinBox, 1, 1);
    m_sizeWidget->setLayout(sizeLayout);

    QVBoxLayout* positionLayout = new QVBoxLayout;
    positionLayout->addWidget(titleLabel);
    positionLayout->addWidget(titleEdit);
    positionLayout->addWidget(descriptionLabel);
    positionLayout->addWidget(descriptionEdit);
    m_positionWidget->setLayout(positionLayout);

    QVBoxLayout* vlayout = new QVBoxLayout;
    vlayout->addWidget(m_sizeButton);
    vlayout->addWidget(m_sizeWidget);
    vlayout->addWidget(m_positionButton);
    vlayout->addWidget(m_positionWidget);
    vlayout->addStretch();
    vlayout->setMargin(0);
    vlayout->setSpacing(0);
    this->setLayout(vlayout);

    connect(m_sizeButton, &LockerButton::clicked, [this](bool) {
        if (m_sizeList % 2)
        {
            m_sizeButton->SetImageLabel(QPixmap(":/Dialog/Resources/Collapse.png"));
            //m_sizeList偶数屏蔽Size列表界面,奇数显示Size列表界面
            m_sizeWidget->setVisible(false);
        }
        else
        {
            m_sizeButton->SetImageLabel(QPixmap(":/Dialog/Resources/Expand.png"));
            m_sizeWidget->setVisible(true);
        }
        m_sizeList++; });

    connect(m_positionButton, &LockerButton::clicked, [this](bool) {
        if (m_positionList % 2)
        {
            m_positionButton->SetImageLabel(QPixmap(":/Dialog/Resources/Collapse.png"));
            m_positionWidget->setVisible(false);
        }
        else
        {
            m_positionButton->SetImageLabel(QPixmap(":/Dialog/Resources/Expand.png"));
            m_positionWidget->setVisible(true);
        }
        m_positionList++; });
}

2.3功能实现

在这里插入图片描述

3.说明

主要参考博文https://blog.csdn.net/naibozhuan3744/article/details/102537152

本文属于学习经验记录,存在很多不足,有错误希望大家指正,相互学习,另外需要转载请下方留言后转载。

  • 32
    点赞
  • 134
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: VS2017Qt是一种非常流行的开发工具和框架,可以帮助开发者轻松创建各种应用程序。在VS2017中,可以使用C++或其他语言来编写应用程序,同时Qt提供了丰富的UI库和功能模块,可以让开发者更加便捷地创建桌面和移动平台的应用程序。 在Qt方面,Qt Creator是一个非常好用的开发环境,可以让开发者更加轻松地创建和管理项目,在创建新项目时,可以轻松选择模板和添加依赖项。Qt还提供了许多其他的工具和组件,例如Qt Designer可以帮助开发者在不需要编写代码的情况下创建用户界面,Qt Quick用于创建动态的用户界面并将其与C++代码集成到一起。 在实际开发中,VS2017Qt结合使用可以得到很好的效果。开发者可以使用VS2017来编写C++代码,并通过Qt来创建用户界面和添加功能模块。同时,VS2017也可以通过Qt的插件来支持Qt项目的开发和管理。 总之,VS2017Qt提供了非常强大的开发工具和框架,可以帮助开发者轻松创建各种应用程序,无论是桌面应用程序还是移动平台应用程序。这两个工具有很好的兼容性和互补性,可以让开发者更加高效地完成项目。 ### 回答2: VS2017是微软公司推出的一款强大的集成开发环境,可用于C++和其他编程语言的开发。Qt是一种跨平台的GUI应用程序框架,也可以使用C++编写。 在VS2017中开发Qt应用程序的实践中,我们可以采用Qt插件,让VS2017能够识别和编译Qt代码。安装插件后,我们可以使用VS2017的工具集来创建、管理和构建Qt项目,从而提高开发的效率。 对于初学者来说,使用VS2017开发Qt程序可能会感到有些困难,但是掌握了必要的知识和技能后,我们就能够灵活运用这些工具,轻松地开发出各种功能强大的Qt应用程序。 总之,VS2017提供了许多有用的开发工具,可用于Qt项目的设计、创建和调试,当与Qt框架配合使用时,这些工具可以帮助我们快速、高效地完成开发任务。 ### 回答3: VS2017是一个较为流行的集成开发环境,它提供了强大的工具和功能,可以快速地开发和调试应用程序。而QT则是一个跨平台的GUI应用程序开发框架,它具有良好的可移植性和开发效率。 在使用VS2017进行QT开发实战时,我们可以利用VS2017提供的QT插件来进行QT程序的开发。这样可以大大地减少开发工作量,并加快开发效率。同时,利用VS2017的调试功能也能够快速地发现和解决程序中的问题。 此外,VS2017还支持使用第三方插件进行QT开发,例如:Visual Qt,它是一个免费的插件,支持Windows,Linux,Mac OS X等多种平台。它提供了完整的QT设计器和源码编辑器,使得开发QT程序更加方便和快速。 总的来说,使用VS2017进行QT开发实战可以大大地提高开发效率和程序质量。同时,VS2017也提供了许多便利的工具和功能,使开发更加简单和有趣。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值