[英]The signal and slot within custom class including PyQt QWidget not working
我在自定义包含QPushButton
和QLabel
的 class 时遇到了一些麻烦,我只想将QPushButton
设置为可检查并为其切换信号定义一个插槽,此外,自定义 class 固有QObject
。
代码如下所示,
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import pyqtSlot, QObject
class CustomButton(QPushButton):
def __init__(self, label='', parent=None):
super().__init__(label, parent)
self.setCheckable(True)
self.toggled.connect(self.update)
def update(self, state):
if state:
self.setStyleSheet('background-color: green')
else:
self.setStyleSheet('background-color: red')
class ButtonCtrl(QObject):
def __init__(self, parent=None, label=''):
super().__init__()
if isinstance(parent, QLayout):
col = QVBoxLayout()
parent.addLayout(col)
else:
col = QVBoxLayout(parent)
self.text = ['ON', 'OFF']
self.label = QLabel(label)
self.button = QPushButton('ON')
# self.button = CustomButton('ON')
col.addWidget(self.label)
col.addWidget(self.button)
self.button.setCheckable(True)
self.button.setChecked(True)
self.button.toggled.connect(self.update)
self.update(True)
self.label.setFont(QFont('Microsoft YaHei', 14))
self.button.setFont(QFont('Microsoft YaHei', 12, True))
self.button.toggle()
# @pyqtSlot(bool)
def update(self, state):
if state:
self.button.setText(self.text[0])
self.button.setStyleSheet('background-color: green')
else:
self.button.setText(self.text[-1])
self.button.setStyleSheet('background-color: red')
class Window(QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
# set the layout
layout = QVBoxLayout(self)
but = ButtonCtrl(layout, "Test")
#self.but = ButtonCtrl(layout, "Test")
btn = CustomButton()
layout.addWidget(btn)
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle('Fusion')
main = Window()
main.show()
sys.exit(app.exec_())
我已经自定义了两个按钮,分别命名为CustomButton(QPushButton)
和ButtonCtrl(QObject)
,并且我已经测试了主 window 中的插槽,但是后台更新插槽适用于CustomButton(QPushbutton)
而不适用于ButtonCtrl(QObject)
,槽 function 甚至没有被调用。
但是,如果我将ButtonCtrl(QObject)
的按钮成员从QPushButton
更改为我的CustomButton(QPushButton)
,它将在主 window 中正常工作。 此外,如果主 window 中的but
通过设置self.but=ButtonCtrl(layout, "Test")
成为主 window class 的成员,它也可以正常工作。
我在 Qt 文档中没有找到直接答案,该文档解释了这一点
当 state 的内部 state 以某种可能对对象的客户或所有者感兴趣的方式发生变化时,信号由 object 发出。 信号是公共访问函数,可以从任何地方发出,但我们建议仅从定义信号及其子类的 class 发出它们。
我不确定是否会导致这种影响的寿命but
希望得到答复,谢谢。
The problem is simple: The ButtonCtrl class object has a local scope so it will be destroyed, and why doesn't the same happen with the CustomButton class object? 好吧,因为 QWidget 的所有权有其父级,并且该按钮的父级是 window,而不是 ButtonCtrl object 没有它。 在这种情况下,解决方案是延长变量的生命周期,在 QObject 的情况下有几个选项:
使用第三种选择只是更改为:
class ButtonCtrl(QObject):
def __init__(self, parent=None, label=''):
super().__init__(parent)
# ...
第一个选项是您的代码中注释的选项:
self.but = ButtonCtrl(layout, "Test")
第二个类似:
self.container = list()
but = ButtonCtrl(layout, "Test")
self.container.append(but)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.