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