使用functools partial结合QPushButton调用外部方法时遇错误求助
PyQt5结合functools partial调用外部方法的错误解决
第一个错误:AttributeError: 'bool' object has no attribute 'number'
问题代码
file1.py:
#!/usr/bin/env python3 import sys from functools import partial from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton import file2 class window(QMainWindow): def __init__(self): super().__init__() self.setGeometry(300, 300, 300, 220) button = QPushButton(self) button.setText('Open') button.clicked.connect(partial(file2.open.get, self)) self.number = 10 self.show() app = QApplication(sys.argv) ex = window() sys.exit(app.exec_())
file2.py:
class open: def __init__(self): super().__init__() def get(self, parent): print(parent.number)
报错信息
Traceback (most recent call last): File "/home/john/github/pyqt5/QFileDialog/file2.py", line 9, in get print(parent.number) ^^^^^^^^^^^^^ AttributeError: 'bool' object has no attribute 'number' Aborted
原因与解决
- 原因:
file2.open.get是类的未绑定方法,调用时第一个参数需要是open类的实例;而QPushButton.clicked信号会默认传递一个布尔值(表示按钮是否被按下)。使用partial(file2.open.get, self)时,self被当作get方法的第一个参数(即open实例),信号传递的布尔值则变成了parent参数,导致parent为布尔类型,没有number属性。 - 解决:先实例化
file2.open类,再绑定实例的get方法:
# file1.py中修改绑定部分 openclass = file2.open() button.clicked.connect(partial(openclass.get, self))
第二个错误:TypeError: open.init() takes 1 positional argument but 2 were given
问题代码
修改后的file2.py:
from PyQt5.QtWidgets import QFileDialog class open: def __init__(self): super().__init__() def get(self, parent): print(parent.number) fileName = QFileDialog.getOpenFileName(parent, "Select a File") print(fileName[0]) with open(fileName[0]) as f: line = f.readline() print(line)
报错信息
Traceback (most recent call last): File "/home/john/github/pyqt5/QFileDialog/file2.py", line 15, in get with open(fileName[0]) as f: ^^^^^^^^^^^^^^^^^ TypeError: open.__init__() takes 1 positional argument but 2 were given Aborted
原因与解决
- 原因:自定义类名
open覆盖了Python内置的open函数,导致with open(fileName[0])实际调用的是自己定义的open类,而该类的__init__仅接受1个参数(self),但这里传入了文件名作为第二个参数,引发错误。 - 解决:
- 重命名自定义类,避免与内置函数冲突,比如改为
FileOpener:
- 重命名自定义类,避免与内置函数冲突,比如改为
# file2.py修改类名 class FileOpener: def __init__(self): super().__init__() def get(self, parent): print(parent.number) fileName = QFileDialog.getOpenFileName(parent, "Select a File") print(fileName[0]) with open(fileName[0]) as f: line = f.readline() print(line)
- 同时修改file1.py中的实例化代码:
openclass = file2.FileOpener() button.clicked.connect(partial(openclass.get, self))
内容的提问来源于stack exchange,提问作者jthornton
相关产品推荐
相关产品推荐

