如何解决Kivy中GridLayout绑定on_press事件的AttributeError: pressed错误
Fixing AttributeError: 'pressed' with Kivy GridLayout and on_press
Hey Ronald, let's break down what's going on here and fix that error!
The root issue is simple: GridLayout doesn't have an on_press event by default. That event is reserved for interactive widgets like Button, ToggleButton, or CheckBox— layouts like GridLayout are designed purely for arranging other widgets, not handling direct click interactions out of the box.
Let's cover the two most common scenarios you might be working with, and how to fix each:
Scenario 1: You want to bind on_press to buttons inside the GridLayout
This is the more typical use case. If you're trying to trigger a method when a button inside the GridLayout is pressed, you need to bind the on_press event to the Button widgets themselves, not the GridLayout. Here's how to adjust your code:
testApp.py
from kivy.app import App from kivy.uix.gridlayout import GridLayout class MyGrid(GridLayout): # This is the method we'll call when a button is pressed def pressed(self, button_instance): print(f"Button '{button_instance.text}' was clicked!") class TestApp(App): def build(self): return MyGrid() if __name__ == "__main__": TestApp().run()
testApp.kv
<MyGrid>: cols: 2 # Set your desired number of columns # Bind on_press of each Button to the root's pressed method Button: text: "First Button" on_press: root.pressed(self) Button: text: "Second Button" on_press: root.pressed(self)
Scenario 2: You want the GridLayout itself to respond to clicks
If you truly need the entire GridLayout to act like a clickable widget, you can add ButtonBehavior to your GridLayout class. This behavior injects all the click-related events (like on_press) into the layout, letting it handle presses while still working as a layout.
testApp.py
from kivy.app import App from kivy.uix.gridlayout import GridLayout from kivy.uix.behaviors import ButtonBehavior # Inherit from ButtonBehavior FIRST, then GridLayout (order matters!) class ClickableGrid(ButtonBehavior, GridLayout): def pressed(self): print("The entire GridLayout was clicked!") class TestApp(App): def build(self): return ClickableGrid() if __name__ == "__main__": TestApp().run()
testApp.kv
<ClickableGrid>: cols: 2 # Now we can bind on_press directly to the GridLayout on_press: root.pressed() # Add child widgets as normal Label: text: "Click anywhere here!" Label: text: "The grid will respond!"
Quick Checks to Avoid This Error Again
- Double-check that your method name in Python matches exactly what you call in kv (typos like
pressinstead ofpressedare a common culprit) - If targeting child widgets, never bind
on_pressto the GridLayout itself— always target the interactive child widgets - When using behaviors like
ButtonBehavior, remember to put the behavior first in the inheritance list (Kivy processes mixins in order)
内容的提问来源于stack exchange,提问作者Ronald Saunfe

