简体   繁体   English

在 kivy 中的类(屏幕)之间传递值

[英]Pass values between classes (screens) in kivy

I know that generally similar questions have been answered before.我知道之前已经回答过一般类似的问题。 I have read them all of them.我已经阅读了所有这些内容。 I have tried them all.我都试过了。 Nothing seems to work for my particular case.对我的特殊情况似乎没有任何作用。

I am working in kivy with python 3. Not sure if that is the reason (maybe prior answers work only on python 2?).我正在使用 python 3 在 kivy 中工作。不确定这是否是原因(也许先前的答案仅适用于 python 2?)。

I simply want to pass the text input from screen1_textinput (screen1_textinput.text) and the text input from screen1_textinput2 (screen1_textinput2.text), [the last one being the input from the slider of screen 1] into the text input of screen2_textinput (screen2_textinput.text).我只是想将来自 screen1_textinput (screen1_textinput.text) 的文本输入和来自 screen1_textinput2 (screen1_textinput2.text) 的文本输入,[最后一个是来自屏幕 1 滑块的输入] 传递到 screen2_textinput (screen2_textinput.text) 的文本输入中。文本)。

Full code below for a simplified version of my app下面是我的应用程序简化版本的完整代码

## IMPORT THE DIFFERENT PACKAGES AND PROGRAMS NEEDED FOR THE APP TO WORK
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition, SwapTransition, FadeTransition, WipeTransition, FallOutTransition, RiseInTransition
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.label import Label
from kivy.uix.button import Button


## THE BUILDER HAS THE CODE THAT DEFINES THE APPEARANCE OF THE APP. IT IS THE KIVY CODE
Builder.load_string("""                    
############################################################SCREEN 1########################################                 
<Screen1>:

    RelativeLayout:    # RelativeLayout allows the elements of a screen to be positioned relatively to the position of the screen



        Label:    # Label is just text
            id: screen1_label    # Identifier
            text: 'This screen just shows a TextInput and a slider'    # Text that appears in the label
            pos_hint: {'x': 0.5, 'y': 0.9}    # Position of the Label in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.15, 0.05)    # Size of the Label
            font_size: (screen1_label.width + screen1_label.height) / 6     # Size of the font relative to the size of the Label
            bold: True    # Bold face




        TextInput:    # TextInput allows the user to enter text into a box
            id: screen1_textinput    # Identifier
            text: ''    # The initial text in the text box, nothing in this case
            hint_text: 'This is a TextInput. Just enter some text'    # The hint text guides the user to what input is expected
            background_color: (1, 0, 0, 1)    # The background of the TextInput
            foreground_color: (1, 1, 1, 1)    # The color of the text
            pos_hint: {'x': 0.05, 'y': 0.8}    # Position of the InputText in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.5, 0.05)    # Size of the InputText in relation to the screen
            font_size: (screen1_textinput.width + screen1_textinput.height) / 32    # Size of the font relative to the size of the TextInput
            on_text: root.manager.get_screen('screen2').screen2_textinput.text = screen1_textinput.text



        Slider:
            id: screen1_slider    # Identifier
            min: 0    # Minimum value allowed for the slider
            max: 100    # Maximum value allowed for the slider
            value: 50    # Initial value
            step: 1    # Step size
            orientation: 'vertical'    # Orientation of the slider
            pos_hint: {'x': 0.3, 'y': 0.20}    # Location of the slider in the screen (relative to the screen size)
            size_hint: (0.05, 0.25)    # Size of the slider relative to the size of the screen



        TextInput:    # TextInput allows the user to enter text into a box
            id: screen1_textinput2    # Identifier
            text: str(int(screen1_slider.value))   # The initial text in the text box, the value of the slider in this case
            background_color: (1, 0, 0, 1)    # The background of the TextInput
            foreground_color: (1, 1, 1, 1)    # The color of the text
            pos_hint: {'x': 0.5, 'y': 0.4}    # Position of the InputText in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.1, 0.05)    # Size of the InputText in relation to the screen
            font_size: (screen1_textinput2.width + screen1_textinput2.height) / 10    # Size of the font relative to the size of the TextInput





        Button:
            id: screen1_buttontoscreen2    # Identifier
            text: 'Move to screen 2'    # Text in the button
            pos_hint: {'x': 0.18, 'y': 0.02}    # Position of the Button in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.2, 0.05)    # Size of the Button in relation to the screen
            background_color: (1, 1, 1, 1)    # The background of the button
            color: (0, 0, 1, 1)    # The color of the text of the Button
            font_size: (screen1_buttontoscreen2.width + screen1_buttontoscreen2.height) / 12    # Size of the font relative to the size of the Button
            on_release:
                root.manager.current = 'screen2'    # Switch to screen 2 on release of the Button







############################################################SCREEN 2########################################
<Screen2>:

    screen2_textinput: screen2_textinput

    RelativeLayout:    # RelativeLayout allows the elements of a screen to be positioned relatively to the position of the screen


        Label:    # Label is just text
            id: screen2_label    # Identifier
            text: 'This screen just collects the inputs from Screen 1'    # Text that appears in the label
            pos_hint: {'x': 0.5, 'y': 0.9}    # Position of the Label in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.15, 0.05)    # Size of the Label
            font_size: (screen2_label.width + screen2_label.height) / 6     # Size of the font relative to the size of the Label
            bold: True    # Bold face





        TextInput:    # TextInput allows the user to enter text into a box
            id: screen2_textinput    # Identifier
            text: ''
            background_color: (1, 0, 0, 1)    # The background of the TextInput
            foreground_color: (1, 1, 1, 1)    # The color of the text
            pos_hint: {'x': 0.5, 'y': 0.45}    # Position of the InputText in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.3, 0.05)    # Size of the InputText in relation to the screen
            font_size: (screen2_textinput.width + screen2_textinput.height) / 10    # Size of the font relative to the size of the TextInput



        Button:
            id: screen2_buttontoscreen1    # Identifier
            text: 'Move to screen 1'    # Text in the button
            pos_hint: {'x': 0.18, 'y': 0.02}    # Position of the Button in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.2, 0.05)    # Size of the Button in relation to the screen
            background_color: (1, 1, 1, 1)    # The background of the button
            color: (0, 0, 1, 1)    # The color of the text of the Button
            font_size: (screen2_buttontoscreen1.width + screen2_buttontoscreen1.height) / 12    # Size of the font relative to the size of the Button
            on_release:
                root.manager.current = 'screen1'    # Switch to screen 1 on release of the Button

            """)




