Reputation: 546
I’m looking for either Python-specific documentation or--better yet--a sample snippet of Python code that shows how to use QSignalBlocker. Will be grateful for anything.
Upvotes: 4
Views: 3658
Reputation: 343
Looking at the documation you can see, that the QSignalBlocker provides a __enter__
and a __exit__
function. On __enter__
the signals of the given object are blocked and on __exit__
the blocked state is set to the previous state. You can see this, when you look at the original Qt-documentation for QSignalBlocker and see the __enter__
function as the C++-constructor and the __exit__
function as the C++-destructor.
To leverage these function you can use the with
-statement and block the signals effectively with this call:
with QSignalBlocker(self.double_spin_box) as blocker:
self.double_spin_box.setValue(2.5)
This with-statement will translate this call to
blocker = QSignalBlocker(self.double_spin_box)
blocker.__enter__()
try:
self.double_spin_box.setValue(2.5)
finally:
blocker.__exit__()
Upvotes: 7
Reputation: 546
The above works, but I'm currently using an alternative mechanism that also works:
self.blockSignals(True)
self.field.clear()
self.blockSignals(False)
Upvotes: 0
Reputation: 244202
The QSignalBlocker class has a simple behavior: When it is set to a QObject the emission of signals from the QObject is blocked, with the unblock()
method the block is removed, with reblock()
it is blocked again.
In the following example if the radiobutton is not checked then each time an item is selected from the QComboBox it will transmit the selected text to the QLabel through signals, if the radiobutton is checked then the signals will not be emitted so the QLabel will not show the text selected by the QComboBox:
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
radiobutton = QtWidgets.QRadioButton("block/unblock")
self.m_label = QtWidgets.QLabel()
self.m_combobox = QtWidgets.QComboBox()
self.m_combobox.addItems(
[
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
]
)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(radiobutton)
lay.addWidget(self.m_label)
lay.addWidget(self.m_combobox)
self.m_blocker = QtCore.QSignalBlocker(self.m_combobox)
self.m_blocker.unblock()
self.m_combobox.currentTextChanged.connect(self.m_label.setText)
radiobutton.toggled.connect(self.on_toggled)
@QtCore.pyqtSlot(bool)
def on_toggled(self, state):
if state:
self.m_blocker.reblock()
else:
self.m_blocker.unblock()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
The same logic can be done with the blockSignals() method of the QObject's:
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
radiobutton = QtWidgets.QRadioButton("block/unblock")
self.m_label = QtWidgets.QLabel()
self.m_combobox = QtWidgets.QComboBox()
self.m_combobox.addItems(
[
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
]
)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(radiobutton)
lay.addWidget(self.m_label)
lay.addWidget(self.m_combobox)
radiobutton.toggled.connect(self.m_combobox.blockSignals)
self.m_combobox.currentTextChanged.connect(self.m_label.setText)
Upvotes: 1