5

我有一个模型

class TreeModel : public QAbstractItemModel

TreeItem我用我的排除列==1的实例填充。在第 1 列中,我创建了CheckBoxes

QVariant TreeModel::data(const QModelIndex &index, int role) const {
    if (!index.isValid())
        return QVariant();

    if (role != Qt::DisplayRole) {
        if (role == Qt::CheckStateRole) {
            if (index.column() == 1) {
                if (index.row() == 1) {
                    return Qt::Unchecked;
                } else
                    return Qt::Checked;
            }
        }
        return QVariant();
    }
    if (role == Qt::DisplayRole) {
        if (index.column() != 1) {
            TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
            return item->data(index.column());
        }
    }
    return QVariant();
  }

我可以将这些 CheckBoxes 雕像设置为Qt::CheckedorQt::Unchecked但我的问题是: 稍后单击它们时我无法更改它们(但是setData用适当的index.column==1and调用role==Qt::CheckStateRole)。我见过的例子ItemDelegate- 只有这似乎有效。这是真的?在这种情况下我必须使用委托吗?

这是我的setData()功能:

bool TreeModel::setData(const QModelIndex & index, const QVariant & value,
        int role) {
    if (role==Qt::CheckStateRole && index.column() == 1) {
        TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
        QTreeWidgetItem *check = static_cast<QTreeWidgetItem*>(index.internalPointer());

        //if (item->data(index.column()) == Qt::Checked)
        if (value == Qt::Checked){
            int i=1;
            //check->setCheckState(1,Qt::Checked); //SIGSEGV
        }else{
            //(item->data(index.column())) = Qt::Unchecked;
            int i=2;
            //check->setCheckState(1,Qt::Unchecked);
        }

        emit dataChanged(index, index);
        return true;
    }
    emit dataChanged(index, index);
    return true;;
}


Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const {
    if (!index.isValid())
        return 0;

    return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable |  Qt::ItemIsEditable;
  }
4

4 回答 4

6

我不明白 Qt 的概念。您必须在setData()(存储检查状态)中设置数据,然后data()使用为复选框返回的新值填充模型,如下所示:

setData()

bool TreeModel::setData(const QModelIndex & index, const QVariant & value, int role) {
    if (role == Qt::CheckStateRole && index.column() == 1) {
        TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
        QTreeWidgetItem *check = static_cast<QTreeWidgetItem*>(index.internalPointer());

        if (value == Qt::Checked) {
            checkedState_ = Qt::Checked;
        }
        else {
            checkedState_ = Qt::Unchecked;
        }
    }
    emit dataChanged(index, index);
    return true;
}

data()

QVariant TreeModel::data(const QModelIndex &index, int role) const {
    if (!index.isValid())
        return QVariant();

    if (role == Qt::CheckStateRole) {
        if (index.column() == 1) {
            return checkedState_;
        }
    }
    else if (role == Qt::DisplayRole) {
        if (index.column() != 1) {
            TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
            return item->data(index.column());
        }
    }
    return QVariant();
}  
于 2013-07-22T12:25:54.643 回答
2

对我来说,您总是返回相同的数据结果对我来说似乎很奇怪(CheckStateRole)

 if (role == Qt::CheckStateRole) {
            if (index.column() == 1) {
                if (index.row() == 1) {
                    return Qt::Unchecked;
                } else
                    return Qt::Checked;
            }
        }

未检查 (1,1) 并检查 ( 与 1 , 1 不同)

setData() 被调用,但是,当视图查询模型的值时,你在 data() 中返回总是相同的

于 2013-07-22T12:11:21.363 回答
1

没有任何ItemDelegate,在flags方法中你必须返回标志:Qt::ItemIsUserCheckable

有关更多信息,请参阅:http: //qt-project.org/doc/qt-4.8/qt.html#ItemFlag-enum

于 2014-05-21T14:06:24.710 回答
0

使用来自@Trompa 和@tinky_winky 的示例,我设法创建了这个工作示例,正如@Trompa 建议的那样,我们需要返回一个不同的值或存储该值并将其检索到我们的 data() 中以获取该特定索引处的实际状态。

QVector<int> status;
int SData::getStatus(int pos)
{
    return status.at(pos);
}

void SData::setStatus(int pos,int value)
{
    status.insert(pos, value);
}
QVariant STableModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (role == Qt::DisplayRole)
        return rowList[index.row()][index.column()];
    else if (role == Qt::CheckStateRole && index.column() == 0)
    {

        int status = SData::instance().getStatus(index.row());
        if (status)
            return Qt::Checked;
        else
            return Qt::Unchecked;
    }
    else
        return QVariant();
}

bool STableModel::setData(const QModelIndex &index,
                         const QVariant &value, int role)
{
    if (!index.isValid() /*|| role != Qt::EditRole*/)
        return false;
    if (role == Qt::CheckStateRole)
    {
        if ((Qt::CheckState)value.toInt() == Qt::Checked)
        {
            SData::instance().setStatus(index.row(),1);
            return true;
        }
        else
        {
            SData::instance().setStatus(index.row(), 0);
            return true;
        }
    }
于 2016-01-29T12:28:11.523 回答