2013-01-04 52 views
2

我想要一個樹形視圖,其中顯示項目名稱,項目描述以及相應列中的兩個相關布爾值。我通過修改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做同樣的事情。與此同時,我不禁想知道是否有其他東西我在這裏失蹤。我聽說一種解決方案是有一個自定義的代表;這是唯一的選擇嗎?

如果有任何人誰可以指出,還有什麼我需要做的,或者提供一個類似的例子,我將不勝感激。

回答

1

我認爲問題出在Data方法中。您應該返回QVariant()當角色是CheckStateRole但該列不是布爾值時。

0

我有這個問題。它發生在TreeModel的::父()方法由於使child.column()值的createIndex ()方法。它應該是0。所以,與其

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

應該

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