2015-07-04 23 views
2

我是PySide的新手,我试图发出信号并从另一个类接收信号。自定义信号在PySide中不起作用

我已经在MySignal类的对象上使用了发射,并且从MyRadioButton类发出了信号。发射和连接都返回True,但正如我想要的,更新方法不被称为

这是文件和代码的基本结构。

# MySignals.py 
from PySide.QtCore import QObject, Signal 

class MyCheckedSignal(QObject): 
    signal = Signal(str) 


# MyRadioButton.py 
class MyRadioButton(QWidget, QObject): 
    def __init__(self, value=None, label=None): 
     QWidget.__init__(self) 
     self.__value = value 
     self.__checked = False 
     self.checkSignal = MySignals.MyCheckedSignal() 

    def toggleCheck(self): 
     if self.__checked == False: 
       self.__checked = True 
       self.checkSignal.emit(SIGNAL(self.__value)) 
     else: 
       self.__checked = False 


# MyRadioGroup.py 
class MyRadioGroup(QObject): 
    def __init__(self, radioes=None): 
     QObject.__init__(self) 
     for radio in radioes: 
      # radio is of type MyRadio 
      # self.connect(radio, SIGNAL("checked()"), self.update) 
      radio.checkSignal.signal.connect(self.update) 
      # self.connect(self.update) 

    def update(self, value): 
     print("Checked", value) 
+0

这是真正的代码?它看起来很奇怪。为了发射信号,“self .__ value”必须是“signal(QString)”。另外,信号**必须**只发送一个字符串参数,否则会引发一个'TypeError'。所以如果你说'connect'和'emit'都返回'True',那么你发布的代码并不能准确地代表你的真实代码。 – ekhumoro

回答

1

前言:你选择的基类的似乎很奇怪:你MyRadioButton或许应该从QRadioButton继承和你MyRadioGroup将受益于QGroupBox,这是一个正确的窗口小部件继承,因此将与的其余部分很好地集成应用。查看里面的描述,了解具体布局的例子。

对于您的具体问题,并且不使用现有的QRadioButton,您不需要为信号创建特殊的类。简单地声明你的MyRadioButton如下:

class MyRadioButton(QPushButton): 
    checkSignal = QtCore.Signal(str) 

    def __init__(self, value=None, label=None): 
     QPushButton.__init__(self) 
     self.__value = value 
     self.__checked = False 
     self.setCheckable(True) # This will 'hold' the button once clicked 
     self.clicked.connect(self.toggleCheck) # Signal emitted on click 

    def toggleCheck(self): 
     if self.__checked == False: 
       self.__checked = True 
       self.checkSignal.emit(self.__value) 
     else: 
       self.__checked = False 

注意,要激活你的toggleCheck方法,你必须将信号从QAbstractButton连接:clicked,该方法。你RadioGroup中就变成了简单的(从QWidget的继承是一个好主意,如果你想以某种方式来显示它):

class MyRadioGroup(QWidget): 
    def __init__(self, radioes=None): 
     QWidget.__init__(self) 
     self.radioes = radioes # good idea to store a reference to it 
     for radio in radioes: 
      radio.checkSignal.connect(self.update) 

    def update(self, value): 
     print("Checked", value) 

我将粘贴整个文件下面为你测试。在我的设置(Python 2.7.8,PySide 1.2.2),这工作正常。

顺便说一句:我很困惑你的线 self.checkSignal.emit(SIGNAL(self.__value))。这是什么SIGNAL?也许我错过了你的问题。


完整的示例文件:

import sys 
from PySide import QtGui 
from PySide import QtCore 

class MyRadioButton(QtGui.QPushButton): 
    checkSignal = QtCore.Signal(str) 

    def __init__(self, text, value=None, label=None): 
     QtGui.QPushButton.__init__(self, text) 
     self.__value = value 
     self.__checked = False 
     self.setCheckable(True) 
     self.clicked.connect(self.toggleCheck) 

    def toggleCheck(self): 
     if self.__checked == False: 
       self.__checked = True 
       self.checkSignal.emit(self.__value) 
     else: 
       self.__checked = False 


class MyRadioGroup(QtGui.QWidget): 
    def __init__(self, radios=None): 
     QtGui.QWidget.__init__(self) 
     self.radios = radios 
     for radio in self.radios: 
      radio.checkSignal.connect(self.update) 

    def update(self, value): 
     print("Checked", value) 

app = QtGui.QApplication(sys.argv) 

radio1 = MyRadioButton('Hello toto', value='toto') 
radio2 = MyRadioButton('Hello titi', value='titi') 
group = MyRadioGroup(radios=[radio1, radio2]) 

vbox = QtGui.QVBoxLayout() 
vbox.addWidget(radio1) 
vbox.addWidget(radio2) 
vbox.addStretch(1) 
group.setLayout(vbox) 
group.resize(250, 150) 
group.setWindowTitle('Signals') 
group.show() 

sys.exit(app.exec_())