【问题标题】:Kivy accessing dynamically created TextInput inside a GridLayoutKivy 在 GridLayout 中访问动态创建的 TextInput
【发布时间】:2018-01-14 00:05:59
【问题描述】:

我对 Kivy/Python/Programming 比较陌生。因此,如果有任何不清楚的地方,我深表歉意,但这是我的问题:我一直在研究 Kivy 锻炼计划,该计划可以随机选择,也可以手动选择我想要进行的锻炼。

我现在遇到的问题是在手动选择练习期间(在下面的 EditWorkoutScreen 中,只需单击主屏幕上的按钮即可到达那里)。下面我的代码的相关部分几乎显示了我想要的内容(到目前为止,它包括标签和 ScrollView/GridLayout 中的文本输入),但我无法弄清楚如何访问文本输入中的文本。该文本代表每次锻炼的默认持续时间,我希望能够更改该时间(例如,如果我想在锻炼期间进行更长/更短的特定锻炼)。我有一个 on_text_validate 函数,它打印文本输入中的内容,但显然现在它只返回最后一行,因为每行的变量都被覆盖,但我需要的是每个文本输入与适当的练习配对。我尝试过使用 RecycleView,因为这似乎是一个不错的选择,但是在尝试从动态创建的小部件中获取文本时,我仍然遇到了问题。

所以我的主要问题是,如何从这些动态创建的小部件访问每个练习的文本输入?

wotester.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
import pandas as pd


class MainScreen(Screen):
    pass

exercisedict = {'exercise':['Pushups', 'Squats', 'Curls'],'focus':['Chest','Legs','Arms'],'equip':['None','None','Dumbells'], 'deftime':['30','30','40']}
exercisedf = pd.DataFrame(exercisedict)

class EditWorkoutScreen(Screen):

    def setupscreen(self):
        global exercisedf

        for index, row in exercisedf.iterrows():
            def testtext(self):
                print extime.text
            grid = GridLayout(rows=1, spacing=2)
            exname = Label(text=str(row.exercise))
            exfocus = Label(text=str(row.focus))
            exequip = Label(text=str(row.equip))
            extime = TextInput(text=str(row.deftime), size_hint=(None,None), size=(25,30),font_size=11, multiline=False)
            extime.bind(on_text_validate=testtext)

            grid.add_widget(exname)
            grid.add_widget(exfocus)
            grid.add_widget(exequip)
            grid.add_widget(extime)

            self.ids.exercisestoverify.add_widget(grid)


class ScreenManagement(ScreenManager):
    pass

presentation = Builder.load_file("wotester.kv")


class MainApp(App):

    def build(self):
        return presentation


MainApp().run()

wotester.kv

#: import FadeTransition kivy.uix.screenmanager.FadeTransition
#: import main wotester

ScreenManagement:
    transition: FadeTransition()
    MainScreen:
    EditWorkoutScreen:

####### Layout Outlines #############################################################
<GridLayout>:
    canvas.after:
        Color:
            rgb: 1,0,0
        Line:
            rectangle: self.x+1,self.y+1,self.width-1,self.height-1
        Color:
            rgb: 1,1,1

<FloatLayout>:
    canvas.after:
        Color:
            rgb: 1,0,0
        Line:
            rectangle: self.x+1,self.y+1,self.width-1,self.height-1
        Color:
            rgb: 1,1,1
<BoxLayout>:
    canvas.after:
        Color:
            rgb: 1,0,0
        Line:
            rectangle: self.x+1,self.y+1,self.width-1,self.height-1
        Color:
            rgb: 1,1,1
#########################################################################################


<MainScreen>:
    name: "main"
    FloatLayout:
        id: test
        canvas.before:
            Color:
                rgba: 0, 0, 1, .5
            Rectangle:
                pos: self.pos
                size: self.size

        Label:
            text: "Workout Creator"
            pos_hint:{"x": 0, "y": .4}
            font_size: 40
        Label:
            text: "Welcome"
            pos_hint:{"x": -.4, "y": .4}
            font_size: 20
        Button:
            text: "Click here"
            color: 0,1,0,1
            size_hint: .2, .1 
            pos_hint: {"x":.4, "y":.7}
            on_release: root.manager.current = "editworkout"

<MyGrid>:

