如何设置QTableView

时间:2016-12-12 21:07:56

标签: qt checkbox pyside qtableview

我正在尝试应用以下帖子中概述的原则,但对于我的模型的CheckStateRole(在我的模型的data / setData方法中定义):

how can i achieve to update multiple rows in a qtableview

但是,我意识到检查/取消选中一列(在我的例子中是第0列),似乎根本没有调用commitData。

以下是代码段:

class MyTableView(QtGui.QTableView):
    """
    View that will set all selected rows to the current CheckedState.
    """
    def __init__(self, parent=None):
        super(MyTableView, self).__init__(parent)

    def commitData(self, editor):
        # this method is not called when a user checks/unchecks an item
        super(MyTableView, self).commitData(editor)
        model = self.currentIndex().model()
        current_row, current_column = self.currentIndex().row(), 0
        value = model.data(model.index(current_row, current_column), QtCore.Qt.CheckStateRole)
        for row in self.selectionModel().selectedRows(0):
            if row != current_row:
                index = model.index(row, current_column)
                model.setData(index, value, QtCore.Qt.CheckStateRole)

如何使用QAbstractTableModel为QTableView中的复选框实现此目的?

在内部,checkBox是如何处理的?它不被视为调用commitData的委托吗?

已解决---------------------------------

我最终通过从模型中的setData方法为CheckStateRole发出dataChanged来处理这个问题,然后将信号连接到将传递的索引检查状态应用于选择的方法。

出现了两个问题:

  • 这会导致无限循环(dataChanged调用一个方法 影响其他指数反过来会发出数据改变...)。该 解决方案是在设置选定的索引时检查blockSignals 方法中的状态。

  • 由于blockSignals,ui未刷新。我内心 假设dataChanged调用索引范围的视图刷新。 视图的简单更新修复了这个问题。

对于加载的数据模型,我不确定这是最好的方法。

2 个答案:

答案 0 :(得分:2)

以下是我解决它的方法(用C ++编写)

  • 将来自selectionChanged的{​​{1}}的{​​{1}}信号连接到数据模型的插槽中:
TableView
  • 每次选择更改时,请在模型中保留其副本。这可能如下所示:
SelectionModel
  • 在模型中的connect(selectionModel(), &QItemSelectionModel::selectionChanged, &model, &Model::onSelectionChanged); 函数中,在更新以响应void Model::onSelectionChanged(QItemSelection const& selected, QItemSelection const& deselected) { if (auto sm = qobject_cast<QItemSelectionModel*>(sender())) { mLastSelection = sm->selection(); } } 更改时,迭代整个选择以对所有选定的单元格应用相同的setData()更改。

接下来,要解决当用户点击复选框时TableView清除选择的问题:

  • 使用与CheckState相同的签名从模型中发出setSelection信号:

    Q_EMIT setSelection(mLastSelection,QItemSelectionModel :: Select);

  • 将此信号连接回选择模型,但最重要的是,使用CheckState执行此操作,以便它在下一个事件循环周期中到达。

  • 在C ++中,要在排队连接中连接这些类型,需要使用QItemSelectionModel::select进行注册。您可以在cpp文件顶部的匿名命名空间中整齐地执行此操作,如下所示:
QueuedConnection

答案 1 :(得分:0)

我最终通过从模型中的setData方法为CheckStateRole发出dataChanged来处理这个问题,然后将信号连接到将传递的索引检查状态应用于选择的方法。

出现了两个问题:

  • 这会导致无限循环(dataChanged调用影响其他索引的方法,而这些索引又会发出dataChanged ......)。解决方法是在方法中设置所选索引检查状态时阻止信号。
  • 由于blockSignals,ui未刷新。在内部我假设dataChanged调用索引范围的视图刷新。视图的简单更新修复了这个问题。 对于加载的数据模型,我不确定这是最好的方法。