Reputation: 3341
In my app I have a QTableView with rows that get selected programmatically, e.g. after a query on the data is performed.
How can I prevent the user to change the selected rows on click, while keeping the ability to select rows programmatically?
This is my code:
self.table = QTableView()
pandas_model: QAbstractTableModel = PandasTableModel(self.data_frame, self)
self.table.setModel(pandas_model)
self.table.setSortingEnabled(False)
self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # full width table
self.table.setSelectionMode(QAbstractItemView.MultiSelection)
self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
Should I override its ItemSelectionModel in order to prevent the default behaviour on user click while keeping the programmatic selection mode? How could I achieve this?
Upvotes: 1
Views: 519
Reputation: 244301
If you want to avoid that the user can select an item(s), row(s) or column(s) you should do the following:
Overwrite delegate editorEvent method so that it does not notify the view click.
Deactivate the ability to click on the sections of the headers
from PyQt5 import QtCore, QtGui, QtWidgets
class Delegate(QtWidgets.QStyledItemDelegate):
def editorEvent(self, event, model, option, index):
res = super(Delegate, self).editorEvent(event, model, option, index)
if event.type() in (
QtCore.QEvent.MouseButtonPress,
QtCore.QEvent.MouseButtonRelease,
QtCore.QEvent.MouseButtonDblClick,
QtCore.QEvent.MouseMove,
QtCore.QEvent.KeyPress
):
return True
return res
class TableView(QtWidgets.QTableView):
def __init__(self, parent=None):
super(TableView, self).__init__(parent)
self.setSortingEnabled(False)
self.horizontalHeader().setSectionResizeMode(
QtWidgets.QHeaderView.Stretch
)
self.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
delegate = Delegate(self)
self.setItemDelegate(delegate)
self.horizontalHeader().setSectionsClickable(False)
self.verticalHeader().setSectionsClickable(False)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
model = QtGui.QStandardItemModel()
for i in range(15):
for j in range(6):
it = QtGui.QStandardItem("{}-{}".format(i, j))
model.setItem(i, j, it)
table = TableView()
table.setModel(model)
# emulate select by query
import random
for row in random.sample(range(model.rowCount()), 5):
table.selectRow(row)
table.resize(640, 480)
table.show()
sys.exit(app.exec_())
Upvotes: 2