将旧的SIGNAL和SLOT转换为新样式的正确方法



我目前正在尝试将一个旧的python程序从python 2转换为python 3,并从PyQt4更新为PyQt5。该应用程序使用PyQt5不支持的旧式信号和插槽。我已经想好了大部分需要做的事情,但下面是一些我似乎无法工作的行:

self.emit(SIGNAL('currentChanged'), row, col)
self.emit(SIGNAL("activated(const QString &)"), self.currentText())
self.connect(self,SIGNAL("currentChanged(const QString&)"), self.currentChanged)

前两行,我不知道从哪里开始,因为它们似乎与任何东西都没有关联。最后一个例子我不太确定该怎么处理(const QString &)。

我不完全确定如何处理这些问题,我仍在学习python,但任何帮助都将不胜感激。

编辑:文档似乎并没有真正深入了解这些案例,至少在我理解的方面是这样。

这个问题的确切答案将取决于self是什么类型的对象。如果它是一个已经定义了这些信号的Qt类,那么新的语法将是:

self.currentChanged[int, int].emit(row, col)
self.activated[str].emit(self.currentText())
self.currentChanged[str].connect(self.handleCurrentChanged)

然而,如果这些中的任何一个不是预定义的,则需要为它们定义自定义信号,如下所示:

class MyClass(QWidget):
# this defines two overloads for currentChanged
currentChanged = QtCore.pyqtSignal([int, int], [str])
activated = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(MyClass, self).__init__(parent)
self.currentChanged[str].connect(self.handleCurrentChanged)   
def handleCurrentChanged(self, text):
print(text)

旧式语法允许动态地发出自定义信号(即不首先定义它们),但这已经不可能了。对于新型语法,必须始终明确定义自定义信号。

请注意,如果一个信号只定义了一个过载,则可以省略选择器:

self.activated.emit(self.currentText())

有关更多信息,请参阅PyQt文档中的以下文章:

  • 支持信号和插槽(PyQt5)
  • 旧式信号和插槽支持(PyQt4)
  • 新型信号和插槽支持(PyQt4)

编辑

对于您的实际代码,您需要对currentChanged信号进行以下更改:

  1. InMultibar.py(第30行附近):

    这定义了一个自定义信号(因为QWidget没有它):

    class MultiTabBar(QWidget):
    # add the following line
    currentChanged = pyqtSignal(int, int)
    
  2. Multibar.py中(第133行附近):

    这会发出(1)中定义的自定义信号:

    # self.emit(SIGNAL('currentChanged'), row, col)
    self.currentChanged.emit(row, col)
    
  3. ScWindow.py中(第478行附近):

    这连接了(1)中定义的信号:

    # self.connect(self.PieceTab,SIGNAL("currentChanged"),self.pieceTabChanged)
    self.PieceTab.currentChanged.connect(self.pieceTabChanged)
    
  4. ItemList.py中(第73行附近):

    QFileDialog类已经定义了这个信号,并且只有一个重载。但是插槽的名称必须更改,因为它隐藏了内置的信号名称(这已成为新型语法中的一个属性)。所以连接应该是这样的:

    # self.connect(self,SIGNAL("currentChanged(const QString&)"),self.currentChanged)
    self.currentChanged.connect(self.onCurrentChanged)
    
  5. ItemList.py中(第78行附近):

    这将重命名(4)中连接的插槽:

    # def currentChanged(self, file):
    def onCurrentChanged(self, file):
    

最新更新