Kivy 2.3.0使用FigureCanvasKivyAgg报错:无'resize_event'属性
解决Kivy 2.3.0中FigureCanvasKivyAgg的AttributeError问题
在Kivy 2.3.0应用中使用FigureCanvasKivyAgg(plt.gcf())绘制基础图表时,持续触发错误:
AttributeError: 'FigureCanvasKivyAgg' object has no attribute 'resize_event'
相关代码及报错信息如下:
matty.py
import kivy from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.floatlayout import FloatLayout from kivy.uix.screenmanager import ScreenManager, Screen from kivy.uix.label import Label from kivy.lang import Builder from kivy.metrics import dp, sp from kivy.clock import Clock #Graphical Imports from kivymd.app import MDApp from kivy.garden.matplotlib.backend_kivyagg import FigureCanvasKivyAgg import matplotlib.pyplot as plt x = [ 1, 2, 3, 4, 5] y = [5, 14, 7, 20, 11] plt.plot(x,y) plt.ylabel("y axis") plt.xlabel("x axis") class WelcomeScreen(Screen): pass class FirstScreen(Screen): pass class SecondScreen(Screen): pass class ScreenManager(ScreenManager): pass class Graph(FloatLayout): def __init__(self, **kwargs): super().__init__(**kwargs) self.add_widget(FigureCanvasKivyAgg(plt.gcf())) def save(self): pass class Project(BoxLayout): pass kv = Builder.load_file("matty.kv") class TestApp(MDApp): title = "Kivy Project" def build(self, **kwargs): return Project() if __name__ == '__main__': TestApp().run()
matty.kv
#:kivy 2.3.0 <Project> orientation: "vertical" canvas.before: Color: rgb: .6, .6, .6 Rectangle: pos: self.pos size: self.size SomeMenu_ActionBar: id: ActionBar ScreenManager: id: sm WelcomeScreen: FirstScreen: SecondScreen: Graph: id: graph_screen <SomeMenu_ActionBar@ActionBar>: ActionView: id: ActionView HiddenIcon_ActionPrevious: ActionGroup: id: App_ActionGroup mode: "spinner" text: "Jump to Screen" ActionButton: text: "Welcome Screen" on_release: app.root.ids.sm.current = 'welcome' app.root.ids.sm.transition.direction = "right" ActionButton: text: "First Screen" on_release: app.root.ids.sm.current = 'first' app.root.ids.sm.transition.direction = "left" ActionButton: text: "Second Screen" on_release: app.root.ids.sm.current = 'second' app.root.ids.sm.transition.direction = "left" ActionGroup: id: App_ActionGroup mode: 'spinner' text: 'App' ActionButton: text: 'Settings' on_press: app.open_settings() ActionButton: text: 'Quit' on_press: app.get_running_app().stop() ActionGroup: id: File_ActionGroup mode: 'spinner' text: 'File' ActionButton: text: 'Open' ActionButton: text: 'Save' ActionButton: text: 'Back to Main Menu' on_release: app.root.ids.sm.current = 'welcome' app.root.ids.sm.transition.direction = "right" <HiddenIcon_ActionPrevious@ActionPrevious>: title: '' with_previous: False app_icon: '' app_icon_width: 0 app_icon_height: 0 size_hint_x: None width: len(self.title)*10 <WelcomeScreen>: name: 'welcome' Label: text: 'Welcome Screen' font_size: sp(50) <FirstScreen>: id: first name: 'first' Label: text: 'First Screen' <SecondScreen>: id: second name: 'second' Graph: id: graph_screen <Graph>: id: boxgraph BoxLayout: size_hint_y: .9 pos_hint: {"top": 1} BoxLayout: size_hint_y: .1 TextInput: id: name multiline: False Button: text: "Save" on_release: root.save()
报错信息
Traceback (most recent call last): File "c:\Users\alisu\OneDrive - UWE Bristol\UWE Bristol & Stuff\3rd Year UWE\Digital Systems\Alistana Fitness & Nutrition Tracker\AFNT-Digital-Systems-Project\AFNT\Application\Classes\matty.py", line 58, in <module> TestApp().run() File "C:\Users\alisu\OneDrive - UWE Bristol\UWE Bristol & Stuff\3rd Year UWE\Digital Systems\Alistana Fitness & Nutrition Tracker\AFNT-Digital-Systems-Project\AFNT\.venv\Lib\site-packages\kivy\app.py", line 956, in run runTouchApp() File "C:\Users\alisu\OneDrive - UWE Bristol\UWE Bristol & Stuff\3rd Year UWE\Digital Systems\Alistana Fitness & Nutrition Tracker\AFNT-Digital-Systems-Project\AFNT\.venv\Lib\site-packages\kivy\base.py", line 574, in runTouchApp EventLoop.mainloop() File "C:\Users\alisu\OneDrive - UWE Bristol\UWE Bristol & Stuff\3rd Year UWE\Digital Systems\Alistana Fitness & Nutrition Tracker\AFNT-Digital-Systems-Project\AFNT\.venv\Lib\site-packages\kivy\base.py", line 339, in mainloop self.idle() File "C:\Users\alisu\OneDrive - UWE Bristol\UWE Bristol & Stuff\3rd Year UWE\Digital Systems\Alistana Fitness & Nutrition Tracker\AFNT-Digital-Systems-Project\AFNT\.venv\Lib\site-packages\kivy\base.py", line 379, in idle Clock.tick() File "C:\Users\alisu\OneDrive - UWE Bristol\UWE Bristol & Stuff\3rd Year UWE\Digital Systems\Alistana Fitness & Nutrition Tracker\AFNT-Digital-Systems-Project\AFNT\.venv\Lib\site-packages\kivy\clock.py", line 733, in tick self.post_idle(ts, self.idle()) File "C:\Users\alisu\OneDrive - UWE Bristol\UWE Bristol & Stuff\3rd Year UWE\Digital Systems\Alistana Fitness & Nutrition Tracker\AFNT-Digital-Systems-Project\AFNT\.venv\Lib\site-packages\kivy\clock.py", line 776, in post_idle self._process_events() File "kivy\_clock.pyx", line 620, in kivy._clock.CyClockBase._process_events File "kivy\_clock.pyx", line 653, in kivy._clock.CyClockBase._process_events File "kivy\_clock.pyx", line 649, in kivy._clock.CyClockBase._process_events File "kivy\_clock.pyx", line 218, in kivy._clock.ClockEvent.tick File "C:\Users\alisu\OneDrive - UWE Bristol\UWE Bristol & Stuff\3rd Year UWE\Digital Systems\Alistana Fitness & Nutrition Tracker\AFNT-Digital-Systems-Project\AFNT\.venv\Lib\site-packages\kivy\uix\floatlayout.py", line 97, in do_layout c.size = c_w, c_h ^^^^^^ File "kivy\properties.pyx", line 520, in kivy.properties.Property.__set__ File "kivy\properties.pyx", line 1478, in kivy.properties.ReferenceListProperty.set File "kivy\properties.pyx", line 606, in kivy.properties.Property._dispatch File "kivy\_event.pyx", line 1307, in kivy._event.EventObservers.dispatch File "kivy\_event.pyx", line 1213, in kivy._event.EventObservers._dispatch File "C:\Users\alisu\OneDrive - UWE Bristol\UWE Bristol & Stuff\3rd Year UWE\Digital Systems\Alistana Fitness & Nutrition Tracker\AFNT-Digital-Systems-Project\AFNT\.venv\Lib\site-packages\kivy\garden\matplotlib\backend_kivy.py", line 1233, in _on_size_changed self.resize_event() ^^^^^^^^^^^^^^^^^ AttributeError: 'FigureCanvasKivyAgg' object has no attribute 'resize_event'
解决方案
原因分析
该错误是由于kivy-garden matplotlib库的版本与Kivy 2.3.0不兼容导致的:旧版本的后端代码中调用了resize_event()方法,但在适配Kivy 2.3.0的版本中,该方法已被移除或重命名,且FigureCanvasKivyAgg类不再包含此方法。
修复步骤
方法1:修改代码避免全局Matplotlib状态并适配布局
- 移除全局图表代码:把全局的
plt.plot等代码移到Graph类内部,创建独立的Figure和Axes,避免全局状态冲突。 - 将画布添加到KV定义的布局中:不要直接把画布加到FloatLayout,而是加到KV中预留的BoxLayout容器里。
修改后的matty.py中Graph类:
class Graph(FloatLayout): def __init__(self, **kwargs): super().__init__(**kwargs) # 创建独立的Figure和Axes,不依赖全局plt fig, ax = plt.subplots() x = [1, 2, 3, 4, 5] y = [5, 14, 7, 20, 11] ax.plot(x, y) ax.set_ylabel("y axis") ax.set_xlabel("x axis") # 创建画布并添加到KV中指定的容器 canvas = FigureCanvasKivyAgg(fig) self.ids.graph_box.add_widget(canvas) def save(self): pass
修改matty.kv中的<Graph>规则,给顶部BoxLayout添加id:
<Graph>: id: boxgraph BoxLayout: id: graph_box # 添加此id用于挂载画布 size_hint_y: .9 pos_hint: {"top": 1} BoxLayout: size_hint_y: .1 TextInput: id: name multiline: False Button: text: "Save" on_release: root.save()
方法2:修复Kivy Garden Matplotlib后端代码
找到你的虚拟环境中backend_kivy.py文件(路径类似venv/Lib/site-packages/kivy/garden/matplotlib/backend_kivy.py),定位到_on_size_changed方法(大约1233行),将self.resize_event()替换为self.draw():
def _on_size_changed(self, instance, value): # 原代码:self.resize_event() self.draw()
方法3:更新Kivy Garden Matplotlib到兼容版本
执行命令更新库:
pip install --upgrade kivy-garden garden install matplotlib --upgrade
内容的提问来源于stack exchange,提问作者alisuhail-amanu2
相关产品推荐
相关产品推荐

