fredrik
fredrik

Reputation: 10281

How to select multiple rows in QTableWidget?

I have a table where I've enabled ExtendedSelection:

table.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)

When I close the UI I use QSettings to remember any selected rows. When I re-open my UI I want it to automatically re-select the rows automatically.

I have this, but this ends up only selecting the last selected row:

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

What should I use instead of table.selectRow(row) in order to make sure to select more than just one row?


Edit

In my original question, I said I was using QtGui.QAbstractItemView.MultiSelection. However, I'm not. I'm using QtGui.QAbstractItemView.ExtendedSelection, which is also why my row selection code obviously doesn't work. By temporarily switching to MultiSelection, selecting the rows and then switch back to ExtendedSelection, the code in my question works great.

Upvotes: 4

Views: 17649

Answers (4)

Konstantin Burlachenko
Konstantin Burlachenko

Reputation: 5665

PyQt is kind of wrapper on top of usual Qt library. The answer for the question is possible to achieve with the following steps.

Step-1: Open documentation for QTableWidget

Step-2: After scrolling documentation understand that table is organized as rectangles of items

Step-3: Understand that it is possible to obtain a number of rows and columns via rowCount and columnCount

Step-4: Understand that to obtain the item from a specific row and column is possible with QTableWidget::item

Step-4: Open documentation for QTableWidgetItem

Step-5: Find that there is a method QTableWidgetItem::setSelected

Finally, you can create code like:

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

p.s. So even PyQt is documented as poor or not ideal, usual Qt has rich documentation.

Upvotes: 1

fredrik
fredrik

Reputation: 10281

By temporarily setting MultiSelection selection mode, each row is selected.

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)

Upvotes: 9

a_manthey_67
a_manthey_67

Reputation: 4286

in this example table.selectRow(i) is working on multiselection:

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_())

i get the behaviour you described, if i call setSelectionMode after setting selection

Upvotes: 0

Brendan Abel
Brendan Abel

Reputation: 37489

You need to use setSelected on each QTableWidgetItem

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)

Upvotes: 1

Related Questions