I have a python QTableWidget populated with 4 columns. Selecting any of the columns runs the qTableWidget.cellClicked() signal, which then highlights the entire row, and runs a bunch of code.
self._qTableWidget.cellClicked.connect(self.cellClicked)
def cellClicked(self, row, column):
"""
Handle cell clicked signal.
"""
self._qTableWidget.setDisabled(True)
qTableWidgetItem = self._qTableWidget.item(row, column)
if qTableWidgetItem is None:
return
else:
# ***RUNS SOME CODE***
pass
self._qTableWidget.setEnabled(True)
In the code, I want to disable the QTableWidget from accepting any clicks until after the code runs, then enable the QTableWidget (which I have tried by using setDisabled()/setEnabled()).
However if you click a cell, the table is disabled correctly, but you can still click on cells in the table. When the table is enabled again, it runs the cellClicked() signal again on the QTableWidgetItem you clicked on while the table was disabled.
I have tried using the following:
self._qTableWidget.blockSignals(True)
self._qTableWidget.blockSignals(False)
self._qTableWidget.cellClicked.disconnect(self.cellClicked)
self._qTableWidget.cellClicked.connect(self.cellClicked)
self.setAllCellItemFlags(QtCore.Qt.NoItemFlags)
def setAllCellItemFlags(self, flag):
"""
Sets all QTableWidgetItem flags
"""
for row in range(self._qTableWidget.rowCount()):
for column in range(self._qTableWidget.columnCount()):
qTableWidgetItem = self._qTableWidget.item(row, column)
qTableWidgetItem.setFlags(flag)
This is what probably happens in your code:
As you can see, the second click gets processed AFTER the signal gets re-enabled. This is the root cause of your problem. What you need to do is to re-enable the signals AFTER the event loop processes the waiting mouse click (or mouse clicks).
The easiest solution would be to call QApplication.processEvents(QEventLoop.AllEvents, 0)
just before you re-enable the signals. This will cause all click events to be processed, i.e. ignored because the signals will still be disabled at that moment. Please read the documentation about this overload of the method which processes also posted (not yet queued) events. In contrast to the other overload without ms
argument, which processes only already queued events. If value 0
is not sufficient, then experiment with a bit longer time delays, e.g. 100 ms.