如何在 Python 中使用 QSignalBlocker?
How to use QSignalBlocker in Python?
我正在寻找特定于 Python 的文档,或者——更好的是——显示如何使用 QSignalBlocker 的 Python 代码示例片段。将不胜感激。
QSignalBlocker class 有一个简单的行为:当它被设置为 QObject 时,来自 QObject 的信号发射被阻止,使用 unblock()
方法移除阻止,使用 reblock()
又被封了
在下面的示例中,如果单选按钮未被选中,则每次从 QComboBox 中选择一个项目时,它将通过信号将所选文本传输到 QLabel,如果单选按钮被选中,则信号将不会发射,因此QLabel 不会显示 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_())
可以使用 QObject 的 blockSignals() 方法完成相同的逻辑:
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)
以上方法有效,但我目前使用的替代机制也有效:
self.blockSignals(True)
self.field.clear()
self.blockSignals(False)
查看 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 并将 __enter__
函数视为 C++ 构造函数,将 __exit__
函数视为 C++ 析构函数。
要利用这些功能,您可以使用 with
-statement 并通过此调用有效地阻止信号:
with QSignalBlocker(self.double_spin_box) as blocker:
self.double_spin_box.setValue(2.5)
此 with 语句会将此调用转换为
blocker = QSignalBlocker(self.double_spin_box)
blocker.__enter__()
try:
self.double_spin_box.setValue(2.5)
finally:
blocker.__exit__()
我正在寻找特定于 Python 的文档,或者——更好的是——显示如何使用 QSignalBlocker 的 Python 代码示例片段。将不胜感激。
QSignalBlocker class 有一个简单的行为:当它被设置为 QObject 时,来自 QObject 的信号发射被阻止,使用 unblock()
方法移除阻止,使用 reblock()
又被封了
在下面的示例中,如果单选按钮未被选中,则每次从 QComboBox 中选择一个项目时,它将通过信号将所选文本传输到 QLabel,如果单选按钮被选中,则信号将不会发射,因此QLabel 不会显示 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_())
可以使用 QObject 的 blockSignals() 方法完成相同的逻辑:
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)
以上方法有效,但我目前使用的替代机制也有效:
self.blockSignals(True)
self.field.clear()
self.blockSignals(False)
查看 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 并将 __enter__
函数视为 C++ 构造函数,将 __exit__
函数视为 C++ 析构函数。
要利用这些功能,您可以使用 with
-statement 并通过此调用有效地阻止信号:
with QSignalBlocker(self.double_spin_box) as blocker:
self.double_spin_box.setValue(2.5)
此 with 语句会将此调用转换为
blocker = QSignalBlocker(self.double_spin_box)
blocker.__enter__()
try:
self.double_spin_box.setValue(2.5)
finally:
blocker.__exit__()