I am using Python and the PySide2 Qt bindings.
My program is intended to load records from a csv file, display them as rows in a table, and when asked, upload each to a remote database. Each upload takes a few seconds, so I figured I'd change the background color of each row as it's uploading, then change it again to either red or green based of success or failure.
I have a TableModel
class that extends QAbstractTableModel
. The program doesn't need to edit the values, just load them from csv, so it doesn't implement setData()
, just data()
. I have it passed through an extended QSortFilterProxyModel
into a QTableView
for sorting purposes.
class TableModel(QAbstractTableModel):
records = [] #Where the list of records is kept
def data(self, index, role=Qt.DisplayRole):
record = self.records[index.row()]
if role == Qt.DisplayRole:
#bunch of table data stuff
elif role == Qt.BackgroundColorRole:
#This gets called all the time
#but is never called during the uploading process
if record.uploading: return QColor.cyan
def upload(self):
for recordRow in range(len(self.records)):
record = self.records[recordRow]
start = self.createIndex(recordRow, 0)
end = self.createIndex(recordRow, 4)
record.uploading = True
#I've tried both explicitly specifying the desired role
#as well as omitting the argument
self.dataChanged.emit(start, end, [Qt.BackgroundColorRole])
record.upload() #Currently just waits for 1 second
record.uploading = False
self.dataChanged.emit(start, end, [Qt.BackgroundColorRole])
As you can see, I set an uploading flag, emit the dataChanged
signal, upload (actually just waits for 1 second at the moment), turn the flag back off, and emit dataChanged
again. I expect to see the cyan highlight stay on each row for one second, moving down the list, but instead nothing happens.
When I monitor the data()
method, it never gets called with the BackgroundColorRole
during the upload iterations.
I connected a test method to the dataChanged
signal as well, and it does get emitted with the correct indices.
Do I need to do something else to connect dataChanged
properly? Does the QSortFilterProxyModel
between my model and view cause issues?
You should not have tasks that delay more than 30 ms in the main thread since it blocks the GUI avoiding that the event loop is executed and consequently the signals do not notify causing the updates of the GUI not to occur. So you should run it on a thread or better use QtNetwork because it is friendly with the Qt event loop.