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

问题描述:

我想要一个树形视图,其中显示项目名称,项目描述以及相应列中的两个相关布尔值。我通过修改Editable Tree Mode example开始,因此有一个TreeModel跟踪一组TreeItem,每个TreeItem不仅有一个TreeItem的子列表,而且还有一个QVariants列表,它存储一组值,稍后可以显示QTreeView中的列。Qt - 具有复选框列的QTreeView和自定义模型

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

Qt TreeView with Checkboxes

这里就是我从例如修改,主要是在TreeModel的部分。

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; 
} 

mainwindow.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做同样的事情。与此同时,我不禁想知道是否有其他东西我在这里失踪。我听说一种解决方案是有一个自定义的代表;这是唯一的选择吗?

如果有任何人谁可以指出,还有什么我需要做的,或者提供一个类似的例子,我将不胜感激。

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

我有这个问题。它发生在TreeModel的::父()方法由于使child.column()值的createIndex ()方法。它应该是0。所以,与其

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

应该

createIndex(parentItem->childNumber(), 0, parentItem);