如何在 QTableWidget 中选择多行?

Posted

技术标签:

【中文标题】如何在 QTableWidget 中选择多行?【英文标题】:How to select multiple rows in QTableWidget? 【发布时间】:2016-06-17 14:45:28 【问题描述】:

我有一张启用了 ExtendedSelection 的表格:

table.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)

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

我有这个,但这最终只选择了最后一个选定的行:

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) 以确保选择不止一行?


编辑

在我最初的问题中,我说我使用的是QtGui.QAbstractItemView.MultiSelection。然而,我不是。我正在使用QtGui.QAbstractItemView.ExtendedSelection,这也是我的行选择代码显然不起作用的原因。通过暂时切换到MultiSelection,选择行然后切换回ExtendedSelection,我的问题中的代码效果很好。

【问题讨论】:

【参考方案1】:

通过临时设置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)

【讨论】:

附带说明,如果您选择所有行,这似乎是一种进行反转选择的简单方法。感谢您的回答!【参考方案2】:

您需要在每个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)

【讨论】:

【参考方案3】:

在此示例中,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,我会得到你描述的行为

【讨论】:

抱歉,我使用的是ExtendedSelection,而不是MultiSelection。我现在明白为什么我的代码只选择了一行。这是因为我基本上没有使用 MultiSelection。所以临时设置应该可以解决我的问题。【参考方案4】:

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

第一步:打开QTableWidget的文档

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

第三步:了解可以通过rowCount和columnCount获取行数和列数

第四步:了解可以使用QTableWidget::item从特定行和列获取项目

第四步:打开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)

附言因此,即使 PyQt 被记录为差或不理想,通常 Qt 也有丰富的文档。

【讨论】:

以上是关于如何在 QTableWidget 中选择多行?的主要内容,如果未能解决你的问题,请参考以下文章

QT如何设置QTableWidget控件占满下方?

如何在qt中的QTableWidget中保存和加载数据

如何告诉 QTableWidget 结束编辑单元格?

QT如何获取QTableWidget表格中的高亮位置的行数?

Qt:在委托绘制事件中渲染时如何增加 QTablewidget?

如何防止用户使用 Python 和 Qt 在 QtableWidget 中移动列的大小?