问题描述
在从QAbstractTableModel继承的类上正确实现一列复选框时,我遇到了麻烦。表格中的每一行都有一个复选框,当有新项目进入时,该复选框会首先被选中,而我需要取消选中。
我尝试返回setData中最初的Qt :: unchecked,但是当我这样做时,我无法选中/取消选中该框。每个项目都有一个选中的内部属性,可以通过is_Checked(item#),set_Checked(item#)访问。 以下是使用Qt 4.11的.cpp文件中的代码
QVariant ClassItemmodel::data(const QModelIndex &index,int role) const
{
if (!index.isValid())
{
return QVariant();
}
int r = index.row();
if (r >= m_data.size() || r < 0)
return QVariant();
int c = index.column();
if (role == Qt::CheckStateRole)
{
if (c == 0)
{
//line below doesn't work since m_data[r].checked is set to false
//initially,so when it returns Qt::Unchecked,it can't be toggled
//
//return m_data[r].is_Checked ? Qt::Checked : Qt::Unchecked
//this works,but each new item in the table is initially checked since display is
//always true
if (m_data[r].display)
{
return Qt::Checked;
}
else
{
return Qt::Unchecked;
}
}
}
bool ClassItemmodel::setData(const QModelIndex &index,const QVariant &value,int role)
{
if (!index.isValid())
{
return false;
}
emit layoutAboutToBeChanged();
int r = index.row();
int c = index.column();
if (role == Qt::CheckStateRole)
{
if (c == 0)
{
bool b = value.toBool();
m_data[r].display = b;
if(static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked)
{
set_Checked(r,false);
}
else
{
set_Checked(r,true);
}
if (!b)
{
emit layoutChanged();
}
}
}
return qabstractitemmodel::setData(index,value,role);
}
Qt::ItemFlags ClassItemmodel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
int c = index.column();
if (c == 0)
{
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
}
....
}
解决方法
您错误地实施了setData()
。
在data()
中,您可以返回使用return m_data[r].is_Checked ? Qt::Checked : Qt::Unchecked;
。
在setData()
中,
if (role == Qt::CheckStateRole)
{
if (c == 0)
{
bool b = value.toBool();
m_data[r].is_Checked = b;
set_Checked(r,value == Qt::Checked);
emit dataChanged(index,index,{role});
if (!b)
emit layoutChanged();
return true;
}
}
return QAbstractItemModel::setData(index,value,role);
请注意,dataChanged()
必须在子类中发出,并且setData()
在成功设置数据后将返回true。基类实现始终返回false。