使用Qt设计一个带下拉CheckBox的ComboBox控件

1.背景

项目需要设计一个带下拉选择的ComboBox,这里重写一个QComboBox实现一下

2.思路

查了一下文档发现,选择QComboBox作为模板,设计ComboBox下拉界面的model和view,用checkBox作为item,实现一下点击功能,即可实现。
这里解决了点击CheckBox空白处无法进行选择,滚动条显示的异常,二次打开下拉菜单item项缺失的问题,可以参考一下

3.代码

1.头文件


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

class CheckComboBox: public QComboBox
{
     
    Q_OBJECT

public:
    explicit CheckComboBox(QWidget *parent = 0);
    ~CheckComboBox();

    /*重置*/
    void resetListWidget();

    /*赋值*/
    void setDataList(const QList<QString> &dataList, const QString &recordText = "");

    /*获取combox含有的所有名称*/
    QList<QString> getLstName();

    /*获取combox选中的所有名称*/
    QList<QString> getSelectLstName();

private slots:

    void updateCheckData(const int &index);

    void updateShowText();

protected:
    virtual void showPopup();
    virtual void hidePopup();

private:
    QLineEdit *m_textShow;
    QListWidget *m_widgetList;
    QList<QCheckBox *> m_checkBoxList;
    QList<QString> m_lstName;
};

2.功能和实现

#include "checkcombobox.h"

CheckComboBox::CheckComboBox(QWidget *parent)
    : QComboBox(parent)
    , m_textShow(new QLineEdit(this))
    , m_widgetList(new QListWidget(this))
{
     
    m_textShow->setText(" ");
    m_textShow->setReadOnly(true);
    m_textShow->setStyleSheet("background:#444444;");

    setLineEdit(m_textShow);
    setMinimumWidth(120);
    setDataList(QList<QString>(),QString());
    // 获取点击状态
    connect(this, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
          [=](int index)
    {
     
        updateCheckData(index);
    });
}

CheckComboBox::~CheckComboBox()
{
     
}

void CheckComboBox::resetListWidget()
{
     
    if(m_widgetList != NULL)
    {
     
        delete m_widgetList;
        m_widgetList = new QListWidget(this);
    }
    m_checkBoxList.clear();
}

void CheckComboBox::setDataList(const QList<QString> &data, const QString &recordText)
{
     
    m_lstName = data;
    //清空listwidget
    resetListWidget();
    QStringList itemNameList = recordText.split(";");

    for (int i = 0; i < data.size(); i++)
    {
     
        QListWidgetItem *item = new QListWidgetItem(m_widgetList);
        item->setData(Qt::UserRole, i);
        m_widgetList->addItem(item);

        QCheckBox *checkBox = new QCheckBox(this);
        checkBox->setText(data.at(i));
        m_checkBoxList.append(checkBox);
        m_widgetList->setItemWidget(item, checkBox);

        if (itemNameList.contains(data.at(i)))
        {
     
            checkBox->setChecked(true);
        }
        connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(updateShowText()));
    }
    setModel(m_widgetList->model());
    setView(m_widgetList);
    m_textShow->setText(recordText);
}

QList<QString> CheckComboBox::getLstName()
{
     
    return m_lstName;
}

QList<QString> CheckComboBox::getSelectLstName()
{
     
    QList<QString> sellstName;
    for (int i = 0; i < m_checkBoxList.count(); i++)
    {
     
        if (m_checkBoxList[i]->isChecked())
        {
     
            sellstName.append(m_checkBoxList[i]->text());
        }
    }
    return sellstName;
}

void CheckComboBox::updateCheckData(const int &index)
{
     
    if (index < 0)
    {
     
        return;
    }

    if (this->count() > 0)
    {
     
        setCurrentIndex(0);
    }

    // 取反
    if (m_checkBoxList.count() > index)
    {
     
        if (m_checkBoxList[index]->isChecked())
        {
     
            m_checkBoxList[index]->setChecked(false);
        }
        else
        {
     
            m_checkBoxList[index]->setChecked(true);
        }
    }
}

void CheckComboBox::updateShowText()
{
     
    QList<QString> showTextList = getSelectLstName();
    QString showText;

    for (int i = 0; i < showTextList.count(); i++)
    {
     
        showText += showTextList[i];
        if (i + 1 != showTextList.count())
        {
     
            showText += ";";
        }
    }
    m_textShow->setText(showText);
}

void CheckComboBox::showPopup()
{
     
    QComboBox::showPopup();
}

void CheckComboBox::hidePopup()
{
     
    // 重置一下滚动条,防止出现widgetList的滚动条在界面最底下
    QScrollBar *bar = m_widgetList->verticalScrollBar();
    bar->setValue(bar->minimum());
    QComboBox::hidePopup();
}

你可能感兴趣的:(Qt,C++,窗体)