将旧 SIGNAL 和 SLOT 转换为新样式的正确方法?
Correct way to convert old SIGNAL and SLOT to new style?
我目前正在尝试将旧的 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 class 已经定义了这些信号,那么新式语法将是这样的:
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 文档中的这些文章:
- Support for Signals and Slots (PyQt5)
- Old-style Signal and Slot Support (PyQt4)
- New-style Signal and Slot Support (PyQt4)
编辑:
对于您的实际代码,您需要对 currentChanged
信号进行以下更改:
在Multibar.py中(第30行左右):
这定义了一个自定义信号(因为 QWidget
没有):
class MultiTabBar(QWidget):
# add the following line
currentChanged = pyqtSignal(int, int)
在Multibar.py中(第133行左右):
这会发出 (1) 中定义的自定义信号:
# self.emit(SIGNAL('currentChanged'), row, col)
self.currentChanged.emit(row, col)
在ScWindow.py中(第478行左右):
这将连接 (1) 中定义的信号:
# self.connect(self.PieceTab,SIGNAL("currentChanged"),self.pieceTabChanged)
self.PieceTab.currentChanged.connect(self.pieceTabChanged)
在ItemList.py(第73行左右):
QFileDialog
classalready defines this signal,而且只有一个重载。但是插槽的名称必须更改,因为它隐藏了内置信号名称(已成为新式语法中的属性)。所以连接应该是这样的:
# self.connect(self,SIGNAL("currentChanged(const QString&)"),self.currentChanged)
self.currentChanged.connect(self.onCurrentChanged)
在ItemList.py(第78行左右):
这将重命名在 (4) 中建立的连接的插槽:
# def currentChanged(self, file):
def onCurrentChanged(self, file):
我目前正在尝试将旧的 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 class 已经定义了这些信号,那么新式语法将是这样的:
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 文档中的这些文章:
- Support for Signals and Slots (PyQt5)
- Old-style Signal and Slot Support (PyQt4)
- New-style Signal and Slot Support (PyQt4)
编辑:
对于您的实际代码,您需要对 currentChanged
信号进行以下更改:
在Multibar.py中(第30行左右):
这定义了一个自定义信号(因为
QWidget
没有):class MultiTabBar(QWidget): # add the following line currentChanged = pyqtSignal(int, int)
在Multibar.py中(第133行左右):
这会发出 (1) 中定义的自定义信号:
# self.emit(SIGNAL('currentChanged'), row, col) self.currentChanged.emit(row, col)
在ScWindow.py中(第478行左右):
这将连接 (1) 中定义的信号:
# self.connect(self.PieceTab,SIGNAL("currentChanged"),self.pieceTabChanged) self.PieceTab.currentChanged.connect(self.pieceTabChanged)
在ItemList.py(第73行左右):
QFileDialog
classalready defines this signal,而且只有一个重载。但是插槽的名称必须更改,因为它隐藏了内置信号名称(已成为新式语法中的属性)。所以连接应该是这样的:# self.connect(self,SIGNAL("currentChanged(const QString&)"),self.currentChanged) self.currentChanged.connect(self.onCurrentChanged)
在ItemList.py(第78行左右):
这将重命名在 (4) 中建立的连接的插槽:
# def currentChanged(self, file): def onCurrentChanged(self, file):