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

如何在Kivy界面点击按钮时重置所有ToggleButton状态?

问题:Kivy动态生成的ToggleButton仅最后一行可重置

我正在自学Kivy(及OOP),开发一款实时数据收集APP,包含多个界面。第四屏会根据第三屏的选择动态生成GridLayout,每行包含一组3个ToggleButton和多个复选框。添加“重置”按钮后,复选框状态能正常清除,但ToggleButton仅能重置最后一行,不确定是迭代、分组问题还是其他原因。

当前相关代码

class RatingScreen(Screen):
    def __init__(self, **kwargs):
        super(RatingScreen, self).__init__(**kwargs)

    def on_enter(self, *args):
        global logsession, logdate, interfererlist
        #layouts
        ratingpage = BoxLayout(orientation='vertical')
        self.row = GridLayout(cols=5)
        nav = GridLayout(cols=3, size_hint=(1,.15))

        #widgets
        currentlabel = Label(text=(f'You are logging interferers for {logsession} on {logdate}.'), size_hint=(1, .15))
        resetbtn = Button(text="Reset", on_press=self.resetbtn)
        backbutton = Button(text="back", on_press = self.backtoint)
        savebtn = Button(text='save', on_press = self.saveint)


        #add widgets to layout
        self.add_widget(ratingpage)
        ratingpage.add_widget(currentlabel)
        self.row.add_widget(Label(text='Interferer'))
        self.row.add_widget(Label(text='Intensity'))
        self.row.add_widget(Label(text="Contact Made"))
        self.row.add_widget(Label(text='Mitigation'))
        self.row.add_widget(Label(text='Aggro'))


        for index, row in interfererlist.iterrows():
            intname = Label(text=str(row['House Name']))
            self.intensityrating = GridLayout(cols=3)
            self.intcon = CheckBox()
            self.intmit = CheckBox()
            self.intagg = CheckBox()
            self.row.add_widget(intname)
            self.row.add_widget(self.intensityrating)
            for n in range(1,4):
                self.ratebtn = ToggleButton(text=f'{n}', group=str(row['Accession Number']))
                self.intensityrating.add_widget(self.ratebtn)
                self.ratebtn.rate = str({n})
                self.ratebtn.int = str({row['Accession Number']})


            self.row.add_widget(self.intcon)
            self.row.add_widget(self.intmit)
            self.row.add_widget(self.intagg)

        ratingpage.add_widget(self.row)
        ratingpage.add_widget(nav)
        nav.add_widget(backbutton)
        nav.add_widget(resetbtn)
        nav.add_widget(savebtn)


    def saveint(self, instance):
        pass

    def resetbtn(self, instance):
        for child in self.row.children:
            if isinstance(child, CheckBox):
                child.state = 'normal'

        for col in self.row.children:
            for child in self.intensityrating.children:
                if isinstance (child, ToggleButton):
                    child.state = 'normal'

    def backtoint(self, instance):
        self.manager.current= 'interfererscreen'

    def on_leave(self, *args):
        self.clear_widgets()

问题核心分析

resetbtn方法是问题所在:复选框重置逻辑正常,但ToggleButton的重置逻辑仅作用于最后一行。此前在另一仅含ToggleButton的GridLayout界面中,使用如下重置逻辑可正常运行:

def resetbtn(self, instance):
    global interfererlist
    for child in self.potint.children:
        if isinstance (child, ToggleButton):
            child.state = 'normal'
            #reset list to empty when buttons are reset
            interfererlist = pd.DataFrame()

我曾考虑清除所有组件后重新执行on_enter,但担心后续保存输入时仍会遇到迭代问题。

解决方法

最终使用widget.walk()方法成功解决该问题,修改后的重置逻辑如下:

for child in self.row.walk():
    if isinstance (child, ToggleButton):
        child.state = 'normal'

内容的提问来源于stack exchange,提问作者ktrex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:37:46