Kivy按钮点击写入CSV异常:获部件位置布尔值而非目标数据
Hey there, let's break down what's going wrong with your code and fix it step by step. The core issue is that your data flow between the collision check, button press, and CSV operations is broken—plus there are a few syntax/logic mistakes that are causing those boolean values to show up instead of your intended data.
1. Fix the Data Flow Between Count() and DataBase
Right now, your Count() method calculates a collision count but doesn't store it anywhere accessible to the DataBase class. Let's add an instance variable to PutOnShelfScreen1 to track this count so we can pass it to DataBase later.
Update the PutOnShelfScreen1 class:
class PutOnShelfScreen1(Screen): def __init__(self, **kwargs): super().__init__(**kwargs) self.collision_count = 0 # Store collision count as an instance variable def Count(self, Transportation, Furniture, Tools, armchair): # No need to reassign parameters to self.ids—you already passed them! armchair = self.ids.my_image2.parent if armchair.collide_widget(Furniture): self.collision_count += 1 print(f"Collision detected! Current count: {self.collision_count}")
2. Fix the DataBase Class and CSV Operations
Your DataBase class has several critical issues:
data.append(i)returnsNone(it modifies the list in-place), so assigning it toself.databreaks your data reference.- You were writing to a Chinese-named CSV file but reading from
results.csv(mismatched filenames). - You never called the
Table()method to actually run the CSV write/read logic.
Here's the corrected DataBase class:
class DataBase(): def __init__(self, count_value, **kwargs): super().__init__(**kwargs) self.count_value = count_value self.database_file = 'results.csv' # Use a consistent filename def Table(self): global data data.append(str(self.count_value)) # Convert count to string for CSV compatibility # Write to CSV with open(self.database_file, 'w', newline='') as database: wr = csv.writer(database, delimiter=',', quoting=csv.QUOTE_MINIMAL) wr.writerow(['Column1', 'Column2', 'Result']) wr.writerow(data) # Read and print CSV content to verify print("\nCSV Verification:") with open(self.database_file, 'r') as database: reader = csv.reader(database) for row in reader: print(row)
3. Fix the Button on_press Binding
Your Next button was calling root.DataBase(database) which is invalid—database isn't defined, and you need to properly pass the collision count and trigger the CSV operations.
Update the button in your KV string:
Button: id: Next pos_hint: {'x': 0.8, 'y': 0.9} size_hint: .2, .1 background_color: [63/255, 191/255, 63/255, 0.3] # Kivy uses 0-1 range for colors! text: '>' on_press: root.save_to_csv()
Add this method to PutOnShelfScreen1 to handle the button press:
class PutOnShelfScreen1(Screen): # ... existing __init__ and Count() methods ... def save_to_csv(self): # Create DataBase instance with our collision count and run operations db = DataBase(self.collision_count) db.Table()
4. Bonus Fix: Kivy Color Values
Kivy expects color values in the 0-1 range (not 0-255). Your background_color properties like [63, 191, 63, 0.3] should be scaled to [63/255, 191/255, 63/255, 0.3] to display correctly.
Full Corrected Code
from kivy.app import App from kivy.lang import Builder from kivy.uix.screenmanager import ScreenManager, Screen from kivy.properties import ObjectProperty import csv Builder.load_string(''' <Sample@Image> size: self.size allow_stretch: False keep_ratio: False do_rotation: False <PutOnShelfScreen1> canvas: Rectangle: source: 'BackForGame113.png' size: self.size pos: self.pos BoxLayout: orientation: 'horizontal' spacing: 30 padding: [10, 150, 10, 10] Button: id: Tools background_color: [63/255, 191/255, 63/255, 0.3] text: '' Button: id: Transportation background_color: [63/255, 191/255, 63/255, 0.3] text: '' Button: id: Furniture background_color: [63/255, 191/255, 63/255, 0.3] text: '' FloatLayout: Button: id: Next pos_hint: {'x': 0.8, 'y': 0.9} size_hint: .2, .1 background_color: [63/255, 191/255, 63/255, 0.3] text: '>' on_press: root.save_to_csv() StencilView: id: armchair ScatterPlane: pos: 500, 500 size: my_image2.size Image: id: my_image2 source: 'path\\image.png' on_touch_up: root.Count(Furniture, Tools, Transportation, armchair) ''') data = ['Bla', '6'] class PutOnShelfScreen1(Screen): def __init__(self, **kwargs): super().__init__(**kwargs) self.collision_count = 0 def Count(self, Transportation, Furniture, Tools, armchair): armchair = self.ids.my_image2.parent if armchair.collide_widget(Furniture): self.collision_count += 1 print(f"Collision detected! Current count: {self.collision_count}") def save_to_csv(self): db = DataBase(self.collision_count) db.Table() class DataBase(): def __init__(self, count_value, **kwargs): super().__init__(**kwargs) self.count_value = count_value self.database_file = 'results.csv' def Table(self): global data data.append(str(self.count_value)) with open(self.database_file, 'w', newline='') as database: wr = csv.writer(database, delimiter=',', quoting=csv.QUOTE_MINIMAL) wr.writerow(['Column1', 'Column2', 'Result']) wr.writerow(data) print("\nCSV Verification:") with open(self.database_file, 'r') as database: reader = csv.reader(database) for row in reader: print(row) sm = ScreenManager() sm.add_widget(PutOnShelfScreen1(name='class')) class SampleApp(App): def build(self): return sm if __name__ == "__main__": SampleApp().run()
How This Works Now
- When you drag the armchair and release (
on_touch_up),Count()checks for a collision with the Furniture button and incrementsself.collision_countif detected. - Clicking the Next button triggers
save_to_csv(), which creates aDataBaseinstance with the current collision count. DataBase.Table()updates yourdatalist, writes it toresults.csv, then reads and prints the CSV content to confirm the write was successful.
You’ll now see your intended data in the CSV instead of those boolean values!
内容的提问来源于stack exchange,提问作者K.Kate

