Qt自定义控件-抽屉盒子
一、项目运行结果
二、项目目录结构
三、源码
仓库:
https://gitee.com/dieyong/Qt_Learning.git
项目:
CustomComponent/lockerwidget_/lockerwidget1_/LockerWidget
四、关键代码
1、lockerwidget.h
#ifndef LOCKERWIDGET_H #define LOCKERWIDGET_H #include <QWidget> #include <QToolButton> #include <QLabel> #include <QPushButton> #include <QScrollArea> #include <QVBoxLayout> #include <QDebug> #include <QPixmap> #include <QHBoxLayout> #define OPEN_ICON ":/images/Boxopen.png" #define CLOSE_ICON ":/images/Boxclose.png" class LockerButton : public QPushButton { Q_OBJECT public: explicit LockerButton(QWidget* parent = nullptr); void SetImageLabel(const QPixmap &pixmap); void SetTextLabel(QString text); QLabel* GetImageHandle(); QLabel* GetTextHandle(); bool isOpen; private: // 按钮图标 QLabel* m_imageLabel; // 按钮文字 QLabel* m_textLabel; }; //================================================================== class LockerWidget : public QWidget { Q_OBJECT public: explicit LockerWidget(QWidget* parent = nullptr); ~LockerWidget(); void add_locker(QStringList names,QList<QWidget*> widgets); void deleteAllitemsOfLayout(QLayout* layout); QScrollArea* get_scrollArea() const { return this->scrollArea; } QWidget* get_scrollWidget() const { return this->scrollWidget; } private: void SetUpUI(); QVBoxLayout* mainLayout; QVBoxLayout* layout_widgetScroll; LockerButton* m_Button; QWidget* m_Widget; QList<LockerButton*> Buttons; QList<QWidget*> Widgets; QScrollArea* scrollArea; QWidget* scrollWidget; QPixmap pixmap_open; QPixmap pixmap_close; public slots: void slot_btn(bool); }; #endif // LOCKERWIDGET_H2、lockerwidget.cpp
#include "lockerwidget.h" LockerButton::LockerButton(QWidget* parent) : QPushButton(parent) { m_imageLabel = new QLabel; m_imageLabel->setFixedWidth(32); 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(4); this->setLayout(mainLayout); this->setStyleSheet("QPushButton{background-color:rgb(250,250,250)}"); this->setMinimumHeight(36);//没有设置最小高度,按钮会缩成一条线 isOpen = false; } 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; } //================================================================== LockerWidget::LockerWidget(QWidget* parent) : QWidget(parent) { mainLayout = new QVBoxLayout; mainLayout->setMargin(0); mainLayout->setSpacing(0); this->setLayout(mainLayout); scrollArea = new QScrollArea; scrollArea->setWidgetResizable(true);//没有它,滚动区域不会让内部 widget 填满视口宽度,导致内容挤在左上角 mainLayout->addWidget(scrollArea); scrollWidget = new QWidget(this); layout_widgetScroll = new QVBoxLayout(scrollWidget); layout_widgetScroll->setMargin(0); layout_widgetScroll->setSpacing(0); pixmap_open = QPixmap(OPEN_ICON); pixmap_close = QPixmap(CLOSE_ICON); } LockerWidget::~LockerWidget() { LockerButton* l = nullptr; QWidget* w = nullptr; if(Buttons.count()>0) { for(int i=0; i<Buttons.count(); ++i) { l = Buttons[i]; if(l != nullptr) { delete l; l = nullptr; } } } if(Widgets.count()>0) { for(int i=0; i<Widgets.count(); ++i) { w = Widgets[i]; if(w != nullptr) { delete w; w = nullptr; } } } } void LockerWidget::add_locker(QStringList names,QList<QWidget*> widgets) { if(names.count() != widgets.count()) { return; } for(int i=0; i<names.count(); ++i) { m_Button = new LockerButton(this); m_Button->SetTextLabel(names[i]); m_Button->SetImageLabel(pixmap_close); connect(m_Button,&LockerButton::clicked,this,&LockerWidget::slot_btn); m_Widget = new QWidget(this); m_Widget->setVisible(false); QHBoxLayout* layout_widget = new QHBoxLayout(m_Widget); layout_widget->setMargin(0); layout_widget->setSpacing(0); layout_widget->addWidget(widgets[i]); Buttons.push_back(m_Button); Widgets.push_back(m_Widget); } deleteAllitemsOfLayout(layout_widgetScroll); for(int i=0; i<Buttons.count(); ++i) { layout_widgetScroll->addWidget(Buttons[i]); layout_widgetScroll->addWidget(Widgets[i]); } layout_widgetScroll->addStretch(); scrollArea->setWidget(scrollWidget); } void LockerWidget::deleteAllitemsOfLayout(QLayout* layout) { QLayoutItem *child; while ((child = layout->takeAt(0)) != nullptr) { ///setParent为NULL,防止删除之后界面不消失 if(child->widget()) { child->widget()->setParent(nullptr); } else if(child->layout()) { deleteAllitemsOfLayout(child->layout()); } delete child; } } void LockerWidget::slot_btn(bool) { LockerButton *btn = qobject_cast<LockerButton *>(sender()); int record = -1; for(int i=0; i<Buttons.count(); ++i) { if(btn == Buttons[i]) { record = i; } } if(record == -1) { return; } btn->isOpen = !btn->isOpen; if(btn->isOpen) { //true //切换图标 btn->SetImageLabel(pixmap_open); //显示widget Widgets[record]->setVisible(true); }else { //false //切换图标 btn->SetImageLabel(pixmap_close); //隐藏widget Widgets[record]->setVisible(false); } }3、form_mainui.h
#ifndef FORM_MAINUI_H #define FORM_MAINUI_H #include <QWidget> namespace Ui { class Form_mainui; } class Form_mainui : public QWidget { Q_OBJECT public: explicit Form_mainui(QWidget *parent = nullptr); ~Form_mainui(); private: Ui::Form_mainui *ui; }; #endif // FORM_MAINUI_H4、form_mainui.cpp
#include "form_mainui.h" #include "ui_form_mainui.h" #include "lockerwidget.h" #include <QSizePolicy> #include <QPushButton> #include <QLabel> #include <QHBoxLayout> Form_mainui::Form_mainui(QWidget *parent) : QWidget(parent), ui(new Ui::Form_mainui) { ui->setupUi(this); //创建抽屉盒子对象 LockerWidget* lockerWidget = new LockerWidget; QVBoxLayout* modelLayout = new QVBoxLayout(ui->modelWidget); modelLayout->setMargin(0); modelLayout->addWidget(lockerWidget); ui->modelWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);//没有拉伸策略,不随窗口扩展 QStringList names; names << "电源设备" << "支路设备" << "变压器设备" << "负荷元件" << "测量设备" << "分布式电源" << "连接元件" << "通信元件" << "逻辑设备" << "其它元件" << "自定义元件"; QList<QWidget*> drawerWidgets; for (int i = 0; i < names.count(); ++i) { QWidget* w = new QWidget(ui->modelWidget); QHBoxLayout* hLayout = new QHBoxLayout(w); QPushButton *btn = new QPushButton("test", w); btn->setFixedHeight(36); btn->setStyleSheet(R"( QPushButton {background-color: #4de85a;border: 1px solid #CCCCCC;border-radius: 4px;color: #FFFFFF;font-size: 18px;padding: 0 12px;} QPushButton:hover { color: #FFFF88; } QPushButton:pressed { color: #FFD700; } )"); QLabel *label = new QLabel("test", w); label->setFixedHeight(36); label->setStyleSheet(R"( QLabel { background-color: #E3F2FD; border: 1px solid #CCCCCC; border-radius: 4px; font-size: 18px; color: #333333; padding: 0 12px; } )"); hLayout->addWidget(btn); hLayout->addStretch();//加一根弹簧 hLayout->addWidget(label); drawerWidgets.append(w); } QList<QWidget*> widgets = drawerWidgets; //向抽屉盒子中添加抽屉 lockerWidget->add_locker(names,widgets); } Form_mainui::~Form_mainui() { delete ui; }五、参考
Qt--自定义抽屉盒子控件_qt 抽屉控件-CSDN博客
