Kivy项目求助:动态行数值求和与自动计算功能实现
解决方案:Kivy 数值求和与自动计算触发
我来帮你搞定这两个问题,下面是具体的修改方案和代码说明:
1. 实现数值求和(替换字符串拼接)
原来的代码只是把输入的数值字符串直接拼接,现在我们需要把每个值转换成数字后累加,同时处理空输入或非数字的异常情况,避免程序崩溃。
修改User类中的test函数:
def test(self): values = [] rows = self.ids.rows for row in reversed(rows.children): vals = [] for ch in reversed(row.children): if isinstance(ch, TextInput): vals.append(ch.text) if isinstance(ch, Button): vals.insert(0, ch.text) values.append(vals) # 初始化总和为0,遍历每个值进行累加 total = 0.0 # 用float支持小数,如果只需要整数可以改成int for val in values: # 处理空输入或非数字的情况,无效输入默认加0 try: num = float(val[2]) total += num except ValueError: pass # 输入不是有效数字时跳过 # 将总和转为字符串显示,保留两位小数更美观 self.total_value.text = f"{total:.2f}"
2. 自动触发计算(无需点击Total Value框)
我们需要让每个"Value"文本框在输入内容变化时,自动调用求和函数。只需要在KV文件中给对应的TextInput添加on_text事件即可:
修改demo.kv中的<Row>规则:
<Row>: size_hint_y: None height: self.minimum_height height: 40 Button: text: root.button_text size_hint_x: None top: 200 TextInput: text: root.col_data3 width: 300 TextInput: text: root.col_data4 width: 300 on_text: app.root.test() # 每次文本变化时触发求和计算
另外,如果你不需要保留点击Total Value框触发计算的功能,可以把total_value文本框的on_focus:root.test()去掉;如果需要保留,也可以同时存在两种触发方式。
修改后的完整代码
demo.py
from kivy.uix.screenmanager import Screen from kivy.app import App from kivy.lang import Builder from kivy.core.window import Window from kivy.uix.boxlayout import BoxLayout from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty, NumericProperty from kivy.uix.textinput import TextInput from kivy.uix.button import Button Window.clearcolor = (0.5, 0.5, 0.5, 1) Window.size = (500, 400) class User(Screen): total_value = ObjectProperty(None) def add_more(self): self.ids.rows.add_row() def test(self): values = [] rows = self.ids.rows for row in reversed(rows.children): vals = [] for ch in reversed(row.children): if isinstance(ch, TextInput): vals.append(ch.text) if isinstance(ch, Button): vals.insert(0, ch.text) values.append(vals) total = 0.0 for val in values: try: num = float(val[2]) total += num except ValueError: pass self.total_value.text = f"{total:.2f}" class Row(BoxLayout): col_data = ListProperty(["?", "?", "?", "?", "?"]) button_text = StringProperty("") col_data3 = StringProperty("") col_data4 = StringProperty("") def __init__(self, **kwargs): super(Row, self).__init__(**kwargs) class Rows(BoxLayout): row_count = 0 def __init__(self, **kwargs): super(Rows, self).__init__(**kwargs) self.add_row() def add_row(self): self.row_count += 1 self.add_widget(Row(button_text=str(self.row_count))) class Test(App): def build(self): self.root = Builder.load_file('demo.kv') return self.root if __name__ == '__main__': Test().run()
demo.kv
<Row>: size_hint_y: None height: self.minimum_height height: 40 Button: text: root.button_text size_hint_x: None top: 200 TextInput: text: root.col_data3 width: 300 TextInput: text: root.col_data4 width: 300 on_text: app.root.test() <Rows>: size_hint_y: None height: self.minimum_height orientation: "vertical" User: total_value:total_value BoxLayout: orientation: "vertical" padding : 20, 5 BoxLayout: orientation: "horizontal" spacing: 10, 10 size: 450, 40 size_hint: None, None Label: size_hint_x: .2 text: "Number" text_size: self.size valign: 'bottom' halign: 'center' Label: size_hint_x: .4 text: "name" text_size: self.size valign: 'bottom' halign: 'center' Label: size_hint_x: .4 text: "Value" text_size: self.size valign: 'bottom' halign: 'center' ScrollView: Rows: id: rows BoxLayout: orientation: "horizontal" padding : 10, 5 spacing: 10, 10 size: 200, 40 size_hint: None, None Label: size_hint_x: .7 text: "Total value" TextInput: id: total_value # 可选:保留点击触发,不需要可以删除下面这行 on_focus:root.test() BoxLayout: orientation: "horizontal" size_hint_x: .2 size_hint_y: .2 Button: text: "+Add More" on_press: root.add_more()
内容的提问来源于stack exchange,提问作者Nirdesh Kumawat
相关产品推荐
相关产品推荐

