You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:02:20