qt 折叠与展开 窗口,折叠列表,展开列表,抽屉效果,根据窗口大小自动产生滚动条

发布时间 2023-12-16 19:59:13作者: 红湿处

 

 

自定义折叠控件,h头文件

#ifndef QUESTIONBANKWIDGET_H
#define QUESTIONBANKWIDGET_H

#include <QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QToolButton>
#include <QPushButton>
#include <QLabel>
#include <QListWidget>
#include <memory>

class QuestionBankWidget : public QWidget
{
    Q_OBJECT
public:
    explicit QuestionBankWidget(QWidget *parent = nullptr);

    /*
     * @brief 主布局
     * @prama
     * @return
     */
    void mainLayout();
    /*
     * @brief 展开与折叠
     * @prama
     * @return
     */
    void fold_unfold();

signals:

private:
    std::unique_ptr<QVBoxLayout> m_mainLayout;

    std::unique_ptr<QWidget> m_titleWid;
    std::unique_ptr<QHBoxLayout> m_titlehly;
    std::unique_ptr<QPushButton> m_titleNameBt;
    std::unique_ptr<QToolButton> m_foldBt;

    std::unique_ptr<QWidget> m_questionWidget;
    std::unique_ptr<QVBoxLayout> m_listvlay;

    std::unique_ptr<QHBoxLayout> add_del_bt_hlay;
    std::unique_ptr<QToolButton> m_addquestion;
    std::unique_ptr<QToolButton> m_delquestion;

    std::unique_ptr<QListWidget> m_listwidget;
    bool m_fold1{false};
};

#endif // QUESTIONBANKWIDGET_H

自定义折叠控件,cpp文件

#include "questionbankwidget.h"
#include <QPropertyAnimation>

QuestionBankWidget::QuestionBankWidget(QWidget *parent)
    : QWidget{parent}
    , m_mainLayout( new QVBoxLayout(this))
    , m_titleWid(new QWidget(this))
    , m_titlehly(new QHBoxLayout(this))
    , m_titleNameBt(new QPushButton(this))
    , m_foldBt(new QToolButton(this))
    , m_questionWidget(new QWidget(this))
    , m_listvlay(new QVBoxLayout(this))
    , add_del_bt_hlay(new QHBoxLayout(this))
    , m_addquestion(new QToolButton())
    , m_delquestion(new QToolButton())
    , m_listwidget(new QListWidget(this))
{

    this->setAttribute(Qt::WA_StyledBackground);
    this->setObjectName("QuestionBankWidget");
    m_titleNameBt->setObjectName("m_titleNameBt");
    m_titleWid->setObjectName("m_titleWid");
    m_titleWid->setFixedHeight(35);
    m_titleNameBt->setText("学生管理"); 
    m_foldBt->setObjectName("m_foldBt");
    QPixmap pixmap(":/resource/arrow_pressed_top.png");
    m_foldBt->setIcon(QIcon(pixmap));
    connect(m_foldBt.get(),&QToolButton::clicked,this,[&](){
        fold_unfold();
    });
    connect(m_titleNameBt.get(),&QPushButton::clicked,this,[&](){
        fold_unfold();
    });

    // 初始界面时显示的固定高度
    this->setFixedHeight(35);
    // 题库列表固定高度
    m_questionWidget->setFixedHeight(0);
    m_addquestion->setText("添加");
    m_delquestion->setText("删除");
    m_listwidget->addItem("学生1"); //
    m_listwidget->addItem("学生2");
    m_listwidget->addItem("学生3");
    m_listwidget->addItem("学生4");
    m_listwidget->addItem("学生5");
    m_listwidget->addItem("学生6");
    m_listwidget->addItem("学生7");
    m_listwidget->addItem("学生8");
    m_listwidget->addItem("学生9");

    mainLayout();
}


void QuestionBankWidget::mainLayout()
{
    // 折叠标题布局 :添加标题名标签和折叠按钮到布局中
    m_titlehly->addWidget(m_titleNameBt.get());
    m_titlehly->addWidget(m_foldBt.get());
    m_titlehly->setContentsMargins(0,0,0,0);
    // 将标题布局添加到标题widget中
    m_titleWid->setLayout(m_titlehly.get());

    // 将添加题库的按钮和删除题库的按钮添加到add_del_bt_hlay布局中
    add_del_bt_hlay->addStretch();
    add_del_bt_hlay->addWidget(m_addquestion.get());
    add_del_bt_hlay->addWidget(m_delquestion.get());
    add_del_bt_hlay->setContentsMargins(0,0,0,0);

    // 添加到布局中
    m_listvlay->addLayout(add_del_bt_hlay.get());
    m_listvlay->addWidget(m_listwidget.get());
    m_listvlay->setContentsMargins(0,0,0,0);
    m_questionWidget->setLayout(m_listvlay.get());

    // 添加到主布局中
    m_mainLayout->addWidget(m_titleWid.get());
    m_mainLayout->addWidget(m_questionWidget.get());
    m_mainLayout->addStretch();
    m_mainLayout->setContentsMargins(0,0,0,0);
    this->setLayout(m_mainLayout.get());
}

