【发布时间】:2011-12-31 18:52:10
【问题描述】:
我知道这已经被问过很多次了,但我似乎找不到任何相关的东西。
使用Qt自带的the simpletreemodel tutorial,如何添加复选框?
【问题讨论】:
标签: c++ python qt checkbox pyqt
我知道这已经被问过很多次了,但我似乎找不到任何相关的东西。
使用Qt自带的the simpletreemodel tutorial,如何添加复选框?
【问题讨论】:
标签: c++ python qt checkbox pyqt
首先,您需要修改 TreeItem 以跟踪选中状态:
private:
...
bool checked;
还有一个 setter 和 getter:
bool isChecked() const { return checked; }
void setChecked( bool set ) { checked = set; }
现在需要修改模型,以便视图知道检查状态:
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
if ( role == Qt::CheckStateRole && index.column() == 0 )
return static_cast< int >( item->isChecked() ? Qt::Checked : Qt::Unchecked );
if (role != Qt::DisplayRole)
return QVariant();
return item->data(index.column());
}
并修改模型的 flags 方法,让视图知道模型包含可检查项:
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
if ( index.column() == 0 )
flags |= Qt::ItemIsUserCheckable;
return flags;
}
我认为应该这样做。如果您希望能够在用户勾选和取消选择项目时更新 TreeItem 检查状态,那么您需要在 TreeModel 中提供 QAbstractItemModel::setData 方法。
【讨论】:
出于自己的目的,我将上述内容转换为 PyQt,并认为我会分享。
def data(self, index, role):
if not index.isValid():
return None
item = index.internalPointer();
if role == Qt.CheckStateRole and index.column() == self.check_col:
return int( Qt.Checked if item.isChecked() else Qt.Unchecked )
return super(TreeModel, self).data(index, role)
def flags(self, index):
if not index.isValid():
return None
if index.column() == self.check_col:
flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsUserCheckable
else:
flags = super(TreeModel, self).flags(index)
return flags
def setData(self, index, value, role=Qt.EditRole):
if index.column() == self.check_col:
if role == Qt.EditRole:
return False
if role == Qt.CheckStateRole:
item = self.getItem(index)
item.setChecked(value)
self.dataChanged.emit(index, index)
return True
return super(TreeModel, self).setData(index, value, role)
【讨论】:
这是另一个使用 QStandardItemModel 的 PyQt 完整示例:
model = QStandardItemModel()
parent_item = model.invisibleRootItem() # type: QStandardItem
for row in [
(Qt.Unchecked, 'unchecked'),
(Qt.PartiallyChecked, 'partially'),
(Qt.Checked, 'checked')
]:
checked, text = row
check_item = QStandardItem('')
check_item.setCheckable(True)
check_item.setCheckState(checked)
parent_item.appendRow([check_item, QStandardItem(text)])
treeview.setModel(model)
顺便说一句,这也适用于任何 C++ 应用程序。
【讨论】:
我只是想通过添加setData 方法来完成@JediLlama 的回答,该方法是从@taynaron 的Python 版本翻译而来的:
bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role) {
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
if (index.column() == 0) {
if (role == Qt::EditRole) {
return false;
}
if (role == Qt::CheckStateRole) {
item->setCheck(value.toBool());
emit dataChanged(index, index);
return true;
}
}
return QAbstractItemModel::setData(index, value, role);
}
【讨论】: