Kivy在GridLayout

时间:2018-01-13 11:06:44

标签: python kivy

我对Kivy / Python /编程比较陌生。所以我道歉,如果有什么不清楚,但这是我的问题:我一直在做一个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

1 个答案:

答案 0 :(得分: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?)所以如果其他人有任何想法或建议,请告诉我!