我有一个使用Python 3.5.1和PyQt5的程序,其中包含一个由QtCreator ui文件创建的GUI。在这个程序中,pyqtSlot装饰器导致了"TypeError: connect() failed between textChanged(QString) and edited()"的错误。
为了重现问题,我在示例代码中定义了两个自定义类:MainApp和LineEditHandler。MainApp实例化了主GUI(从文件"mainwindow.ui"中读取),而LineEditHandler处理一个QLineEdit对象。LineEditHandler的存在是为了将与QLineEdit对象相关的自定义方法集中到一个类中。它的构造函数需要一个QLineEdit对象和MainApp实例(以便在需要时访问其他对象/属性)。
在MainApp中,我将QLineEdit的textChanged信号连接到LineEditHandler的edited()方法。如果我不使用pyqtSlot()装饰LineEditHandler的edited()方法,一切都正常工作。但是,如果我使用@pyqtSlot()装饰该方法,代码运行将失败,并显示"TypeError: connect() failed between textChanged(QString) and edited()"。我在这里做错了什么?
您可以在此处获取mainwindow.ui文件:https://drive.google.com/file/d/0B70NMOBg3HZtUktqYVduVEJBN2M/view 这是生成问题的示例代码:
为了重现问题,我在示例代码中定义了两个自定义类:MainApp和LineEditHandler。MainApp实例化了主GUI(从文件"mainwindow.ui"中读取),而LineEditHandler处理一个QLineEdit对象。LineEditHandler的存在是为了将与QLineEdit对象相关的自定义方法集中到一个类中。它的构造函数需要一个QLineEdit对象和MainApp实例(以便在需要时访问其他对象/属性)。
在MainApp中,我将QLineEdit的textChanged信号连接到LineEditHandler的edited()方法。如果我不使用pyqtSlot()装饰LineEditHandler的edited()方法,一切都正常工作。但是,如果我使用@pyqtSlot()装饰该方法,代码运行将失败,并显示"TypeError: connect() failed between textChanged(QString) and edited()"。我在这里做错了什么?
您可以在此处获取mainwindow.ui文件:https://drive.google.com/file/d/0B70NMOBg3HZtUktqYVduVEJBN2M/view 这是生成问题的示例代码:
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSlot
Ui_MainWindow, QtBaseClass = uic.loadUiType("mainwindow.ui")
class MainApp(QMainWindow, Ui_MainWindow):
def __init__(self):
# noinspection PyArgumentList
QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
# Instantiate the QLineEdit handler.
self._line_edit_handler = LineEditHandler(self, self.lineEdit)
# Let the QLineEdit handler deal with the QLineEdit textChanged signal.
self.lineEdit.textChanged.connect(self._line_edit_handler.edited)
class LineEditHandler:
def __init__(self, main_window, line_edit_obj):
self._line_edit = line_edit_obj
self._main_window = main_window
# FIXME The pyqtSlot decorator causes "TypeError: connect() failed between
# FIXME textChanged(QString) and edited()"
@pyqtSlot(name="edited")
def edited(self):
# Copy the entry box text to the label box below.
self._main_window.label.setText(self._line_edit.text())
def main():
app = QApplication(sys.argv)
window = MainApp()
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()