【问题标题】:Kivy: Generate dynamically buttons on the second, third... etc screensKivy:在第二个,第三个......等屏幕上动态生成按钮
【发布时间】:2019-12-10 12:16:50
【问题描述】:

我是 Kivy 的新手:python。我正在尝试使用 ScreenManager 做一个应用程序。我有一张地图和地图键的想法应该在几个屏幕上生成按钮。例如: 地图:{user1:{thing1:value1,thing2,value2},user2:{thing1:value1...}} 第一个屏幕在滚动视图中有两个按钮:user1 和 user2。 下一个屏幕上的按钮集合将是thing1,thingN,具体取决于用户按下的“user_name”。这只是“玩具”项目,我正在研究 Kivy

我有一些全局变量。在第一个屏幕中,全局变量“user_name”根据用户在第一个屏幕上按下的内容进行初始化。然后在第二个屏幕的类中,我尝试使用 map_of_maps[user_name].keys() 并将这些键作为按钮放在第二个屏幕上。

# kivy_test.py

class MyMainApp(App):
    gapi = gAPI("tilit.txt")
    gapi.file_download()
    gapi.parse_downloaded_file()
    global data
    global user_name
    global account
    data = gapi.get_data()
    user_name = None
    account = None
    def build(self):
        return kv

class MainWindow(Screen):
    f_view = ObjectProperty(None)
    def __init__(self,**kwargs):
        super(MainWindow, self).__init__(**kwargs)
        Clock.schedule_once(self.create_scrollview)

    def create_scrollview(self, inst):
        base = data.keys()
        layout = GridLayout(cols=1)
        layout.bind(minimum_height=layout.setter("height"))

        for element in base:
            button = Button(text=str(element), size_hint=(1, 0.1))
            button.bind(on_press=self.on_scrbutton_pressed)
            layout.add_widget(button)
        scrollview = ScrollView(size=(Window.width, Window.height))
        scrollview.add_widget(layout)
        self.f_view.add_widget(scrollview)

    def on_scrbutton_pressed(self, instance):
        user_name = instance.text
        print(instance.text)

class SecondWindow(Screen):
    s_view = ObjectProperty(None)
    def __init__(self,**kwargs):
        super(SecondWindow,self).__init__(**kwargs)
        Clock.schedule_once(self.create_scrollview)

    def create_scrollview(self, inst):
        base = data[user_name].keys() # Here I have a problem
        layout = GridLayout(cols=1)
        layout.bind(minimum_height = layout.setter("height"))

        for element in base:
            button = Button(text = str(element), size_hint=(1,0.1))
            button.bind(on_press=self.on_scrbutton_pressed)
            layout.add_widget(button)
        scrollview = ScrollView(size=(Window.width, Window.height))
        scrollview.add_widget(layout)
        self.s_view.add_widget(scrollview)

    def on_scrbutton_pressed(self, instance):
        print(instance.text)

运行代码时出现错误:base = data[user_name].keys()。关键错误:无

# my.kv

# Filename: my.kv
WindowManager:
    MainWindow:
    SecondWindow:
    ThirdWindow:

<MainWindow>:
    name: "main"
    f_view: f_view

    GridLayout:
        cols: 1

        ScrollView:
            id : f_view

#        Button:
#            text: "User1"
#            on_release:
#                app.root.current = "second"
#                root.manager.transition.direction = "left"

#        Button:
#            text: "User2"
#            on_release:
#                app.root.current = "second"
#                root.manager.transition.direction = "left"


<SecondWindow>:
    name: "second"
    s_view : s_view

    GridLayout:
        cols: 1

        ScrollView:
            id : s_view

        Button:
            text: "Add"


<ThirdWindow>:
    name: "third"
    t_view : t_view

    GridLayout:
        cols: 1
        id : t_view

还有一个问题:在这种情况下如何在屏幕之间进行转换?

【问题讨论】:

    标签: python dynamic kivy screen


    【解决方案1】:

    问题 1 - KeyError

         base = data[user_name].keys()  # Here I have a problem
     KeyError: None
    

    根本原因

    当 Kivy 处理您的 kv 文件时,它会将 WindowManager 对象实例化为根,并且它还会实例化其子对象 MainWindowSecondWindow。在实例化SecondWindow 时,它调用了构造函数(__init__)和方法create_scrollview。它抛出了 KeyError,因为全局变量 user_name 包含字典类型 data 中不存在的 None 的初始值。

    解决方案

    在填充user_name 之前,在class MainWindow 的方法on_scrbutton_pressed 中添加global user_name。如果没有global user_name,Python 会在将instance.text 分配给user_name 时创建一个新的局部变量。

    问题 2

    这种情况下如何进行画面间的转换?

    解决方案

    1. 默认情况下,每个屏幕都有一个属性管理器,可为您提供 使用的 ScreenManager 的实例。将以下内容添加到方法中 on_scrbutton_pressedclass MainWindow

          self.manager.current = "second"
          self.manager.transition.direction = "left"
      
    2. class Secondwindow 中,删除构造函数并将方法create_scrollview(self, inst) 替换为on_pre_enter(self)
    3. class MainWindow 中,将构造函数__init__ 替换为on_pre_enter(self):
    4. 添加方法 on_pre_leave 以删除添加的小部件以防止重复

    片段

    class MainWindow(Screen):
        f_view = ObjectProperty(None)
    
        def on_pre_enter(self):
            Clock.schedule_once(self.create_scrollview)
        ...
    
        def on_pre_leave(self):
            self.f_view.clear_widgets()
    
        def on_scrbutton_pressed(self, instance):
            global user_name
            user_name = instance.text
            print(instance.text)
            self.manager.current = "second"
            self.manager.transition.direction = "left"
    
    
    class SecondWindow(Screen):
        s_view = ObjectProperty(None)
    
        def on_pre_enter(self):
            base = data[user_name].keys()
            ...
    
        def on_pre_leave(self):
            self.s_view.clear_widgets()
    

    【讨论】:

    • 感谢您如此全面的回答!你真的帮了我。
    【解决方案2】:

    我在我的应用中也实现了几乎相同的功能。

    • 我有一个章节名称列表作为键,它们的摘要作为 价值观。
    • 当用户进入屏幕时,keys() 被调用并且 按钮已创建。
    • 根据单击的按钮,摘要为 显示在下一个屏幕上

    这是我的编码方式(片段)

    class chapter_list(Screen):
        def on_pre_enter(self):
            self.buttons = []
            for i in flamingo.keys(): #for loop to generate buttons
                button = Button(text=str(i),height=150) #the text on the button is the chapter name
                button.bind(on_press=self.pressed) #when the button is clicked, the function pressed on called
                self.ids.fgrid.add_widget(button) #added to the flamingogrid
                self.buttons.append(button)
    

    这里的fgridLayoutid:(在这种情况下为GridLayout)我在kv 文件中为此screen 选择

    self.buttons = [] 只是为了收集按钮,以便我可以在屏幕退出时将它们删除。

    如果这有帮助,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多