I'm working on a python application that uses a QTableView to display some information. When the user double-clicks a row of the table, I want to extract the model data for that row and do something with it. The problem is, the data method for QAbstractTableModel returns the display string, not the data that was used to create it. So if I have a cell with an integer, I want to extract the actual integer but the data() method returns a string. In this simple case I could simply convert the string back to an int, but if I do something more complicated that may not be an option.
My solution so far has been to store a copy of the data list used to populate the model and look up the data in that using the index from the double click signal. It works, but I feel like there should be a cleaner way of doing this. Am I just overthinking this? Is there a better way of extracting data from a QT model?
For reference my model class looks like this:
from PyQt5 import QtCore
from PyQt5.QtCore import Qt
from ResourceCard import ResourceCard
class ResourceCardModel( QtCore.QAbstractTableModel):
'''
classdocs
'''
_headers = ["Level", "Color", "Points", "Cost"]
def __init__(self, cards: list[ ResourceCard]):
'''
Constructor
'''
super(ResourceCardModel, self).__init__()
self._data = cards
def data(self, index, role):
if role == Qt.DisplayRole or role == Qt.EditRole:
# Look up the key by header index.
column = index.column()
row = index.row()
item:ResourceCard = self._data[row]
match column:
case 0:
return str(item.level)
case 1:
return str(item.suit.name)
case 2:
return str(item.points)
case 3:
return str(item.cost)
case _:
return ""
def rowCount(self, index):
# The length of the outer list.
return len(self._data)
def columnCount(self, index):
# The length of our headers.
return len(self._headers)
def headerData(self, section, orientation, role):
# section is the index of the column/row.
if role == Qt.DisplayRole:
if orientation == Qt.Horizontal:
return str(self._headers[section])
if orientation == Qt.Vertical:
return ""
In my main class I have some code like:
def __init__(self, *args, obj=None, **kwargs):
'''
Constructor
'''
QtWidgets.QMainWindow.__init__(self)
Ui_Widget.__init__(self)
self.setupUi(self)
self.players = []
self.gameActions = GameActions(["p1", "p2", "p3", "p4"])
self.players = self.gameActions.getPlayersList()
self.cards:dict[int,list] = self.gameActions.game.availableResources
self.lvOneModel = ResourceCardModel( self.cards.get(1))
self.lvOneCardsTable.setModel(self.lvOneModel)
self.lvOneCardsTable.doubleClicked.connect(self.availableCardDoubleClicked)
def availableCardDoubleClicked(self, item:QModelIndex):
msgDialog = QtWidgets.QMessageBox(self)
itemData = self.cards.get(1)[item.row()]
msgDialog.setText(str(itemData))
msgDialog.show()