QTableWidget 中如何 select 多行?

How to select multiple rows in QTableWidget?

我有一个 table 启用了 ExtendedSelection:

table.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)

当我关闭 UI 时,我使用 QSettings 来记住任何 selected 行。当我重新打开 UI 时,我希望它自动重新 select 行。

我有这个,但这最终只 select 最后 selected 行:

QSETTINGS = [1, 2, 3]  # Indicates row 1, 2 and 3 should be selected

for row in xrange(table.rowCount()):
    table_item = table.item(row, 1)
    row_data = table_item.data(QtCore.Qt.UserRole)
    row_id = row_data
    if row_id in QSETTINGS:
        table.selectRow(row)  # This ends up only making one row selected

我应该使用什么来代替 table.selectRow(row) 以确保 select 不止一行?


编辑

在我原来的问题中,我说我正在使用 QtGui.QAbstractItemView.MultiSelection。然而,我不是。我正在使用 QtGui.QAbstractItemView.ExtendedSelection,这也是为什么我的行 selection 代码显然不起作用的原因。通过临时切换到 MultiSelection、select 行然后切换回 ExtendedSelection,我问题中的代码效果很好。

您需要在每个 QTableWidgetItem

上使用 setSelected
for row in xrange(table.rowCount()):
    table_item = table.item(row, 1)
    row_data = table_item.data(QtCore.Qt.UserRole)
    row_id = row_data
    if row_id in QSETTINGS:
        for col in table.columnCount():
            item = table.item(row, col)
            if item:
                item.setSelected(True)

在此示例中,table.selectRow(i) 正在处理多选:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class MyTableWidget(QtWidgets.QTableWidget):
    def __init__(self, parent = None):
        QtWidgets.QTableWidget.__init__(self, parent)
        self.setRowCount(5)
        self.setColumnCount(3)
        self.items = [['a1','b1', 'c1'], ['a2','b2','c2'], ['a3','b3','c3'], ['a4','b4','c4'], ['a5','b5','c5']]
        self.hh = ['a', 'b','c']
        self.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
        selected = [1,2,4]
        self.setSel(selected)

        for r in range(0,len(self.items)):
            for c in range(0,len(self.items[0])):
                item = QtWidgets.QTableWidgetItem()
                item.setText(self.items[r][c])
                item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsSelectable)
                self.setItem(r,c,item)

    def setSel(self, selection):
        for i in selection:
            self.selectRow(i)

app = QtWidgets.QApplication(sys.argv) 
widget = MyTableWidget()
widget.show()
sys.exit(app.exec_())

如果我在设置选择

后调用 setSelectionMode,我就会得到你描述的行为

通过临时设置MultiSelection选择模式,每一行都被选中。

QSETTINGS = [1, 2, 3]  # Indicates row 1, 2 and 3 should be selected

# Temporarily set MultiSelection
table.setSelectionMode(QtGui.QAbstractItemView.MultiSelection)

for row in xrange(table.rowCount()):
    table_item = table.item(row, 1)
    row_data = table_item.data(QtCore.Qt.UserRole)
    row_id = row_data
    if row_id in QSETTINGS:
        table.selectRow(row)  # This ends up only making one row selected

# Revert MultiSelection to ExtendedSelection
table.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)

PyQt 是普通 Qt 库之上的一种包装器。问题的答案可以通过以下步骤实现。

第 1 步: 打开 QTableWidget

的文档

第 2 步: 滚动文档后了解到 table 被组织为项目的矩形

Step-3: 了解可以通过rowCount and columnCount

获取行数和列数

第 4 步: 了解可以使用 QTableWidget::item

从特定行和列获取项目

第 4 步: 打开 QTableWidgetItem

的文档

Step-5:发现有方法QTableWidgetItem::setSelected

最后,您可以创建如下代码:

for r in range(tblMy.rowCount()):
    for c in range(tblMy.columnCount()):
        item = tblMy.item(r, c)
        isSelected = ...
        item.setSelected(isSelected)

p.s。所以即使 PyQt 被记录为糟糕或不理想,通常 Qt 有丰富的文档。