重写 Qt MouseEvent 但前提是 class 变量为 True
Override a Qt MouseEvent but only if class variable is True
我有 QComboBox
,我希望用户能够锁定其索引。为此,我 subclassed QComboBox
并将 mousePressEvent
覆盖为空,但在 QComboBox
.
的方法中
我尝试的两个问题:
- 我不知道如何在另一个 class 方法中重新定义
mousePressEvent
- 如果不满足特定条件,我不知道如何恢复
QComboBox
的原始 mousePressEvent
行为。我的代码:
class MyComboBox(QtWidgets.QComboBox):
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
def lockSelection(self, bool=None):
if bool:
def mousePressEvent(self, *args, **kwargs):
pass
else:
def mousePressEvent(self, *args, **kwargs):
return QtWidgets.QComboBox.mousePressEvent(*args, **kwargs)
..... later
## I want this to get my overriden mousePressEvent
MyComboBox.lockSelection(True)
## I want this to get the original mousePressEvent
MyComboBox.lockSelection(False)
如果您想阻止继承的方法,您只需重写该方法并避免在必要时调用该方法:
from PyQt5 import QtWidgets
class MyComboBox(QtWidgets.QComboBox):
def lockSelection(self, lock):
self._lock_selection = lock
def mousePressEvent(self, event):
lock = getattr(self, "_lock_selection", False)
if not lock:
super(MyComboBox, self).mousePressEvent(event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = QtWidgets.QWidget()
combo = MyComboBox()
combo.addItems(list("ABCD"))
radio = QtWidgets.QCheckBox("Lock")
radio.toggled.connect(combo.lockSelection)
lay = QtWidgets.QHBoxLayout(w)
lay.addWidget(radio)
lay.addWidget(combo)
w.resize(320, 60)
w.show()
sys.exit(app.exec_())
如果您想避免继承,您可以使用事件过滤器实现储物柜,这样您就可以在任何小部件中使用它:
from PyQt5 import QtCore, QtWidgets
class MouseLocker(QtCore.QObject):
def __init__(self, widget):
super(MouseLocker, self).__init__(widget)
widget.installEventFilter(self)
self._lock_selection = False
def lockSelection(self, lock):
self._lock_selection = lock
def eventFilter(self, obj, event):
if obj is self.parent() and event.type() == QtCore.QEvent.MouseButtonPress:
return self._lock_selection
return super(MouseLocker, self).eventFilter(obj, event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = QtWidgets.QWidget()
combo = QtWidgets.QComboBox()
combo.addItems(list("ABCD"))
locker = MouseLocker(combo)
radio = QtWidgets.QCheckBox("Lock")
radio.toggled.connect(locker.lockSelection)
lay = QtWidgets.QHBoxLayout(w)
lay.addWidget(radio)
lay.addWidget(combo)
w.resize(320, 60)
w.show()
sys.exit(app.exec_())
我有 QComboBox
,我希望用户能够锁定其索引。为此,我 subclassed QComboBox
并将 mousePressEvent
覆盖为空,但在 QComboBox
.
我尝试的两个问题:
- 我不知道如何在另一个 class 方法中重新定义
mousePressEvent
- 如果不满足特定条件,我不知道如何恢复
QComboBox
的原始mousePressEvent
行为。我的代码:
class MyComboBox(QtWidgets.QComboBox):
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
def lockSelection(self, bool=None):
if bool:
def mousePressEvent(self, *args, **kwargs):
pass
else:
def mousePressEvent(self, *args, **kwargs):
return QtWidgets.QComboBox.mousePressEvent(*args, **kwargs)
..... later
## I want this to get my overriden mousePressEvent
MyComboBox.lockSelection(True)
## I want this to get the original mousePressEvent
MyComboBox.lockSelection(False)
如果您想阻止继承的方法,您只需重写该方法并避免在必要时调用该方法:
from PyQt5 import QtWidgets
class MyComboBox(QtWidgets.QComboBox):
def lockSelection(self, lock):
self._lock_selection = lock
def mousePressEvent(self, event):
lock = getattr(self, "_lock_selection", False)
if not lock:
super(MyComboBox, self).mousePressEvent(event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = QtWidgets.QWidget()
combo = MyComboBox()
combo.addItems(list("ABCD"))
radio = QtWidgets.QCheckBox("Lock")
radio.toggled.connect(combo.lockSelection)
lay = QtWidgets.QHBoxLayout(w)
lay.addWidget(radio)
lay.addWidget(combo)
w.resize(320, 60)
w.show()
sys.exit(app.exec_())
如果您想避免继承,您可以使用事件过滤器实现储物柜,这样您就可以在任何小部件中使用它:
from PyQt5 import QtCore, QtWidgets
class MouseLocker(QtCore.QObject):
def __init__(self, widget):
super(MouseLocker, self).__init__(widget)
widget.installEventFilter(self)
self._lock_selection = False
def lockSelection(self, lock):
self._lock_selection = lock
def eventFilter(self, obj, event):
if obj is self.parent() and event.type() == QtCore.QEvent.MouseButtonPress:
return self._lock_selection
return super(MouseLocker, self).eventFilter(obj, event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = QtWidgets.QWidget()
combo = QtWidgets.QComboBox()
combo.addItems(list("ABCD"))
locker = MouseLocker(combo)
radio = QtWidgets.QCheckBox("Lock")
radio.toggled.connect(locker.lockSelection)
lay = QtWidgets.QHBoxLayout(w)
lay.addWidget(radio)
lay.addWidget(combo)
w.resize(320, 60)
w.show()
sys.exit(app.exec_())