基于Qt 实现的list窗口,可以包含多个listWidget,每个窗口都可以展开和折叠,多个窗口是采用QVBoxLayout控件进行排布,当每个窗口折叠后,标题栏显示在窗口最顶部,形如下图:
话不多说,上代码:
#include <QApplication>
#include <QMainWindow>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QListWidget>
#include <QList>
#include <QObject>
#include <QDebug>
// 定义可折叠列表窗口类
class CollapsibleListWidget : public QWidget {
Q_OBJECT
public:
CollapsibleListWidget(const QString& title, QWidget* parent = nullptr) : QWidget(parent) {
// 创建标题栏按钮
titleButton = new QPushButton(title, this);
titleButton->setStyleSheet("text-align: left;");
connect(titleButton, &QPushButton::clicked, this, &CollapsibleListWidget::toggleCollapse);
// 创建列表窗口, 初始默认显示状态
listWidget = new QListWidget(this);
listWidget->setVisible(true);
isVisible = true;
// 创建布局
layout = new QVBoxLayout(this);
layout->addWidget(titleButton);
layout->addWidget(listWidget);
layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0);
}
// 获取列表窗口指针,方便外部操作列表
QListWidget* getListWidget() {
return listWidget;
}
signals:
void change();
private slots:
// 切换列表窗口的展开和折叠状态
void toggleCollapse() {
bool visibleFlag = listWidget->isVisible();
listWidget->setVisible(!visibleFlag);
isVisible = !visibleFlag;
qDebug() << "have send signal";
emit change();
}
public:
bool listVisible() const{
return isVisible;
}
private:
QPushButton* titleButton;
QListWidget* listWidget;
QVBoxLayout* layout;
bool isVisible;
};
// 主窗口类
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget* parent = nullptr) : QMainWindow(parent) {
// 创建中央部件
QWidget* centralWidget = new QWidget(this);
// 创建垂直布局
mainLayout = new QVBoxLayout(centralWidget);
QList<CollapsibleListWidget *> allListWidget;
// 创建第一个可折叠列表窗口
listWidget1 = new CollapsibleListWidget("List Window 1", this);
listWidget1->getListWidget()->addItem("Item 1-1");
listWidget1->getListWidget()->addItem("Item 1-2");
mainLayout->addWidget(listWidget1);
allListWidget.push_back(listWidget1);
// 创建第二个可折叠列表窗口
listWidget2 = new CollapsibleListWidget("List Window 2", this);
listWidget2->getListWidget()->addItem("Item 2-1");
listWidget2->getListWidget()->addItem("Item 2-2");
mainLayout->addWidget(listWidget2);
allListWidget.push_back(listWidget2);
listWidget3 = new CollapsibleListWidget("List Window 3", this);
listWidget3->getListWidget()->addItem("Item 2-1");
listWidget3->getListWidget()->addItem("Item 2-2");
mainLayout->addWidget(listWidget3);
allListWidget.push_back(listWidget3);
for (auto item : allListWidget)
{
QObject::connect(item, &CollapsibleListWidget::change, this, [=]()
{
bool flagVisible = false;
for(auto itemVisible: allListWidget)
{
flagVisible = flagVisible || itemVisible->listVisible();
}
if(!flagVisible)
{
mainLayout->addStretch(0);
}
else
{
if (mainLayout->count() > allListWidget.size())
{
mainLayout->removeItem(mainLayout->itemAt(mainLayout->count() - 1));
}
} });
}
setCentralWidget(centralWidget);
}
private:
CollapsibleListWidget *listWidget1;
CollapsibleListWidget *listWidget2;
CollapsibleListWidget *listWidget3;
QVBoxLayout *mainLayout;
};
#include "main.moc"
int main(int argc, char* argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
解释:
CollapsibleListWidget
类
- 成员变量:
titleButton
:用于显示标题并作为展开 / 折叠的触发按钮。listWidget
:实际显示列表项的QListWidget
。layout
:垂直布局,用于排列标题按钮和列表窗口。
- 构造函数:初始化标题按钮、列表窗口和布局,并将标题按钮的点击信号连接到
toggleCollapse
槽函数。 getListWidget
方法:返回listWidget
的指针,方便在外部向列表中添加数据。toggleCollapse
槽函数:通过改变listWidget
的可见性来实现列表窗口的展开和折叠。
通过变量 QList<CollapsibleListWidget *> allListWidget; 对已经添加的listWidget进行管理,可循环简单完成每个listWidget的connect;