繁体   English   中英

Kivy在GridLayout中访问动态创建的TextInput

[英]Kivy accessing dynamically created TextInput inside a GridLayout

我是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

好的,我已经在解决问题上取得了一些进步,我认为我的代码已经工作到可以将其应用到完整程序中的程度,并且可以完全满足我的要求(希望如此!) 。 我对.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函数中获取每个textinput的值。我想要的textinput。

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

我想可能会有更好的方法来完成此操作(也许使用RecycleView?),因此,如果其他人有任何想法或建议,请告诉我!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM