记录封装QComboBox类时报错解决过程

使用封装QComboBox类时报读取访问权限冲突问题记录

之前封装了一个QMutiComBox类继承QComboBox类,是一个多选下拉框效果,如下图:
在这里插入图片描述
代码如下:

#ifndef QMUTICOMBOBOX_H
#define QMUTICOMBOBOX_H

#include <QWidget>
#include <QListWidget>
#include <QLineEdit>
#include <QComboBox>
#include <QCheckBox>
#include <QDebug>
#include <QList>

class QMutiComboBox : public QComboBox
{
    Q_OBJECT
public:
    QMutiComboBox(QWidget *parent = 0);
    QMutiComboBox(const QMap<int,QString> &mapData,QWidget *parent = 0);
    ~QMutiComboBox();

public:
    void setModelData(const QMap<int,QString> &mapData);
    void setCheckedItems(const QString &data);
    QString getSelectedItemDatas();
    QList<int> selectedItemIndexes;

private slots:
    void stateChanged(int state);
    void textChanged(const QString &text);

public:
    void clear();

public:
    QListWidget *pListWidget;
    QLineEdit *pLineEdit;
    QString strSelectedText;
    bool bSelected;

signals:
    void selectedItemChanged(QList<int> selectedItemIndexes);
};

#endif // QMUTICOMBOBOX_H

#include "QMutiComboBox.h"

QMutiComboBox::QMutiComboBox(QWidget *parent) : QComboBox(parent)
{
    pListWidget = new QListWidget(this);
    pListWidget->setObjectName("MutiComboBoxListWidget");
    pLineEdit = new QLineEdit(this);
    //this->setModel(pListWidget->model());
    //this->setView(pListWidget);
    this->setLineEdit(pLineEdit);
    pLineEdit->setReadOnly(true);
    connect(pLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(textChanged(const QString &)));
}

QMutiComboBox::QMutiComboBox(const QMap<int, QString> &mapData, QWidget *parent) : QComboBox(parent)
{
    pListWidget = new QListWidget(this);
    pLineEdit = new QLineEdit(this);
    QMapIterator<int,QString> it(mapData);
    while(it.hasNext()){
        it.next();
        QListWidgetItem *pItem = new QListWidgetItem(pListWidget);
        pListWidget->addItem(pItem);
        pItem->setData(Qt::UserRole,it.key());
        QCheckBox *pCheckBox = new QCheckBox(this);
        pCheckBox->setText(it.value());
        pListWidget->addItem(pItem);
        pListWidget->setItemWidget(pItem,pCheckBox);
        connect(pCheckBox,SIGNAL(stateChanged(int)),this,SLOT(stateChanged(int)));
    }

    this->setModel(pListWidget->model());
    this->setView(pListWidget);
    this->setLineEdit(pLineEdit);
    pLineEdit->setReadOnly(true);
    connect(pLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(textChanged(const QString &)));
}

QMutiComboBox::~QMutiComboBox()
{
    delete pListWidget;
    delete pLineEdit;
}

void QMutiComboBox::setModelData(const QMap<int, QString> &mapData)
{
    int count = pListWidget->count();
    for (int row = 0; row < count;++row)
    {
        QListWidgetItem *pItem = pListWidget->takeItem(0);
        delete pItem;
    }

    QMapIterator<int,QString> it(mapData);
    while(it.hasNext()){
        it.next();
        QListWidgetItem *pItem = new QListWidgetItem(pListWidget);
        pListWidget->addItem(pItem);
        pItem->setData(Qt::UserRole,it.key());
        QCheckBox *pCheckBox = new QCheckBox(this);
        pCheckBox->setText(it.value());
        pListWidget->addItem(pItem);
        pListWidget->setItemWidget(pItem,pCheckBox);
        connect(pCheckBox,SIGNAL(stateChanged(int)),this,SLOT(stateChanged(int)));
    }
    this->setModel(pListWidget->model());
    this->setView(pListWidget);
}

void QMutiComboBox::setCheckedItems(const QString &data)
{
    clear();

    if(data.isEmpty())
        return;

    int count = pListWidget->count();
    QStringList list(data.split(";"));
    QStringListIterator it(list);
    while(it.hasNext())
    {
        QString da = it.next();
        for(int i=0;i<count;++i)
        {
            QListWidgetItem *pItem = pListWidget->item(i);
            if(pItem->data(Qt::UserRole).toString() == da)
            {
                QWidget *pWidget = pListWidget->itemWidget(pItem);
                QCheckBox *pCheckBox = (QCheckBox*) pWidget;
                pCheckBox->setChecked(true);
                break;
            }
        }
    }
}

QString QMutiComboBox::getSelectedItemDatas()
{
    int nCount = pListWidget->count();
    QString strSeltectedData("");
    for(int i=0; i < nCount; ++i)
    {
        QListWidgetItem *pItem = pListWidget->item(i);
        QWidget *pWidget = pListWidget->itemWidget(pItem);
        QCheckBox *pCheckBox = (QCheckBox*) pWidget;
        if(pCheckBox->isChecked()){
            QString strText = pItem->data(Qt::UserRole).toString().trimmed();
            strSeltectedData.append(strText).append(";");
        }
    }

    if(strSeltectedData.endsWith(";"))
    {
        strSeltectedData.remove(strSeltectedData.count()-1,1);
    }
    return strSeltectedData;
}

void QMutiComboBox::stateChanged(int state)
{
    bSelected = true;
    QString strSelectedData("");
    strSelectedText.clear();
    QObject *object= QObject::sender();
    QCheckBox *pSenderCheckBox = static_cast<QCheckBox*>(object);
    int nCount = pListWidget->count();
    selectedItemIndexes.clear();
    for(int i=0; i < nCount; ++i)
    {
        QListWidgetItem *pItem = pListWidget->item(i);
        QWidget *pWidget = pListWidget->itemWidget(pItem);
        QCheckBox *pCheckBox = (QCheckBox*) pWidget;
        if(pCheckBox->isChecked()){
            QString strText = pCheckBox->text();
            strSelectedData.append(strText).append(";");
            selectedItemIndexes.append(i);
        }
    }
    emit selectedItemChanged(selectedItemIndexes);


    if(strSelectedData.endsWith(";"))
    {
        strSelectedData.remove(strSelectedData.count()-1,1);
    }

    if(!strSelectedData.isEmpty())
    {
        strSelectedText = strSelectedData;
        pLineEdit->setText(strSelectedData);
        pLineEdit->setToolTip(strSelectedData);
    }
    else
    {
        pLineEdit->clear();
    }
    bSelected = false;
}

void QMutiComboBox::textChanged(const QString &text)
{
    if(!bSelected)
    {
        pLineEdit->setText(strSelectedText);
    }
}

void QMutiComboBox::clear()
{
    int nCount = pListWidget->count();
    for(int i=0; i < nCount; ++i)
    {
        QListWidgetItem *pItem = pListWidget->item(i);
        QWidget *pWidget = pListWidget->itemWidget(pItem);
        QCheckBox *pCheckBox = (QCheckBox*) pWidget;
        if(pCheckBox->isChecked()){
            pCheckBox->setChecked(false);
        }
    }
    strSelectedText = "";
    pLineEdit->setText("");
}

今天在使用时程序崩溃了,表现在当我连续两次调用setModelData函数,程序就会崩溃,报如下错误:

引发了异常: 读取访问权限冲突。
q->**data**0xFFFFFFFFFFFFFFF3

经过一系列排查,我发现问题出在setModelData函数最后一行代码上:**this->setView(pListWidget);**想想也是,同一个视图设置两次,你不报错谁报错,改成:**if(this->view() != pListWidget) this->setView(pListWidget);**后,此报错解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值