void QuestionBankWidget::fold_unfold()
{
    if(m_fold1 == false){
        QPixmap pixmap(":/resource/arrow_pressed_down.png");
        m_foldBt->setIcon(QIcon(pixmap));
        QPropertyAnimation* animation = new QPropertyAnimation(this, ""); //qt动画类
        animation->setDuration(15); //动画持续时间15ms ,15毫秒折叠和展示时不卡顿
        animation->setStartValue(0);//动画开始值和结束值
        animation->setEndValue(400);
        connect(animation, &QPropertyAnimation::valueChanged, [this](const QVariant& value){
            m_questionWidget->setFixedHeight(value.toInt());
            this->setFixedHeight(35+value.toInt());
        });
        animation->start(QAbstractAnimation::DeleteWhenStopped);
        m_fold1 = true;
    }
    else
    {
        QPixmap pixmap(":/resource/arrow_pressed_top.png");
        m_foldBt->setIcon(QIcon(pixmap));
        QPropertyAnimation* animation = new QPropertyAnimation(this, ""); //qt动画类
        animation->setDuration(15); //动画持续时间15ms,15毫秒折叠和展示时不卡顿
        animation->setStartValue(400);//动画开始值和结束值
        animation->setEndValue(0);
        connect(animation, &QPropertyAnimation::valueChanged, [this](const QVariant& value){
            m_questionWidget->setFixedHeight(value.toInt());
            this->setFixedHeight(35+value.toInt());
        });
        animation->start(QAbstractAnimation::DeleteWhenStopped);
        m_fold1 = false;
    }
}

加入到自动产生滚动条的控件中

自动产生滚动条的控件,h头文件

#ifndef MANAGETESTQUESTIONS_H
#define MANAGETESTQUESTIONS_H

#include <QWidget>
#include <QVBoxLayout>
#include <QListWidget>
#include <QListWidgetItem>
#include <QScrollArea>
#include <memory>
#include "questionbankwidget.h"

class ManageTestQuestions : public QWidget
{
    Q_OBJECT
public:
    ManageTestQuestions(QWidget *parent = nullptr);

    void mainlayout();

public:


private:
    std::unique_ptr<QVBoxLayout> m_mainlayout;
    std::unique_ptr<QuestionBankWidget> m_questionbankD; 
    std::unique_ptr<QuestionBankWidget> m_questionbankZ; 
    std::unique_ptr<QuestionBankWidget> m_questionbankF; 
    std::unique_ptr<QuestionBankWidget> m_questionbankJ; 

    std::unique_ptr<QScrollArea> m_scrollarea;
    std::unique_ptr<QWidget> m_scrollCenterWidget;
    std::unique_ptr<QVBoxLayout> vlay;

};

#endif // MANAGETESTQUESTIONS_H

自动产生滚动条的控件,cpp文件

#include "managetestquestions.h"
#include <QPropertyAnimation>

ManageTestQuestions::ManageTestQuestions(QWidget *parent )
    : QWidget(parent)
    , m_mainlayout(new QVBoxLayout)
    , m_questionbankD(new QuestionBankWidget)
    , m_questionbankZ(new QuestionBankWidget)
    , m_questionbankF(new QuestionBankWidget)
    , m_questionbankJ(new QuestionBankWidget)
    , m_scrollarea(new QScrollArea)
    , m_scrollCenterWidget(new QWidget)
    , vlay(new QVBoxLayout)
{
    this->setObjectName("ManageTestQuestions");
    mainlayout();
}

void ManageTestQuestions::mainlayout(){
    // 将题库窗口添加到布局中
    vlay->addWidget(m_questionbankD.get());
    vlay->addWidget(m_questionbankZ.get());
    vlay->addWidget(m_questionbankF.get());
    vlay->addWidget(m_questionbankJ.get());
    vlay->addStretch();

    // 给scroll中心部件设置上面的布局
    m_scrollCenterWidget->setLayout(vlay.get());

    // 将scroll中心部件添加到scrollarea中
    m_scrollarea->setWidget(m_scrollCenterWidget.get());
    // 设置自动调整大小
    m_scrollarea->setWidgetResizable(true);

    // 将scroll添加到主布局中
    m_mainlayout->addWidget(m_scrollarea.get());
    this->setLayout(m_mainlayout.get());
}