## THIS PART IS THE PYTHON CODE
class Screen1(Screen):
    pass




class Screen2(Screen):
    def passvariables(self):
        self.screen2_textinput.text = self.ids.screen1_textinput.text
    pass








class whAppever(App):
    def build(self):
        sm = ScreenManager(transition = FallOutTransition())
        sm.add_widget(Screen1(name = 'screen1'))
        sm.add_widget(Screen2(name = 'screen2'))
        return sm



if __name__=='__main__':
    whAppever().run()

My question in particular is how to pass values from the kivy language to the python language and from the python language to the kivy language and have the values updated at all times.我的问题特别是如何将值从 kivy 语言传递到 python 语言,从 python 语言传递到 kivy 语言,并始终更新值。 After reviewing and trying all the prior answers, I figured out that a good way to pass values is to use this in screen 2:在查看并尝试了所有先前的答案之后,我发现传递值的一个好方法是在屏幕 2 中使用它:

class Screen2(Screen):
    def passvariables(self):
        self.screen2_textinput.text = self.ids.screen1_textinput.text
    pass

My idea was that with this code I am making the value screen2_textinput.text equal the value screen1_textinput.text我的想法是,使用此代码,我使值 screen2_textinput.text 等于值 screen1_textinput.text

This code runs and the app is uploaded without error.此代码运行并且应用程序上传没有错误。 However, nothing happens when I update the text of screen1_textinput.text (no update in the text of screen2_textinput).但是,当我更新 screen1_textinput.text 的文本时,没有任何反应(screen2_textinput 的文本没有更新)。 According to a prior answer to a similar question, this should work, but it does not.根据之前对类似问题的回答,这应该有效,但没有。

The only potential workaround that I found is to use in the kivy language screen1_textinput我发现的唯一可能的解决方法是在 kivy 语言 screen1_textinput 中使用

on_text: root.manager.get_screen('screen2').screen2_textinput.text = screen1_textinput.text

