【问题标题】:QTreeView CheckboxesQTreeView 复选框
【发布时间】:2011-12-31 18:52:10
【问题描述】:

我知道这已经被问过很多次了,但我似乎找不到任何相关的东西。

使用Qt自带的the simpletreemodel tutorial,如何添加复选框?

【问题讨论】:

    标签: c++ python qt checkbox pyqt


    【解决方案1】:

    首先,您需要修改 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 方法。

    【讨论】:

    • 非常酷!正是我想要的。但是我发现我应该一直使用 TreeWidget 来构建我正在尝试构建的东西。非常感谢你的帖子。
    • 并不是说我可以提出更好的解决方案 atm,但布尔值当然缺乏令人敬畏的三态。 (例如,部分选定的文件夹)
    【解决方案2】:

    出于自己的目的,我将上述内容转换为 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)
    

    【讨论】:

    【解决方案3】:

    这是另一个使用 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++ 应用程序。

    【讨论】:

      【解决方案4】:

      我只是想通过添加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);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多