使用封装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);**后,此报错解决。