<EditWorkoutScreen>:
    name:'editworkout'
    on_enter: root.setupscreen()
    FloatLayout:
        Label:
            text: 'Verify/Edit Workout'
            pos: 0, 550
            font_size: 20

        ScrollView:
            pos_hint: {"x":.160, "y":-.15}
            GridLayout:
                id: exercisestoverify
                size_hint_y: None
                size_hint_x: .80
                orientation: "vertical"
                height: self.minimum_height  
                row_default_height: 30
                spacing: 0
                cols:1

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    好的,我在解决我的问题方面取得了一些进展,我认为我的代码可以运行到可以将它应用到我的完整程序并让它完全按照我需要做的事情的地步(希望!)。我对我的 .py 代码进行了一些重大更改,并对 kv 文件进行了一些小的更改,我将在此处发布这些更改,以防它对处于类似情况的其他人有所帮助。

    wotester.py

    from kivy.app import App
    from kivy.lang import Builder
    from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
    from kivy.uix.widget import Widget
    from kivy.uix.button import Button
    from kivy.uix.textinput import TextInput
    from kivy.uix.label import Label
    from kivy.uix.floatlayout import FloatLayout
    from kivy.uix.gridlayout import GridLayout
    import pandas as pd
    
    exercisedict = {'exercise':['Pushups', 'Squats', 'Curls'],'focus':['Chest','Legs','Arms'],'equip':['None','None','Dumbells'], 'deftime':['30','30','40']}
    exercisedf = pd.DataFrame(exercisedict)
    
    
    class MainScreen(Screen):
        pass
    
    
    class EditWorkoutScreen(Screen):
    
        def setupscreen(self):
            for index, row in exercisedf.iterrows():
                MyGrid(str(row.exercise),str(row.focus),str(row.equip),str(row.deftime))
    
        def addgrids(self):
            global grids
            for i in grids:
                print i.children
                self.ids.exercisestoverify.add_widget(i)
    
        def printtext(self):
            global grids
            for i in grids:
                print i.extime.text
    
    
    class ScreenManagement(ScreenManager):
        pass
    
    grids= []
    class MyGrid(GridLayout):
        def __init__(self,exname,exfocus,exequip,extime, **kwargs):
            super(MyGrid, self).__init__(**kwargs)
            global grids
            def testtext(self):
                print self.text
            self.exname = Label(text=exname)
            self.exfocus = Label(text=exfocus)
            self.exequip = Label(text=exequip)
            self.extime = TextInput(text=extime, size_hint=(None,None), size=(25,30),font_size=11, multiline=False)
            self.extime.bind(on_text_validate=testtext)
    
            self.add_widget(self.exname)
            self.add_widget(self.exfocus)
            self.add_widget(self.exequip)
            self.add_widget(self.extime)
    
            grids.append(self)
    
    
    presentation = Builder.load_file("wotester.kv")
    
    
    class MainApp(App):
    
        def build(self):
            return presentation
    
    
    MainApp().run()
    

    wotester.kv

    #: import FadeTransition kivy.uix.screenmanager.FadeTransition
    #: import main wotester
    
    ScreenManagement:
        transition: FadeTransition()
        MainScreen:
        EditWorkoutScreen:
    
    ####### Layout Outlines #############################################################
    <GridLayout>:
        canvas.after:
            Color:
                rgb: 1,0,0
            Line:
                rectangle: self.x+1,self.y+1,self.width-1,self.height-1
            Color:
                rgb: 1,1,1
    
    <FloatLayout>:
        canvas.after:
            Color:
                rgb: 1,0,0
            Line:
                rectangle: self.x+1,self.y+1,self.width-1,self.height-1
            Color:
                rgb: 1,1,1
    <BoxLayout>:
        canvas.after:
            Color:
                rgb: 1,0,0
            Line:
                rectangle: self.x+1,self.y+1,self.width-1,self.height-1
            Color:
                rgb: 1,1,1
    #########################################################################################
    
    
    <MainScreen>:
        name: "main"
        FloatLayout:
            id: test
            canvas.before:
                Color:
                    rgba: 0, 0, 1, .5
                Rectangle:
                    pos: self.pos
                    size: self.size
    
            Label:
                text: "Workout Creator"
                pos_hint:{"x": 0, "y": .4}
                font_size: 40
            Label:
                text: "Welcome"
                pos_hint:{"x": -.4, "y": .4}
                font_size: 20
            Button:
                text: "Click here"
                color: 0,1,0,1
                size_hint: .2, .1 
                pos_hint: {"x":.4, "y":.7}
                on_release: root.manager.current = "editworkout"
    
    <MyGrid>:
        rows: 1
    
    <EditWorkoutScreen>:
        name:'editworkout'
        on_enter: root.setupscreen()
        FloatLayout:
            Label:
                text: 'Verify/Edit Workout'
                pos: 0, 550
                font_size: 20
    
            ScrollView:
                pos_hint: {"x":.160, "y":-.15}
                GridLayout:
                    id: exercisestoverify
                    size_hint_y: None
                    size_hint_x: .80
                    orientation: "vertical"
                    height: self.minimum_height  
                    row_default_height: 30
                    spacing: 0
                    cols:1
            Button:
                text: 'press'
                on_press: root.addgrids()
                size: 100,20
                size_hint: None,None
            Button:
                text: 'text input text'
                on_press: root.printtext()
                size: 100,20
                size_hint: None,None
                pos: 100,100
    

    现在进入 EditWorkout 屏幕后,我的 setupscreen 函数运行,它为我的数据框中的每个练习实例化自定义 GridLayout (MyGrid),然后将其附加到列表(网格)中。然后,我通过 addgrids 函数将网格列表中的每个对象添加到屏幕上的 GridLayout 中,现在我可以使用网格列表从 EditWorkout 屏幕下添加的 printtext 函数中获取每个文本输入的值,以挑选出哪个我想要的文本输入。

    主要的关键是创建自定义 GridLayout 类,使用我需要的所有变量/小部件对其进行初始化,并将每个自定义对象添加到列表中,以便我可以浏览该列表并在需要时获取必要的文本输入文本。

    我想可能有更好的方法来实现这一点(也许使用 RecycleView?)所以如果其他人有任何想法或建议,请告诉我!

    【讨论】:

      猜你喜欢
      • 2021-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-01
      • 2021-10-24
      • 2016-09-02
      相关资源
      最近更新 更多