Python 点击kv文件启用/禁用按钮

Python 点击kv文件启用/禁用按钮,python,kivy,Python,Kivy,我编写了一个简单的代码来创建计时器,为此我添加了两个按钮:开始和停止。这个想法是,当一个按钮被启用时,另一个按钮没有被启用,反之亦然 下面的代码可以工作,但我希望使用kv文件获得相同的行为 def update_time(self, instance): timer = Clock.schedule_interval(self.timer, 1.0 / 1.0) instance.disabled = True self.stop_button.disabled

我编写了一个简单的代码来创建计时器,为此我添加了两个按钮:开始和停止。这个想法是,当一个按钮被启用时,另一个按钮没有被启用,反之亦然

下面的代码可以工作,但我希望使用kv文件获得相同的行为

def update_time(self, instance):    
    timer = Clock.schedule_interval(self.timer, 1.0 / 1.0)
    instance.disabled = True
    self.stop_button.disabled = False

def stop_updating(self, instance):
    Clock.unschedule(self.timer)
    instance.disabled = True
    self.timer_button.disabled = False
如果我尝试使用下面的代码段,脚本会抛出一个错误,因为它缺少一个参数(实例)

我知道kv文件中存在“disabled”属性,但我不知道如何(或是否)使用它来修改我想要修改的两个按钮onclick

你知道怎么做吗

所有脚本代码

