Qt--自定义抽屉盒子控件


(资料图)

一、前言

因项目需求,需要用到类似于抽屉的控件,归类摆放不同的器件,熟悉Qt的朋友一定马上联想到了​QToolBox​​​,我一开始也是这么做的,但是​​QToolBox​​有个弊端:它同一时刻只能打开一个抽屉,即抽屉间是互斥的关系。虽然能满足归类的需求,但是实际使用过程中很不便利,我希望能同时打开多个抽屉,抽屉的开关由我自己控制,实现真正的自由。

二、思路

采用​​QWidget::setVisible(bool)​​来选择是否显示控件

每添加一个抽屉,就创建一个按钮和一个widget,然后对按钮和widget进去垂直布局,例如:

QT学习基地:

按钮设置​​setVisible(true)​​​,widget设置​​setVisible(false)​​;

然后对所有把所有按钮链接到同一个槽函数中,用​​QObject::sender()​​获取发送对象,然后根据按钮的状态来判断是否显示该按钮对应的widget

三、运行效果

四、详细代码

#ifndef#define#include #include #include #include #include #include #include #include #include #define#defineclass LockerButton : public QPushButton{Q_OBJECTpublic: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_OBJECTpublic:explicit LockerWidget(QWidget* parent = nullptr);~LockerWidget();void add_locker(QStringList names,QListwidgets);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;QListButtons;QListWidgets;QScrollArea* scrollArea;QWidget* scrollWidget;QPixmap pixmap_open;QPixmap pixmap_close;public slots:void slot_btn(bool);};#endif// LOCKERWIDGET_H
#include ""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("background-color:rgb(250,250,250)}");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;mainLayout->addWidget(scrollArea);scrollWidget = new QWidget(this);scrollWidget->setFixedHeight(3000);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(()>0) {for(int i=0; i<(); ++i) {l = Buttons[i];if(l != nullptr) {delete l;l = nullptr;}}}if(()>0) {for(int i=0; i<(); ++i) {w = Widgets[i];if(w != nullptr) {delete w;w = nullptr;}}}}void LockerWidget::add_locker(QStringList names,QListwidgets){if(() != ()) {return;}for(int i=0; i<(); ++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]);_back(m_Button);_back(m_Widget);}deleteAllitemsOfLayout(layout_widgetScroll);for(int i=0; i<(); ++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(sender());int record = -1;for(int i=0; i<(); ++i) {if(btn == Buttons[i]) {record = i;}}if(record == -1) {return;}btn->isOpen = !btn->isOpen;if(btn->isOpen) { //true//切换图标btn->SetImageLabel(pixmap_open);//显示widgetWidgets[record]->setVisible(true);}else { //false//切换图标btn->SetImageLabel(pixmap_close);//隐藏widgetWidgets[record]->setVisible(false);}}//==================================================================

五、代码使用指南

//创建抽屉盒子对象LockerWidget* lockerWidget = new LockerWidget;//准备好抽屉widget(内部放啥自己布局决定)widget_BranchDevice = new QWidget(modelWidget); //支路设备widget_PowerDevice = new QWidget(modelWidget); //电源设备widget_MeasureUnit = new QWidget(modelWidget); //测量设备widget_TransformerDevice = new QWidget(modelWidget); //变压器设备widget_Load = new QWidget(modelWidget); //负荷元件widget_CleanPower = new QWidget(modelWidget); //分布式电源widget_ConmuniceteUnit = new QWidget(modelWidget); //通信元件widget_ConnectUnit = new QWidget(modelWidget); //连接元件widget_LogicDevice = new QWidget(modelWidget); //逻辑设备widget_othersUnit = new QWidget(modelWidget); //其它元件widget_userDIY = new QWidget(modelWidget); //用户自定义元件//准备好抽屉的名字集合、widget集合QStringList names;names << "电源设备" << "支路设备" << "变压器设备" << "负荷元件" << "测量设备"<< "分布式电源" << "连接元件" << "通信元件" << "逻辑设备" << "其它元件"<< "自定义元件";QListwidgets;widgets << widget_PowerDevice << widget_BranchDevice << widget_TransformerDevice<< widget_Load << widget_MeasureUnit << widget_CleanPower << widget_ConnectUnit<< widget_ConmuniceteUnit << widget_LogicDevice << widget_othersUnit << widget_userDIY;//向抽屉盒子中添加抽屉lockerWidget->add_locker(names,widgets);

【领 QT开发教程 学习资料, 点击下方链接莬费领取↓↓ ,先码住不迷路~】

点击这里: