PySide2 中的 QtCore.QObject.connect 不像 PyQt4 中那样工作。信号订购接缝是问题所在。它是已知的错误还是 PySide2 不支持的功能?任何帮助将不胜感激,谢谢你,埃里克
工作示例:(抱歉,我无法缩短说明问题的时间)
通常 PySide2 下的输出抱怨信号和槽没有被排序。
QMetaObject 'BaseEditor' 中的信号和槽没有正确排序,这可能会导致问题。
信号 initFirstTimeDONE(object)
插槽 aclick(object)
信号 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_())