2015-07-04 66 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_())