which simply passes the text inputed at screen1_textinput to screen2_textinput, but this is not what I want.它只是将在 screen1_textinput 输入的文本传递给 screen2_textinput,但这不是我想要的。 I want to have the text value of screen1_textinput (screen1_textinput.text) passed to python code so that I can manipulate it, have the text value of screen1_textinput2 (screen1_textinput2.text) passed to python code so that I can manipulate in python code, put them together (much easier to manipulate strings in python than in kivy language) and then pass the resulting string back to screen2_textinput (screen2_textinput.text).我想将 screen1_textinput (screen1_textinput.text) 的文本值传递给 python 代码,以便我可以操作它,将 screen1_textinput2 (screen1_textinput2.text) 的文本值传递给 python 代码,以便我可以在 python 代码中进行操作,把将它们放在一起(在 python 中操作字符串比在 kivy 语言中更容易),然后将结果字符串传递回 screen2_textinput (screen2_textinput.text)。 And have all values updated.并更新所有值。

I thought that this should be straigthforward, but there are tens of pages on this and nothing seems to work and update the values as I want.我认为这应该是直截了当的,但是这上面有几十页,似乎没有任何效果,可以根据需要更新值。

Any help appreciated.任何帮助表示赞赏。 I have already read and tried previous answers to similar questions.我已经阅读并尝试了以前对类似问题的回答。 Nothing does what I am trying to do.没有什么可以做我想做的。

Thank you谢谢

Problem & Explanation问题及说明

Your app encountered problem because self is referring to Screen2 and ids.screen1 does not exist in self.ids .您的应用程序遇到问题,因为self指的是 Screen2 而ids.screen1self.ids中不存在。 If you add a print(self.ids) before the code, it will display all the ids defined in kv file under Screen2.如果在代码前添加一个print(self.ids) ,它会显示Screen2下kv文件中定义的所有id

Snippets片段

 self.screen2_textinput.text = self.ids.screen1_textinput.text

Soltuion解决方案

Please refer to the example for details.详情请参考示例。

kv file kv文件

  1. Add a new class ScreenManagement添加一个新类 ScreenManagement
  2. Add screens 1 and 2 under ScreenManagement在 ScreenManagement 下添加屏幕 1 和 2
  3. Add ids for screens 1 and 2为屏幕 1 和 2 添加ID
  4. Remove on_text event for screen1_textinput删除了screen1_textinput on_text事件

Python file蟒蛇文件

  1. Replace passvariables(self) with on_enter(self, *args)on_enter(self, *args)替换passvariables(self) on_enter(self, *args)
  2. Replace self.ids.screen1_textinput.text with self.manager.ids.screen1.ids.screen1_textinput.textself.ids.screen1_textinput.text替换为self.manager.ids.screen1.ids.screen1_textinput.text
  3. Add class ScreenManagement添加类ScreenManagement
  4. Replace return sm with return ScreenManagement()return ScreenManagement()替换return sm
  5. Remove all references to sm删除所有对sm 的引用

Example例子

main.py主文件

## IMPORT THE DIFFERENT PACKAGES AND PROGRAMS NEEDED FOR THE APP TO WORK
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition, SwapTransition, FadeTransition, WipeTransition, FallOutTransition, RiseInTransition
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.label import Label
from kivy.uix.button import Button


