【问题标题】:How to get Id and Text value of a kivy button as string?如何获取 kivy 按钮的 Id 和 Text 值作为字符串?
【发布时间】:2017-07-18 15:34:52
【问题描述】:

我有一个带有多个按钮的应用程序,我需要在按下按钮时将按钮的 id 和文本值作为字符串获取。然后将抓取的按钮的 Ids 和 Text 值传递给另一个函数以进行进一步处理。为简单起见,我编写了这个示例程序。

# main.py

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout

########################################################################
class KVMyHBoxLayout(BoxLayout):
    pass


########################################################################
class ExampleApp(App):
    def Pressbtn(self, *args):
        print'Pressed button'
    #----------------------------------------------------------------------
    def build(self):

        return KVMyHBoxLayout()

#----------------------------------------------------------------------
if __name__ == "__main__":
    app = ExampleApp()
    app.run()

kv文件

<MyButton@Button>:
    color: .8,.9,0,1
    font_size: 32

<KVMyHBoxLayout>:
    orientation: 'vertical'
    MyButton:
        id:"idBtn1"
        text: "Btn1"
        background_color: 1,0,0,1
        on_press:app.Pressbtn()
    MyButton:
        id:"idBtn2"
        text: "Btn2"
        background_color: 0,1,0,1
        on_press:app.Pressbtn()
    Label:
        text: "ID"
        background_color: 0,0,1,1
    Label:
        text: "Text"
        background_color: 1,0,1,1

当按下按钮时,其对应的 id 和 text 值将显示在 ID 和 Text 标签中。目前上述代码仅在按下按钮时打印Pressed button。我想知道如何以python方式获取按钮的id和文本值。

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    首先,当从 kv 调用按钮实例时,必须将按钮实例显式传递给方法:

    on_press: app.Pressbtn(self)
    

    然后您可以使用实例引用来修改按钮或查看其属性,您不需要id。如果要获取id,只能使用按钮父级的ids字典。

    基于您的代码的示例:

    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.lang import Builder
    
    kv_file = '''
    <MyButton@Button>:
        color: .8,.9,0,1
        font_size: 32
    
    <KVMyHBoxLayout>:
        orientation: 'vertical'
        MyButton:
            id:"idBtn1"
            text: "Btn1"
            background_color: 1,0,0,1
            on_press:app.Pressbtn(self)
        MyButton:
            id:"idBtn2"
            text: "Btn2"
            background_color: 0,1,0,1
            on_press:app.Pressbtn(self)
        Label:
            id: lobj
            text: "Object"
            background_color: 1,0,1,1
    
        Label:
            id: lid
            text: "ID"
            background_color: 0,0,1,1
        Label:
            id: ltext
            text: "Text"
            background_color: 1,0,1,1
    '''
    
    
    class KVMyHBoxLayout(BoxLayout):
        pass
    
    class ExampleApp(App):
        def Pressbtn(self, instance):
            instance.parent.ids.lobj.text = str(instance)
            instance.parent.ids.ltext.text = instance.text
            instance.parent.ids.lid.text= self.get_id(instance)
    
        def get_id(self,  instance):
            for id, widget in instance.parent.ids.items():
                if widget.__self__ == instance:
                    return id
    
        def build(self):
            Builder.load_string(kv_file)
            return KVMyHBoxLayout()
    
    if __name__ == "__main__":
        app = ExampleApp()
        app.run()
    

    输出:

    编辑:

    如果您在 .py 文件中定义小部件(按钮),则不需要将实例传递给函数,它会自动作为参数传递:

    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.uix.button import Button
    from kivy.uix.scrollview import ScrollView
    
    
    class FirstScreen(Screen):
        def __init__(self,**kwargs):
            super(FirstScreen, self).__init__(**kwargs)    
            layout=BoxLayout(orientation="vertical",size_hint_y= None)
            layout.bind(minimum_height=layout.setter('height'))                
            for i in range(50):
                    btn = Button(text="Button"+str(i),
                                 id=str(i),
                                 size_hint=(None, None),
                                 on_press=self.Press_auth)               #<<<<<<<<<<<<<<<<           
                    layout.add_widget(btn)
            root = ScrollView()
            root.add_widget(layout)
            self.add_widget(root)
    
        def Press_auth(self,instance):     
            print(str(instance))
    
    class TestScreenManager(ScreenManager):
        def __init__(self,  **kwargs):
            super(TestScreenManager,  self).__init__(**kwargs)
            self.add_widget(FirstScreen())
    
    class ExampleApp(App):
        def build(self):           
            return TestScreenManager()
    
    def main():
        app = ExampleApp()
        app.run()
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

    • 谢谢它的工作我在屏幕内使用按钮当我按下按钮它返回屏幕的对象&lt;Screen name='FirstScreen''&gt;任何想法如何获取屏幕内布局内的按钮实例。
    • @Eka 即使按钮位于Screen 内的布局内,此代码也有效(获取id 除外)。如果您无法使其正常工作,请通过添加代码来编辑问题以查看我是否可以帮助您。最好的问候。
    • 这是我的代码pastebin.com/PDQpXbkU 我正在屏幕类中动态创建一个带有按钮的Scrollview boxlayout。这个on_press=lambda a:self.Press_auth(self)我是从一些示例代码中获取的,它检测到按下事件,但它传递的对象是&lt;Screen name='FirstScreen''&gt;
    • @Eka 您只需将on_press = lambda to: self.Press_auth (self) 替换为on_press=self.Press_auth。我编辑了答案。最好的问候。
    • 谢谢它解决了我的问题。最初我试过这个 on_press=self.Press_auth() 。它给了我一个错误。再次感谢您
    【解决方案2】:

    您可以按照这些思路使用回调函数。在您的 KV 文件中:

     ToggleButton:
         text: 'Label'
         id: halftimebutton
         on_state: root.callback(self)
    

    然后在你的 .py 文件中你可以这样做:

    def callback_halftime_state(self, instance):
        if instance.state == 'down':
            self.halftime == True
        else:
            self.halftime == False
    

    这当然是显示 instance.state - 但它可以是 Kivy 公开的按钮的任何 属性instance.textinstance.id

    【讨论】:

      【解决方案3】:

      在按钮单击时获取按钮文本的示例:

      class MainApp(MDApp):
      def build(self):
      
          VB = BoxLayout(orientation='vertical', padding=50,spacing="10")
      
          Atbtn = Button(text="AT (Automata Theory)", font_size="25sp")
          Atbtn.bind(on_press=self.callback)
      
          Pybtn = Button(text="Python", font_size="25sp")
          Pybtn.bind(on_press=self.callback)
      
      
          VB.add_widget(Atbtn)
          VB.add_widget(Pybtn)
      
          return VB
      
      def callback(self, instance):
          print(instance.text)
      

      【讨论】:

        猜你喜欢
        • 2014-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多