class LandingScreen(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def go_to_timer(self):
        clock_app.screen_manager.current = 'Timer'


class TimerScreen(GridLayout):
    current_time = StringProperty()
    timer_start = ObjectProperty(Button)
    timer_stop = ObjectProperty(Button)
    tot_sec = 0    

    def __init__(self, **kwargs): # Widgets without .kv file
        super().__init__(**kwargs)
        self.rows = 4
        self.current_time = '00:00'        

    def update_time(self, instance):    
        timer = Clock.schedule_interval(self.timer, 1.0 / 1.0)
        instance.disabled = True
        # self.stop_button.disabled = False
        self.timer_stop.disabled = False

    def stop_updating(self, instance):
        Clock.unschedule(self.timer)
        instance.disabled = True
        # self.timer_button.disabled = False
        self.timer_start.disabled = False

    def timer(self, instance):
        # Code
        

class ClockApp(App):
    def build(self):
        self.screen_manager = ScreenManager()

        # Landing screen
        self.landing_screen = LandingScreen()
        screen = Screen(name='Landing')
        screen.add_widget(self.landing_screen)
        self.screen_manager.add_widget(screen)

        # Timer screen
        self.timer_screen = TimerScreen()
        screen = Screen(name='Timer')
        screen.add_widget(self.timer_screen)
        self.screen_manager.add_widget(screen)

        return self.screen_manager

    def go_to_landing(self):
        clock_app.screen_manager.current = 'Landing'


if __name__ == '__main__':
    clock_app = ClockApp()
    clock_app.run()
<TimerScreen>:
    rows: 5
    Label:
        font_size: 60       
        text: root.current_time
    
    GridLayout:
        cols: 3
        Label:
            text: ''
        Button:
            id: 'timer_start'
            text: 'Start'
            on_press: root.update_time(self)
        Label:
            text: ''
        Label:
            text: ''
        Button:
            id: 'timer_stop'
            text: 'Stop'
            on_press: root.stop_updating(self)
            disabled: True
        Label:
            text: ''
        Label:
            text: ''
        Label:
            text: ''
        Label:
            text: ''
        
        AnchorLayout:
            anchor_x: 'left'                
            Button:
                text: 'Back'
                width: root.width / 7
                size_hint_x: None
                on_press: app.go_to_landing()


<LandingScreen>:
    rows: 7
    Label:
        font_size: 50
        text: 'Clock types'
        canvas.before:
            Color:
                rgba: 1, 0, 0, 1

    GridLayout:
        cols:3
        Label:
            text: ''
        Button:
            text: 'Timer'
            on_press: root.go_to_timer()
        Label:
            text: ''
        Label:
            text: ''
        Button:
            text: 'Countdown'
            on_press: root.go_to_countdown()
        Label:
            text: ''
        Label:
            text: ''
    
    Label:
        text: ''
kv文件

class LandingScreen(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def go_to_timer(self):
        clock_app.screen_manager.current = 'Timer'


class TimerScreen(GridLayout):
    current_time = StringProperty()
    timer_start = ObjectProperty(Button)
    timer_stop = ObjectProperty(Button)
    tot_sec = 0    

    def __init__(self, **kwargs): # Widgets without .kv file
        super().__init__(**kwargs)
        self.rows = 4
        self.current_time = '00:00'        

    def update_time(self, instance):    
        timer = Clock.schedule_interval(self.timer, 1.0 / 1.0)
        instance.disabled = True
        # self.stop_button.disabled = False
        self.timer_stop.disabled = False

    def stop_updating(self, instance):
        Clock.unschedule(self.timer)
        instance.disabled = True
        # self.timer_button.disabled = False
        self.timer_start.disabled = False

    def timer(self, instance):
        # Code
        

class ClockApp(App):
    def build(self):
        self.screen_manager = ScreenManager()

        # Landing screen
        self.landing_screen = LandingScreen()
        screen = Screen(name='Landing')
        screen.add_widget(self.landing_screen)
        self.screen_manager.add_widget(screen)

        # Timer screen
        self.timer_screen = TimerScreen()
        screen = Screen(name='Timer')
        screen.add_widget(self.timer_screen)
        self.screen_manager.add_widget(screen)

        return self.screen_manager

    def go_to_landing(self):
        clock_app.screen_manager.current = 'Landing'


if __name__ == '__main__':
    clock_app = ClockApp()
    clock_app.run()
<TimerScreen>:
    rows: 5
    Label:
        font_size: 60       
        text: root.current_time
    
    GridLayout:
        cols: 3
        Label:
            text: ''
        Button:
            id: 'timer_start'
            text: 'Start'
            on_press: root.update_time(self)
        Label:
            text: ''
        Label:
            text: ''
        Button:
            id: 'timer_stop'
            text: 'Stop'
            on_press: root.stop_updating(self)
            disabled: True
        Label:
            text: ''
        Label:
            text: ''
        Label:
            text: ''
        Label:
            text: ''
        
        AnchorLayout:
            anchor_x: 'left'                
            Button:
                text: 'Back'
                width: root.width / 7
                size_hint_x: None
                on_press: app.go_to_landing()


<LandingScreen>:
    rows: 7
    Label:
        font_size: 50
        text: 'Clock types'
        canvas.before:
            Color:
                rgba: 1, 0, 0, 1

    GridLayout:
        cols:3
        Label:
            text: ''
        Button:
            text: 'Timer'
            on_press: root.go_to_timer()
        Label:
            text: ''
        Label:
            text: ''
        Button:
            text: 'Countdown'
            on_press: root.go_to_countdown()
        Label:
            text: ''
        Label:
            text: ''
    
    Label:
        text: ''
:
行数:5
标签:
字体大小:60
文本:root.current\u time
网格布局:
科尔斯:3
标签:
文本:“”
按钮:
id:'计时器启动'
文本:“开始”
按:root.update\u时间(self)
标签:
文本:“”
标签:
文本:“”
按钮:
id:'计时器停止'
文本:“停止”
按:root。停止更新(self)
残疾人士:对
标签:
文本:“”
标签:
文本:“”
标签:
文本:“”
标签:
文本:“”
主持人安排:
主播:左
按钮:
文本:“返回”
宽度:root.width/7
大小提示:无
按:应用程序转到登录()
:
行数:7
标签:
字体大小:50
文本:“时钟类型”
在以下情况之前:
颜色:
rgba:1,0,0,1
网格布局:
科尔斯:3
标签:
文本:“”
按钮:
文本:“计时器”
按:root.转到计时器()
标签:
文本:“”
标签:
文本:“”
按钮:
文字:“倒计时”
按:root.转到倒计时()
标签:
文本:“”
标签:
文本:“”
标签:
文本:“”

我认为您的代码基本上正常工作。关于
ids
的使用,请注意以下几点:

  • 您不应该将字符串文字用作
    id
    。使用
    id:timer\u start
    代替
    id:timer\u start
    。如果使用字符串文字,如果尝试在
    kv
    中的其他位置引用它,将遇到问题(它将被解释为字符串,而不是
    id
  • 在将由
    kv
    中的
    id
    定义的类中声明
    ObjectProperty
    时,请在类中的声明中使用
    ObjectProperty(None)
  • 使用
    kv
    中的声明与类中的声明匹配
  • 将上述内容应用于python代码:

    class TimerScreen(GridLayout):
        current_time = StringProperty()
        timer_start = ObjectProperty(None)
        timer_stop = ObjectProperty(None)
        tot_sec = 0
    
    在相应的
    kv

    <TimerScreen>:
        timer_start: timer_start
        timer_stop: timer_stop
        rows: 5
    
    以及:

    kv
    ObjectProperty
    的典型声明如下:

    timer_start: timer_start
    

    可能会让人困惑,但通常就是这样做的。我更喜欢为
    ObjectProperty
    使用不同的名称,以使其更清晰。上面的第一个名称是
    ObjectProperty
    的名称,第二个名称是
    id
    。他们恰好有相同的名字。

    尝试在
    kv
    中的调用中添加
    self
    。如
    root.update\u time(self)
    。感谢您的评论。它部分起作用。现在我可以点击我的按钮一次,但当完成后,另一个按钮不会被启用。我想我应该修改函数中的“self.timer\u button.disabled=False”部分,以引用在kv文件中创建的按钮。你知道怎么做吗?你可以在
    kv
    文件中的两个
    按钮中添加
    id
    ,然后用它访问另一个
    按钮。如果看不到更多的代码,就不能说更多。我已经编辑了我的问题,以包含几乎所有的代码(我删除了不相关的代码,使其不那么重要)。嘿,John,我做了上述更改,现在它开始工作了。非常感谢您的解决方案和解释。这真的让我更了解了发生的事情!!你太棒了!
    
    timer_start: timer_start