如何设置qtableview的某一行被选中

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何设置qtableview的某一行被选中相关的知识,希望对你有一定的参考价值。

你说的是不是gridView控件?设置其某行被选中,其实可以使用该控件自带的功能。具体做法是,打开编辑列功能,向列集合中添加一个字段,字段为CommandField下的”选择“字段。为了让其有显示效果,请将GridView控件中的选中行的背景色设为比较醒目的颜色,如Red。编译并运行,单击选择项之后,该行会被选中,在后台处理gridView控件中RowSelectChanging事件时,可以实现很多的效果。 参考技术A ui->tableview->selectRow(2); 参考技术B 你说的是不是gridView控件?设置其某行被选中,其实可以使用该控件自带的功能。具体做法是,打开编辑列功能,向列集合中添加一个字段,字段为CommandField下的”选择“字段。为了让其有显示效果,请将GridView控件中的选中行的背景色设为比较醒目的颜色,如Red。编译并运行,单击选择项之后,该行会被选中,在后台处理gridView控件中RowSelectChanging事件时,可以实现很多的效果。

如何设置选中/未选中 QTableView 的多个选定行

【中文标题】如何设置选中/未选中 QTableView 的多个选定行【英文标题】:How to set checked/unchecked multiple selected rows of a QTableView 【发布时间】:2016-12-12 21:07:56 【问题描述】:

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

how can i achieve to update multiple rows in a qtableview

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

这里是sn-p的代码:

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 调用的方法 影响了其他索引,而这些索引又会发出 dataChanged ...)。这 解决方案是在设置选定的索引检查时阻止信号 方法中的状态。

由于 blockSignals,ui 不会刷新。在内部我 假设 dataChanged 调用索引范围的视图刷新。 对视图的简单更新解决了这个问题。

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

【问题讨论】:

复选框不是编辑器,因此没有理由为它们调用commitData 【参考方案1】:

这是我解决它的方法(在 C++ 中)

将来自TableViewSelectionModelselectionChanged 信号连接到数据模型上的插槽:
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() 函数中,当更新以响应 CheckState 更改时,遍历整个选择以将相同的 CheckState 更改应用于所有选定的单元格。

接下来处理TableView在用户点击复选框时清除选择的问题:

从模型中发出一个与QItemSelectionModel::select具有相同签名的setSelection信号:

Q_EMIT setSelection(mLastSelection, QItemSelectionModel::Select);

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

在 C++ 中,要在队列连接中连接这些类型,需要使用 qRegisterMetaType 注册它们。您可以在 cpp 文件顶部的匿名命名空间中巧妙地执行此操作,如下所示:

    bool const _ = []
        qRegisterMetaType<QItemSelection>();
        qRegisterMetaType<QItemSelectionModel::SelectionFlags>();
        return true;
    ();

【讨论】:

dynamic_cast 需要一个模板参数,我猜qobject_cast 是一个更好的选择。那么您要将其投射到哪种类型? dataChanged() 不是虚拟方法,所以在我们的模型中使用这个方法很奇怪。 感谢您的编辑。删除所有模板参数的格式有些奇怪(在最后一节也是如此)。 'dataChanged' 是一个错误,应该是 'setData' - 现在已更正。【参考方案2】:

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

出现了两个问题:

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

【讨论】:

以上是关于如何设置qtableview的某一行被选中的主要内容,如果未能解决你的问题,请参考以下文章

如何取得gridview中选中行中的某一字段

如何用代码选中datagrid中的某一行

获取所有行值给定一个单元格被选中 QTableView

QTableWidget

QTableView高级选择

如何根据内容调整 QTableView 的高度?