I am new to PyQt and having to really dig to understand how the objects fit together. I am probably overlooking some basic things at this point. I have started building my application, but keep tripping into things that don’t work the way I want. Please be understanding if I am missing basic concepts. Doing this as retirement project, no longer being paid to code.
The problem is that I want to add a row to a tableView and have it selected. This code is extracted from a more complex environment.
What am I doing wrong?
import sys
from PyQt5 import QtCore as qtc
from PyQt5 import QtWidgets as qtw
"""
Model: based on QAbstractTableModel
View: QTable view
data: simple table of integers (3 columns)
Implemented insert and remove row methods.
I want an inserted table row to be selected
Problem: selectRow after insert of table row works only
if I have just deleted the next to last entry in the table
"""
# Model +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class TableModel(qtc.QAbstractTableModel):
def __init__(self, data):
super(TableModel, self).__init__()
self._data = data
def data(self, index, role):
if role == qtc.Qt.DisplayRole:
value = self._data[index.row()][index.column()]
return str(value)
def setData(self, index, value, role):
if role == qtc.Qt.EditRole:
self._data[index.row()][index.column()] = value
return True
def rowCount(self, index):
rows = len(self._data)
return rows
def columnCount(self, index):
cols = len(self._data[0])
return cols
def flags(self, index):
flags = qtc.Qt.ItemIsSelectable|qtc.Qt.ItemIsEnabled|qtc.Qt.ItemIsEditable
return flags
def removeRow(self, row):
self.rowsAboutToBeRemoved.emit(qtc.QModelIndex(), row, row)
self._data.pop(row)
self.rowsRemoved.emit(qtc.QModelIndex(), row, row)
def insertRow(self, data)->int:
row = len(self._data) + 1
self.rowsAboutToBeInserted.emit(qtc.QModelIndex(), row, row)
self._data.append(data)
self.rowsInserted.emit(qtc.QModelIndex(), row, row)
return row
# end class TableModel
class MainWindow(qtw.QMainWindow):
def __init__(self):
super().__init__()
self.setMinimumSize(qtc.QSize(350, 200))
self.cIndex = None # current selection
self.pIndex = None # previous selection
self.rowData = 10 # for generated adds
self.sm = None # selection model
# view +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
self.table = qtw.QTableView()
self.table.setSelectionMode(qtw.QAbstractItemView.SingleSelection)
self.table.setSelectionBehavior(qtw.QAbstractItemView.SelectRows)
# model +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
data = [ [1, 9, 2] ] # start with 1 row
self.model = TableModel(data)
self.table.setModel(self.model)
sm = self.table.selectionModel()
sm.currentRowChanged.connect(self.currentRowChanged)
self.sm = sm
# buttons ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
buttons = qtw.QHBoxLayout()
self.pbAdd = qtw.QPushButton('Add')
self.pbDelete = qtw.QPushButton('Delete')
self.pbAdd.clicked.connect(self.pbAddClicked)
self.pbDelete.clicked.connect(self.pbDeleteClicked)
# layout ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vBox = qtw.QVBoxLayout()
vBox.addWidget(self.table)
buttons.addWidget(self.pbAdd)
buttons.addWidget(self.pbDelete)
vBox.addLayout(buttons)
# complete main window
self.widget = qtw.QWidget()
self.widget.setLayout(vBox)
self.setCentralWidget(self.widget)
self.show()
def currentRowChanged(self, cIndex, pIndex):
self.cIndex = cIndex
self.pIndex = pIndex
# add row
def pbAddClicked(self):
col = self.rowData
data = [col, col+1, col+2]
self.rowData += 10
row = self.model.insertRow(data)
# select the inserted row
# *** this only works when the next to last entry has been deleted ???
self.table.selectRow(row)
# remove row
def pbDeleteClicked(self):
row = self.cIndex.row()
self.model.removeRow(row)
# end class MainWindow
app=qtw.QApplication([])
window=MainWindow()
app.exec_()