Qt - QTreeView 和带有复选框列的自定义模型

标签 qt checkbox qtreeview qabstractitemmodel

我想要一个 TreeView ,它在各个列中显示项目名称、项目描述和两个相关的 bool 值。我首先修改 Editable Tree Mode example ,所以有一个 TreeModel 跟踪一组 TreeItem,每个 TreeItem 不仅有一个子 TreeItem 列表,还有一个 QVariants 列表,其中存储一组值,这些值以后可以显示在 QTreeView 的列中。

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

Qt TreeView with Checkboxes

这是我从示例中修改的部分,主要在 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();

    …
}

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

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

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

最佳答案

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

关于Qt - QTreeView 和带有复选框列的自定义模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14158191/

相关文章:

Qt - 如何在顶部而不是底部显示 tabified dockwidget 的选项卡

javascript - 如何在选中其他复选框时取消选中复选框?

r - checkboxGroupInput 在 R shiny 中用于 ggplot

python-3.x - QTreeView 不跨越父级宽度或高度

c++ - 如何防止特定的 QTreeView 分支被拖动?

c++ - 我可以将 QObject 的两个子类移动到同一个 QThread 吗?

c++ - Qt QVBoxLayout : How to divide the layout in fixed height Boxes?

javascript - 取消选中所有(自动生成的)复选框

Python PyQt5 - 是否可以添加一个按钮在 QTreeView 内按下?

c++ - 将 unsigned short/int 转换为 char *