5

我想要一个树视图,它在各个列中显示项目名称、项目描述和两个相关的布尔值。我从修改Editable Tree Mode 示例开始,所以有一个 TreeModel 跟踪一组 TreeItem,每个 TreeItem 不仅有一个子 TreeItem 列表,还有一个 QVariants 列表,它存储一组值,以后可以显示在 QTreeView 的列中。

我设法为两个布尔值添加了另外两列。我还在网上搜索了如何为 QTreeView 和 QAbstractItemModel 添加复选框。我设法让两个布尔列上的复选框以及树层次结构的其余部分正常工作。然而,每列中的所有项目现在都呈现一个复选框和一行文本。

带有复选框的 Qt TreeView

这是我从示例中修改的部分,主要在 TreeModel 中。

树模型.cpp:

bool TreeModel::isBooleanColumn( const QModelIndex &index ) const
{
    bool bRet = false;
    if ( !index.isValid() )
    {
    }
    else
    {
        bRet = ( index.column() == COLUMN_BOL1 ) || ( index.column() == COLUMN_ BOL2 );
    }
    return bRet;
}

Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return 0;
    if ( isBooleanColumn( index ) )
    {
        return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
    }
    else
    {
        return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    }
}

QVariant TreeModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();
    if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::CheckStateRole )
        return QVariant();
    TreeItem *item = getItem(index);
    if ( role == Qt::CheckStateRole && isBooleanColumn( index ) )
    {
        Qt::CheckState eChkState = ( item->data( index.column() ).toBool() ) ? Qt::Checked : Qt::Unchecked;
        return eChkState;
    }
    return item->data(index.column());
}

bool TreeModel::setData(const QModelIndex &index, const QVariant &value,
                        int role)
{
    if (role != Qt::EditRole && role != Qt::CheckStateRole )
        return false;
    TreeItem *item = getItem(index);
    bool result;
    if ( role == Qt::CheckStateRole && isBooleanColumn( index ) )
    {
        Qt::CheckState eChecked = static_cast< Qt::CheckState >( value.toInt() );
        bool bNewValue = eChecked == Qt::Checked;
        result = item->setData( index.column(), bNewValue );
    }
    else
    {
        result = item->setData(index.column(), value);
    }
    if (result)
        emit dataChanged(index, index);
    return result;
}

主窗口.cpp:

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
    …
    QStringList headers;
    headers << tr("Title") << tr("Description") << tr("Hide") << tr("Lock");
    QFile file(":/default.txt");
    file.open(QIODevice::ReadOnly);
    TreeModel *model = new TreeModel(headers, file.readAll());
    file.close();

    …
}

非布尔列下的复选框不响应用户输入,并且布尔列下的文本不可编辑。所以功能方面没有错,但就 UI 而言仍然很麻烦。

我正在让 QTreeWidget 做同样的事情。同时,我不禁想知道我在这里是否还缺少其他东西。我听说一种解决方案是有一个自定义委托;那是唯一的选择吗?

如果有人能指出我还需要做什么,或者提供类似的例子,我将不胜感激。

4

2 回答 2

1

我认为问题出在 Data 方法中。当角色为 CheckStateRole 但列不是布尔值时,您应该返回 QVariant()。

于 2014-03-19T18:58:20.163 回答
0

我有这个问题。由于将child.column()值传递给createIndex()方法,它发生在TreeModel::parent( ) 方法中。它应该是 0。所以,而不是

createIndex(parentItem->childNumber(), child.column(), parentItem);

应该

createIndex(parentItem->childNumber(), 0, parentItem);
于 2017-12-14T12:19:28.343 回答