如何修复AttributeError: 'Button1'对象无'fn'属性问题
解决Kivy按钮点击打开PDF时的AttributeError问题
错误原因分析
你遇到的AttributeError: 'Button1' object has no attribute 'fn'是因为两个核心问题:
- 在KV语言的按钮事件里,
on_press:root.russ_yaz(self.fn)中的self指向的是按钮实例,而非你的SubjectsScreen10屏幕对象,按钮本身并没有fn属性,自然会报错。 - 你定义的
russ_yaz方法没有接收参数,但调用时却传递了参数,这也会导致参数不匹配的问题。
修正方案
我们只需要调整KV代码和Python方法逻辑,让按钮点击时能正确触发PDF打开操作:
- 修改KV按钮事件:无需传递
self.fn,直接调用root.russ_yaz()即可,文件名可以在方法内部定义。 - 完善
russ_yaz方法:在方法内完成PDF文件的加载逻辑,确保正确初始化PDF查看组件并展示内容。
修正后的完整代码示例
from kivy.app import App from kivy.lang import Builder from kivy.uix.screenmanager import ScreenManager, Screen from kivy.uix.boxlayout import BoxLayout from sys import argv from kivy.base import runTouchApp # 导入你已有的PDF相关依赖模块 from tempfile import mkdtemp, mkstemp from shutil import rmtree from binascii import b2a_hex from os import write, close from threading import Thread from pdfminer.pdfpage import PDFPage from pdfminer.pdfparser import PDFParser from pdfminer.converter import PDFPageAggregator from pdfminer.pdfdocument import PDFDocument, PDFNoOutlines from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.layout import ( LAParams, LTTextBox, LTTextLine, LTFigure, LTImage, LTChar, LTCurve, LTLine, LTRect, ) from kivy.clock import Clock import kivy.graphics from kivy.graphics import Mesh, Color from kivy.graphics.tesselator import Tesselator from kivy.uix.widget import Widget from kivy.uix.recycleview import RecycleView from kivy.uix.label import Label from kivy.uix.image import Image from kivy.uix.relativelayout import RelativeLayout from kivy.properties import ( StringProperty, ListProperty, NumericProperty, AliasProperty, DictProperty, ObjectProperty, BooleanProperty, ColorProperty, ) # 确保你的PDFDocumentWidget能正确接收source参数并渲染PDF class PDFDocumentWidget(BoxLayout): source = StringProperty('') def __init__(self, source='', cols=1, **kwargs): super().__init__(**kwargs) self.source = source # 这里添加你的PDF渲染逻辑(比如解析PDF内容并展示) # KV语言定义界面 Builder.load_string(''' <SubjectsScreen10>: Button: text:"Русский язык" on_press: root.russ_yaz() ''') class SubjectsScreen10(Screen): def russ_yaz(self): # 指定PDF文件路径,Android平台注意权限和路径正确性 pdf_path = 'Дудников, А.В Русский язык.pdf' # 创建PDF查看组件并替换当前屏幕内容 pdf_widget = PDFDocumentWidget(source=pdf_path, cols=1) self.clear_widgets() self.add_widget(pdf_widget) class BookLibraryApp(App): def build(self): sm = ScreenManager() sm.add_widget(SubjectsScreen10(name='subjects')) return sm if __name__ == '__main__': if len(argv) > 1: # 支持通过命令行参数传入PDF路径 fn = argv[1] root = PDFDocumentWidget(source=fn, cols=1) runTouchApp(root) else: BookLibraryApp().run()
额外注意事项
- 如果PDF文件不在应用默认工作目录,需要提供完整的绝对路径,比如Android外部存储路径
'/storage/emulated/0/books/Дудников, А.В Русский язык.pdf'。 - Android平台需要在
AndroidManifest.xml中添加读取外部存储的权限,否则无法访问PDF文件。 - 确保你的
PDFDocumentWidget类能正确解析和渲染PDF内容,若之前的PDF解析逻辑有问题,也需要同步排查。
内容的提问来源于stack exchange,提问作者Roman_Sarnov
相关产品推荐
相关产品推荐

