Kivy应用报错TypeError:期望路径对象而非Button的问题求助
问题解决:Kivy应用下载按钮报错TypeError
错误根源
- 你的
callback函数里的path参数根本不是文件路径——Kivy按钮绑定on_press时,默认会把按钮自身作为参数传给回调函数,和filebrowser返回的路径完全不沾边。 filebrowser函数只是返回了路径,但没把路径存在App的实例变量里,下载时自然拿不到用户选的位置。
修复步骤
- 在App类的
build方法里新增一个实例变量,用来存用户选择的保存路径:self.save_path = None - 修改
filebrowser函数,把选择的路径赋值给这个变量(注意plyer的save_file返回的是列表,取第一个元素) - 调整
callback函数,使用实例变量里的路径,同时加个判断防止用户没选路径就点下载
修改后的完整代码
import kivy from kivy.app import App from kivy.uix.gridlayout import GridLayout from kivy.uix.label import Label from kivy.uix.image import Image from kivy.uix.button import Button from kivy.uix.textinput import TextInput from plyer import filechooser from pytube import YouTube import os class SayHello(App): def build(self): self.save_path = None # 新增:存储保存路径的实例变量 self.window = GridLayout() self.window.cols = 1 self.window.size_hint = (0.6, 0.7) self.window.pos_hint = {"center_x":0.5, "center_y":0.5} self.window.add_widget(Image(source="logo.png")) # 视频链接输入区域 self.videolink = Label(text="What is the link of your Youtube video?", font_size=18) self.window.add_widget(self.videolink) self.user = TextInput(multiline=False, padding_y=(20,20), size_hint=(1, 0.5)) self.window.add_widget(self.user) # 保存位置选择区域 self.loc = Label(text="what is the location where you want this file saved?", font_size=18) self.window.add_widget(self.loc) self.buttonone = Button(text="Choose where to save", size_hint=(1, 0.5), bold=True) self.buttonone.bind(on_press=self.filebrowser) self.window.add_widget(self.buttonone) # 下载按钮 self.button = Button(text=" Download Video", size_hint=(1, 0.5), bold=True, background_color='#32FFD1') self.button.bind(on_press=self.callback) self.window.add_widget(self.button) return self.window def filebrowser(self, instance): # plyer.save_file返回的是列表,取第一个元素作为路径 paths = filechooser.save_file(title="Choose where to Save", filters=[("*.mp4")]) if paths: # 防止用户取消选择 self.save_path = paths[0] def callback(self, instance): # 先检查路径和链接是否有效 if not self.save_path: self.videolink.text = "请先选择保存位置!" return if not self.user.text.strip(): self.videolink.text = "请输入视频链接!" return self.videolink.text = "Video Downloading Please Wait... " try: t = YouTube(self.user.text) highresvid = t.streams.get_highest_resolution() # 提取目录路径(因为save_file返回的是带文件名的路径,pytube的output_path需要目录) output_dir = os.path.dirname(self.save_path) # 使用用户选择的文件名保存 highresvid.download(output_path=output_dir, filename=os.path.basename(self.save_path)) self.videolink.text = "视频下载完成!" except Exception as e: self.videolink.text = f"下载失败:{str(e)}" SayHello().run()
额外说明
- 新增了错误处理:用户没选路径/没输链接时会提示,下载出错也会显示错误信息
- 处理了
plyer.save_file返回带文件名的路径问题——pytube的output_path需要目录路径,所以用os.path.dirname提取目录,os.path.basename提取文件名作为下载后的文件名
内容的提问来源于stack exchange,提问作者Jason Donegan
相关产品推荐
相关产品推荐

