2

PySide2 中的 QtCore.QObject.connect 不像 PyQt4 中那样工作。信号订购接缝是问题所在。它是已知的错误还是 PySide2 不支持的功能?任何帮助将不胜感激,谢谢你,埃里克

工作示例:(抱歉,我无法缩短说明问题的时间)

通常 PySide2 下的输出抱怨信号和槽没有被排序。

QMetaObject 'BaseEditor' 中的信号和槽没有正确排序,这可能会导致问题。

  1. 信号 initFirstTimeDONE(object)

  2. 插槽 aclick(object)

  3. 信号 optionChangeDONE(object)


import os
import sys
import types
from collections import namedtuple

try:
    from PySide2 import QtCore,QtWidgets,QtGui
    SINGLE_ARG = 'object'
except:
    from PyQt4 import QtCore,QtGui 
    from PyQt4 import QtGui as QtWidgets
    SINGLE_ARG = 'PyQt_PyObject'

######################################################################  
class baseSig(object):
    """ helper mixing for signal name and signature """
    @property
    def asTuple(self):
        return self.name,self.arg

class signalInfoT(namedtuple("signalInfo", 
                         "name arg signature"),baseSig):
    __slots__ = ()

def signalInfo(name, arg, signature=None):
    if signature == None:
        return signalInfoT(name,arg,"%s(%s)" % (name,arg))
    else:
        return signalInfoT(name,arg,signature)


# declare 2 signalInfo
OPTION = signalInfo('optionChange',SINGLE_ARG)
INITF = signalInfo('initFirstTime',SINGLE_ARG)


######################################################################
class Msg(object):
    """ Signal argument type """
    def __init__(self,a):
        self.a = a


######################################################################
class BaseEditor(QtCore.QObject):
    """ object that centralized all the signal declaration (as a hub)
        and in which widget can register connection (request_connect)
    """
    def __init__(self,**args):
        super(BaseEditor,self).__init__()
        self._Assign = {}
        self.declare_signalT(INITF.asTuple, self.initFirst, SINGLE_ARG)
        self.declare_signalT(OPTION.asTuple, self.aclick, SINGLE_ARG)

    def declare_signalT(self,sig,functMethod,cbSignature=""):
        self.declare_signal(sig[0],sig[1],functMethod,cbSignature)

    def declare_signal(self,sName,sSignature,functMethod,cbSignature=""):

        self._Assign[sName] = {
                "signal":QtCore.SIGNAL("%s(%s)" % (sName,sSignature)),
                "methodR": functMethod,
                "signalDone": QtCore.SIGNAL("%sDONE(%s)" % (sName,
                                                        cbSignature))
                }

    def request_connect(self,emitter,sName,canEmit,callerCB = None):
        """Main method to register signal"""

        if canEmit:
            x = self.connect(emitter,self._Assign[sName]["signal"],self._Assign[sName]["methodR"])
        if callerCB != None:
            x = emitter.connect(self,self._Assign[sName]["signalDone"],callerCB)

    def initFirst(self, msg):
        self.emit(self._Assign[INITF.name]["signalDone"],msg)
    def aclick(self,msg):
        print "BaseEditor: this is not called", msg
        self.emit(self._Assign[OPTION.name]["signalDone"],msg)

######################################################################
class AWidget(QtWidgets.QWidget):
    def __init__(self,parent,**argv):
        super(AWidget,self).__init__(parent)
        self.setObjectName("ll%s" % id(self))
        verticalLayout = QtWidgets.QHBoxLayout(self)
        self.pushButton = QtWidgets.QPushButton("Hey")
        self.lineEdit = QtWidgets.QLineEdit()
        verticalLayout.addWidget(self.pushButton)
        verticalLayout.addWidget(self.lineEdit)
        self.pushButton.clicked.connect(self.on_click)
        editor = argv.get('editor')
        editor.request_connect(self, INITF.name, False, self.init_first)
        editor.request_connect(self, OPTION.name, True,self.ahaha)

    def init_first(self,msg):
        self.lineEdit.setText("%s" % msg.a)

    def on_click(self):
        msg = Msg(3)
        self.emit(QtCore.SIGNAL(OPTION.signature),msg)

    def ahaha(self,msg):
        print "ahaha: this is never called with Qt5", msg
        self.lineEdit.setText("%s" % msg.a)

#####################################################################
class ShotInfoMain(QtWidgets.QWidget):
    def __init__(self, parent,**argv):
        super(ShotInfoMain, self).__init__(parent)
        verticalLayout = QtWidgets.QVBoxLayout(self)
        self.setObjectName("shot%s" % id(self))
        w1 = AWidget(None,**argv)
        verticalLayout.addWidget(w1)
        editor = argv.get('editor')
        editor.request_connect(self,INITF.name,False,self.initFirstTime)

    def initFirstTime(self, msg):
        print  "ShotInfoMain:",msg

################################################################
class BrowserApp(QtWidgets.QMainWindow):

    def __init__(self, parent, **argv):

        super(BrowserApp, self).__init__(parent)
        editor = argv.get('editor')
        self.setObjectName("Browsert%s" % id(self))
        ll = ShotInfoMain(None,**argv)
        self.setCentralWidget(ll)
        editor.request_connect(self, INITF.name, True)
        msg = Msg(id(self))
        self.emit(QtCore.SIGNAL(INITF.signature), msg)

if __name__ == "__main__":
    # create a hub to where signal are send first
    ed = BaseEditor()
    # app
    app = QtWidgets.QApplication(sys.argv)
    # the mainwindow
    window = BrowserApp(None,editor=ed)

    # start
    QtWidgets.QApplication.processEvents()
    window.show()
    window.raise_()
    sys.exit(app.exec_())
4

0 回答 0