## THE BUILDER HAS THE CODE THAT DEFINES THE APPEARANCE OF THE APP. IT IS THE KIVY CODE
Builder.load_string("""
#:import FallOutTransition kivy.uix.screenmanager.FallOutTransition

<ScreenManagement>:
    transition: FallOutTransition()
    Screen1:
        id: screen1
        name: 'screen1'
    Screen2:
        id: screen2
        name: 'screen2'
                
############################################################SCREEN 1########################################                 
<Screen1>:

    RelativeLayout:    # RelativeLayout allows the elements of a screen to be positioned relatively to the position of the screen

        Label:    # Label is just text
            id: screen1_label    # Identifier
            text: 'This screen just shows a TextInput and a slider'    # Text that appears in the label
            pos_hint: {'x': 0.5, 'y': 0.9}    # Position of the Label in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.15, 0.05)    # Size of the Label
            font_size: (screen1_label.width + screen1_label.height) / 6     # Size of the font relative to the size of the Label
            bold: True    # Bold face

        TextInput:    # TextInput allows the user to enter text into a box
            id: screen1_textinput    # Identifier
            text: ''    # The initial text in the text box, nothing in this case
            hint_text: 'This is a TextInput. Just enter some text'    # The hint text guides the user to what input is expected
            background_color: (1, 0, 0, 1)    # The background of the TextInput
            foreground_color: (1, 1, 1, 1)    # The color of the text
            pos_hint: {'x': 0.05, 'y': 0.8}    # Position of the InputText in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.5, 0.05)    # Size of the InputText in relation to the screen
            font_size: (screen1_textinput.width + screen1_textinput.height) / 32    # Size of the font relative to the size of the TextInput

        Slider:
            id: screen1_slider    # Identifier
            min: 0    # Minimum value allowed for the slider
            max: 100    # Maximum value allowed for the slider
            value: 50    # Initial value
            step: 1    # Step size
            orientation: 'vertical'    # Orientation of the slider
            pos_hint: {'x': 0.3, 'y': 0.20}    # Location of the slider in the screen (relative to the screen size)
            size_hint: (0.05, 0.25)    # Size of the slider relative to the size of the screen

        TextInput:    # TextInput allows the user to enter text into a box
            id: screen1_textinput2    # Identifier
            text: str(int(screen1_slider.value))   # The initial text in the text box, the value of the slider in this case
            background_color: (1, 0, 0, 1)    # The background of the TextInput
            foreground_color: (1, 1, 1, 1)    # The color of the text
            pos_hint: {'x': 0.5, 'y': 0.4}    # Position of the InputText in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.1, 0.05)    # Size of the InputText in relation to the screen
            font_size: (screen1_textinput2.width + screen1_textinput2.height) / 10    # Size of the font relative to the size of the TextInput

        Button:
            id: screen1_buttontoscreen2    # Identifier
            text: 'Move to screen 2'    # Text in the button
            pos_hint: {'x': 0.18, 'y': 0.02}    # Position of the Button in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.2, 0.05)    # Size of the Button in relation to the screen
            background_color: (1, 1, 1, 1)    # The background of the button
            color: (0, 0, 1, 1)    # The color of the text of the Button
            font_size: (screen1_buttontoscreen2.width + screen1_buttontoscreen2.height) / 12    # Size of the font relative to the size of the Button
            on_release:
                root.manager.current = 'screen2'    # Switch to screen 2 on release of the Button


############################################################SCREEN 2########################################
<Screen2>:

    screen2_textinput: screen2_textinput

    RelativeLayout:    # RelativeLayout allows the elements of a screen to be positioned relatively to the position of the screen

        Label:    # Label is just text
            id: screen2_label    # Identifier
            text: 'This screen just collects the inputs from Screen 1'    # Text that appears in the label
            pos_hint: {'x': 0.5, 'y': 0.9}    # Position of the Label in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.15, 0.05)    # Size of the Label
            font_size: (screen2_label.width + screen2_label.height) / 6     # Size of the font relative to the size of the Label
            bold: True    # Bold face

        TextInput:    # TextInput allows the user to enter text into a box
            id: screen2_textinput    # Identifier
            text: ''
            background_color: (1, 0, 0, 1)    # The background of the TextInput
            foreground_color: (1, 1, 1, 1)    # The color of the text
            pos_hint: {'x': 0.5, 'y': 0.45}    # Position of the InputText in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.3, 0.05)    # Size of the InputText in relation to the screen
            font_size: (screen2_textinput.width + screen2_textinput.height) / 10    # Size of the font relative to the size of the TextInput

        Button:
            id: screen2_buttontoscreen1    # Identifier
            text: 'Move to screen 1'    # Text in the button
            pos_hint: {'x': 0.18, 'y': 0.02}    # Position of the Button in relation to the screen (coordinates (0,0) are lower left)
            size_hint: (0.2, 0.05)    # Size of the Button in relation to the screen
            background_color: (1, 1, 1, 1)    # The background of the button
            color: (0, 0, 1, 1)    # The color of the text of the Button
            font_size: (screen2_buttontoscreen1.width + screen2_buttontoscreen1.height) / 12    # Size of the font relative to the size of the Button
            on_release:
                root.manager.current = 'screen1'    # Switch to screen 1 on release of the Button

            """)


## THIS PART IS THE PYTHON CODE
class Screen1(Screen):
    pass


class Screen2(Screen):
    def on_enter(self, *args):
        self.screen2_textinput.text = self.manager.ids.screen1.ids.screen1_textinput.text


class ScreenManagement(ScreenManager):
    pass


class whAppever(App):
    def build(self):
        return ScreenManagement()


if __name__ == '__main__':
    whAppever().run()

Output输出

img01 - Kivy 进入 img02 - Kivy 显示

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

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