qt自定义可折叠控件类似QToolBox(支持同时打开多个)

QToolBox 是Qt中的一个控件,用于显示包含多个折叠 Widget(该Widget可自定义)的工具框。每个折叠 Widget 都有一个标题栏,用户可以通过点击标题栏来展开或折叠相应的Widget。QToolBox 也提供了简单的api让用户可以轻松创建折叠控件。
但是该控件不支持同时展开多个Widget窗口,这样就使得很多的需求得不到满足,所以我们只能通过自定义控件来实现想要的功能。

ToolBoxWidget

首先创建ToolBoxWidget类,该类主要作用是可包含多个折叠Widget,同时当widget的内容大于ToolBoxWidget时,会自动添加滚动条。

ToolPanel

该类作用是创建标题栏,并且当点击标题时可将widget折叠或打开。

代码如下:

//toolbox_widget.h
#ifndef TOOLBOX_WIDGET_H_
#define TOOLBOX_WIDGET_H_
#include <QFrame>

class ToolPlane:public QFrame
{
	Q_OBJECT
public:
	explicit ToolPlane(QWidget* parent = nullptr);
	~ToolPlane();
	void initUI();
	void setWidget(const QString& title, QWidget* widget);
	void expand();
	void collapse();
	void onPushButtonFoldClicked();
private:
	class QLabel* m_pLabel;
	QWidget* m_widgetPlane;
	QWidget* widgetContent;
	bool m_bIsExpanded;
	class QVBoxLayout* widget_content_lyt;
	class QPushButton* pushButtonFold;
};

class ToolBoxWidget:public QFrame
{
	Q_OBJECT
public:
	explicit ToolBoxWidget(QWidget* parent = nullptr);
	~ToolBoxWidget();
	void initUI();
	void addWidget(const QString& title, QWidget* widget);
private:
	class QScrollArea* m_scrollArea;
	class QVBoxLayout* m_pContentVBoxLayout;
};
#endif
//toolbox_widget.cpp
#include "toolbox_widget.h"
#include <QBoxLayout>
#include <QScrollArea>
#include <QPushButton>
#include <QLabel>

ToolPlane::ToolPlane(QWidget* parent ):QFrame(parent), m_bIsExpanded(true)
{
}
ToolPlane::~ToolPlane()
{
}
void ToolPlane::initUI()
{
	QVBoxLayout* verticalLayout = new QVBoxLayout(this);
	verticalLayout->setContentsMargins(0, 0, 0, 0);
	pushButtonFold = new QPushButton(this);
	pushButtonFold->setMinimumSize(QSize(0, 24));
	pushButtonFold->setCheckable(false);
	pushButtonFold->setFlat(true);
	widgetContent = new QWidget(this);
	widget_content_lyt = new QVBoxLayout(widgetContent);
	widget_content_lyt->setSpacing(0);
	widget_content_lyt->setContentsMargins(0, 0, 0, 0);
	m_pLabel = new QLabel(this);
	m_pLabel->setFixedSize(24, 24);
	m_pLabel->setPixmap(QPixmap(":/qss_icons/dark/rc/arrow_up@2x.png").scaled(m_pLabel->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
	QHBoxLayout* layout = new QHBoxLayout(pushButtonFold);
	layout->setContentsMargins(0, 0, 0, 0);
	layout->addStretch(1);
	layout->addWidget(m_pLabel);
	connect(pushButtonFold, &QPushButton::clicked, this, &ToolPlane::onPushButtonFoldClicked);
	verticalLayout->addWidget(pushButtonFold);
	verticalLayout->addWidget(widgetContent);
}
void ToolPlane::setWidget(const QString& title, QWidget* widget)
{
	if(m_widgetPlane)
	{
		widget_content_lyt->removeWidget(m_widgetPlane);
		m_widgetPlane = nullptr;
	}
	pushButtonFold->setText(title);
	widget_content_lyt->addWidget(widget);
}

void ToolPlane::expand()
{
	widgetContent->show();
	m_bIsExpanded = true;
	m_pLabel->setPixmap(QPixmap(":/qss_icons/dark/rc/arrow_up@2x.png").scaled(m_pLabel->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
}

void ToolPlane::collapse()
{
	widgetContent->hide();
	m_bIsExpanded = false;
	m_pLabel->setPixmap(QPixmap(":/qss_icons/dark/rc/arrow_down@2x.png").scaled(m_pLabel->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
}

void ToolPlane::onPushButtonFoldClicked()
{
	if (m_bIsExpanded) {
		collapse();
	}
	else {
		expand();
	}
}

ToolBoxWidget::ToolBoxWidget(QWidget* parent):QFrame(parent)
{
}
void ToolBoxWidget::initUI()
{
	QVBoxLayout* main_lyt = new QVBoxLayout(this);
	main_lyt->setContentsMargins(0, 0, 0, 0);

	QFrame* scroll_area_frame = new QFrame();
	m_pContentVBoxLayout = new QVBoxLayout(scroll_area_frame);
	m_pContentVBoxLayout->setContentsMargins(0, 0, 0, 0);
	m_pContentVBoxLayout->setSpacing(2);
	m_pContentVBoxLayout->setAlignment(Qt::AlignTop);//重要

	m_scrollArea = new QScrollArea(this);
	m_scrollArea->setWidget(scroll_area_frame);
	m_scrollArea->setWidgetResizable(true);//重要
	m_scrollArea->setFrameShape(QFrame::NoFrame);//重要 
	main_lyt->addWidget(m_scrollArea);//重要
}
void ToolBoxWidget::addWidget(const QString& title, QWidget* widget)
{
	ToolPlane* page = new ToolPlane();
	page->initUI();
	page->setWidget(title, widget);
	m_pContentVBoxLayout->addWidget(page);
}

ToolBoxWidget::~ToolBoxWidget()
{
}
//使用示例
#include "toolbox_widget.h"
QFrame* create_toolbox_widget()
{
	ToolBoxWidget* tbw = new ToolBoxWidget();
	tbw->initUI();
	tbw->addWidget(u8"widget1", new QLabel("111"));
	tbw->addWidget(u8"widget1", new QLabel("222"));
	tbw->addWidget(u8"widget1", new QLabel("333"));
}

如果帮大家解决了问题的话请点赞加关注吧~

请添加图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值