Kivy(Python)实现带图片按钮异常求助
Kivy(Python)实现带图片按钮异常求助
看起来你在尝试用Kivy做两个带自定义图片的可点击按钮,想要分别显示“b1”和“b2”的图片,但目前只看到空白按钮,图片完全没加载出来对吧?我帮你分析下问题,再给你调整方案~
先说说你代码里的核心问题
- 图片尺寸获取时机不对:你在
build方法里直接获取img01.texture_size,但这时候图片还没加载完成,texture_size大概率是(0,0),导致按钮和图片的尺寸都被设成了0,自然看不到内容。 - 重复代码冗余:两个按钮的创建逻辑完全一样,重复写两遍不仅麻烦,还容易出错。
- (隐性问题)
path1/path2未定义:你代码里直接用了这两个变量但没赋值,运行时会直接报错,这个应该是你写的时候省略了,不过也要注意替换成实际的图片路径~
解决方案1:修复你原有代码的逻辑
我把你的代码重构了一下,主要解决了图片尺寸加载时机的问题,还把重复代码抽成了通用函数,更易维护:
from kivy.app import App from kivy.uix.image import Image from kivy.uix.button import Button from kivy.uix.boxlayout import BoxLayout from kivy.clock import Clock class MyApp(App): def build(self): # 替换成你实际的图片路径! path1 = "b1.png" path2 = "b2.png" layout = BoxLayout(orientation='horizontal', spacing=10, padding=10) # 用通用函数创建带图按钮,避免重复代码 btn01 = self.create_image_button(path1, self.on_image_click01) btn02 = self.create_image_button(path2, self.on_image_click02) layout.add_widget(btn01) layout.add_widget(btn02) return layout def create_image_button(self, img_path, click_callback): # 创建透明背景的按钮 btn = Button(size_hint=(None, None), background_normal='', background_down='') # 创建图片控件 img = Image(source=img_path, allow_stretch=True, keep_ratio=False) # 用Clock延迟执行,等图片加载完成后再设置尺寸 def set_widget_sizes(dt): btn.size = img.texture_size img.size = btn.size Clock.schedule_once(set_widget_sizes, 0) btn.add_widget(img) btn.bind(on_press=click_callback) return btn def on_image_click01(self, instance): print("Click 1", instance.children[0].source) def on_image_click02(self, instance): print("Click 2", instance.children[0].source) if __name__ == '__main__': MyApp().run()
解决方案2:更简洁的实现方式(推荐)
其实Kivy的Button本身就支持直接把图片设为背景,完全不需要嵌套Image控件,代码会简洁很多:
from kivy.app import App from kivy.uix.button import Button from kivy.uix.boxlayout import BoxLayout class MyApp(App): def build(self): # 替换成你实际的图片路径! path1 = "b1.png" path2 = "b2.png" layout = BoxLayout(orientation='horizontal', spacing=10, padding=10) # 第一个带图按钮:直接用background_normal设图片 btn01 = Button(size_hint=(None, None), background_normal=path1, background_down=path1) btn01.bind(on_press=self.on_image_click01) # 绑定texture_size事件,图片加载完成后自动设置按钮尺寸 btn01.bind(texture_size=lambda inst, size: setattr(inst, 'size', size)) # 第二个带图按钮,逻辑和第一个一致 btn02 = Button(size_hint=(None, None), background_normal=path2, background_down=path2) btn02.bind(on_press=self.on_image_click02) btn02.bind(texture_size=lambda inst, size: setattr(inst, 'size', size)) layout.add_widget(btn01) layout.add_widget(btn02) return layout def on_image_click01(self, instance): print("Click 1", instance.background_normal) def on_image_click02(self, instance): print("Click 2", instance.background_normal) if __name__ == '__main__': MyApp().run()
这个方案里,background_down可以设置按钮被点击时显示的图片,如果不需要和正常状态不同,直接设成和background_normal一样就行,省了嵌套Image的麻烦~
备注:内容来源于stack exchange,提问作者nel_junior000
相关产品推荐
相关产品推荐

