【问题标题】:Get access a variable inside a method from another class - Python and Kivy从另一个类访问方法内的变量 - Python 和 Kivy
【发布时间】:2017-10-06 08:23:57
【问题描述】:

我目前正在与 kivy 合作开发一个可以在多个屏幕上动态打印数字的应用程序。

现在正在从一个屏幕打印值,但我还必须在其他两个屏幕上显示值,问题是我正在调用一个类的方法以及时连续运行并更新变量值,我想要从其他类中的该方法查询或访问这些变量以在其他屏幕上打印它们,每个类都代表一个屏幕,因此它们必须存在于代码中。

我想知道这是否可行以及如何实施解决方案。

让我分享我的一段代码,它非常大,所以我只粘贴相关代码:

gui.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.properties import ObjectProperty, StringProperty, NumericProperty
from kivy.uix.gridlayout import GridLayout
from kivy.clock import Clock

# Creating dynamic variables
class Show_Val(Screen):
    timer_update = NumericProperty(0)
    dist_travel = NumericProperty(0)
    average_mph = NumericProperty(0)
    temp = NumericProperty(0)
    dist_travel_2 = NumericProperty(0)

# screen 1: this is working ok
class Main_Screen(Screen):
    update_val = Show_Val()

    def update(self, dt):
        # these corresponds to the screen 1, their are currently working
        self.update_val.timer_update += 1
        self.update_val.dist_travel += 1 
        self.update_val.average_mph += 1

        # temp variable would be printed in screen 2: Input_Screen
        self.update_val.temp += 1

        # and dist_travel_2 will be printed in screen 3: Route_Screen
        self.update_val.dist_travel_2 += 1


# screen 2: here I need to get access to self.update_val.temp      
class Input_Screen(Screen):
    pass

# screen 3: here I need to get access to self.update_val.temp   
class Route_Screen(Screen):
    pass

# screen 0 or master screen management, it's just for reference
class Screen_Management(ScreenManager):
    pass

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

class guiApp(App):
    def build(self):
        main = Main_Screen()

        # this call is my "loop" and is updating the variables at 50hz
        # frequency, I tried to call differently functions like this one
        # but with no success.
        Clock.schedule_interval(main.update, 1.0/50.0)
        return presentation

guiApp().run()

gui.kv

Screen_Management:
    id: screen_management
    transition: FadeTransition()
    Main_Screen:
        id: main_screen
        name: "main_screen_name"
        manager: screen_management
    Input_Screen:
        id: tire_setup_screen_id
        name: "tire_setup_screen_name"
        manager: screen_management
    Route_Screen:
        name: "route_input_screen_name"

##############################################################
##############################################################

# Screen 1: Main Screen
# working ok
<Main_Screen>:
    canvas:
        Color:
            rgb: [.30, .30, .30]
        Rectangle:
            pos: self.pos
            size: self.size

    BoxLayout:
        orientation: 'vertical'
        Button:
            id: timer_indicator
            background_disabled_down: ('0.00.00,000')
            background_color: .52, .52, .52, 1
            bold: 1
            color: .0078,.67,.69,1
            font_size: 100
            text: str(root.update_val.timer_update)
            #text: root.update_val.test
            pos_hint: {'x': .2}
            size_hint: [.8, 1]


        Button:
            background_color: .52, .52, .52, 1
            bold: 1
            color: .0078,.67,.69,1
            font_size: 100
            text: str(root.update_val.dist_travel)
            pos_hint: {'x': .2}
            size_hint: [.8, 1]
        Button:
            background_color: .52, .52, .52, 1
            bold: 1
            color: .0078,.67,.69,1
            font_size: 100
            text: str(root.update_val.average_mph)
            pos_hint: {'x': .2}
            size_hint: [.8, 1]

    Button:
        background_color: .52, .52, .52, 1
        bold: 1
        color: .0078,.67,.69,1
        size_hint: .2, 1
        pos_hint: {"x": 0, "center_y": .5}
        on_release: app.root.current = "tire_setup_screen_name"
        text: " INPUTS "
        font_size: 30

##############################################################
##############################################################

# Screen 2: Input Screen
# I will need to print self.update_val.temp value in this creen

<Input_Screen>:
    canvas:
        Color:
            rgb: [.30, .30, .30]
        Rectangle:
            pos: self.pos
            size: self.size
    Button:
        background_color: .52, .52, .52, 1
        bold: 1
        color: .0078,.67,.69,1
        font_size: 30
        size_hint: 0.2, .5
        text: "MAIN"
        pos_hint: {'x':0, 'y': 0}
        on_release: app.root.current = "main_screen_name"
    Button:
        background_color: .52, .52, .52, 1
        bold: 1
        color: .0078,.67,.69,1
        font_size: 30
        size_hint: .2, .5
        text: "ROUTES"
        pos_hint: {'x':0, 'y': .5}
        on_release: app.root.current = "route_input_screen_name"  

    GridLayout:
        cols: 2
        pos: (205,150)
        size_hint: (.8, .75)

        Button:
            background_color: .52, .52, .52, 1
            bold: 1
            color: .0078,.67,.69,1
            font_size: 30
            text: "     TIRE\nTEMP (°C)"
            size_hint_x: None
            width: 150
        Button:
            background_color: .52, .52, .52, 1
            bold: 1
            color: .0078,.67,.69,1
            font_size: 100
            text: "000.000" # self.update_val.temp value it will be here

##############################################################
##############################################################

# Screen 3: Route Screen
# self.update_val.dist_travel_2 will be printed in this screen
<Route_Screen>:
    canvas:
        Color:
            rgb: [.30, .30, .30]
        Rectangle:
            pos: self.pos
            size: self.size

    Button:
        background_color: .52, .52, .52, 1
        bold: 1
        color: .0078,.67,.69,1
        font_size: 30
        size_hint: 0.2, .5
        text: "INPUTS"
        pos_hint: {'x':0, 'y': 0}
        on_release: app.root.current = "tire_setup_screen_name"

    BoxLayout:
        orientation: 'vertical'
        Button:
            background_color: .52, .52, .52, 1
            bold: 1
            color: .0078,.67,.69,1
            font_size: 50
            text: "000.000 MPH" # self.update_val.dist_travel_2 value 
            pos_hint: {'x': .2}
            size_hint: [.8, 1]

感谢您抽出宝贵时间,希望您能帮我解决这个问题。

如何从其他类中的一种方法访问变量?

【问题讨论】:

    标签: python kivy kivy-language


    【解决方案1】:

    使用 Kivy ObjectProperty 连接到屏幕 ID。详情请参考以下示例。

    片段

    Python 脚本

    class Screen_Management(ScreenManager):
        main_screen = ObjectProperty(None)
        input_screen = ObjectProperty(None)
        route_screen = ObjectProperty(None)
    
    ...
    
    class Main_Screen(Screen):
        update_val = Show_Val()
    
        def update(self, dt):
            # these corresponds to the screen 1, their are currently working
            self.update_val.timer_update += 1
            self.update_val.dist_travel += 1
            self.update_val.average_mph += 1
    
            # temp variable would be printed in screen 2: Input_Screen
            self.update_val.temp += 1
            self.manager.input_screen.access_update_val(self.update_val)
            self.manager.route_screen.access_update_val(self.update_val)
    
            # and dist_travel_2 will be printed in screen 3: Route_Screen
            self.update_val.dist_travel_2 += 1
    

    kv 文件

    <Screen_Management>:
        id: screen_management
        main_screen: main_screen
        input_screen: tire_setup_screen_id
        route_screen: route_screen
        transition: FadeTransition()
        Main_Screen:
            id: main_screen
            name: "main_screen_name"
            manager: screen_management
        Input_Screen:
            id: tire_setup_screen_id
            name: "tire_setup_screen_name"
            manager: screen_management
        Route_Screen:
            id: route_screen
            name: "route_input_screen_name"
    

    示例

    gui2.py

    ​​>
    from kivy.app import App
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.properties import ObjectProperty, NumericProperty
    from kivy.clock import Clock
    
    
    # Creating dynamic variables
    class Show_Val(Screen):
        timer_update = NumericProperty(0)
        dist_travel = NumericProperty(0)
        average_mph = NumericProperty(0)
        temp = NumericProperty(0)
        dist_travel_2 = NumericProperty(0)
    
    
    # screen 1: this is working ok
    class Main_Screen(Screen):
        update_val = Show_Val()
    
        def update(self, dt):
            # these corresponds to the screen 1, their are currently working
            self.update_val.timer_update += 1
            self.update_val.dist_travel += 1
            self.update_val.average_mph += 1
    
            # temp variable would be printed in screen 2: Input_Screen
            self.update_val.temp += 1
            self.manager.input_screen.access_update_val(self.update_val)
            self.manager.route_screen.access_update_val(self.update_val)
    
            # and dist_travel_2 will be printed in screen 3: Route_Screen
            self.update_val.dist_travel_2 += 1
    
    
    # screen 2: here I need to get access to self.update_val.temp
    class Input_Screen(Screen):
        def access_update_val(self, obj):
            print("Input_Screen: update_val.temp={}".format(obj.temp))
    
    
    # screen 3: here I need to get access to self.update_val.temp
    class Route_Screen(Screen):
        def access_update_val(self, obj):
            print("Route_Screen: update_val.temp={}".format(obj.temp))
    
    
    # screen 0 or master screen management, it's just for reference
    class Screen_Management(ScreenManager):
        main_screen = ObjectProperty(None)
        input_screen = ObjectProperty(None)
        route_screen = ObjectProperty(None)
    
    
    class gui2App(App):
        def build(self):
            sm = Screen_Management()
    
            # this call is my "loop" and is updating the variables at 50hz
            # frequency, I tried to call differently functions like this one
            # but with no success.
            Clock.schedule_interval(sm.main_screen.update, 1.0/50.0)
            return sm
    
    
    if __name__ == "__main__":
        gui2App().run()
    

    gui2.kv

    #:kivy 1.10.0
    #:import FadeTransition kivy.uix.screenmanager.FadeTransition
    
    <Screen_Management>:
        id: screen_management
        main_screen: main_screen
        input_screen: tire_setup_screen_id
        route_screen: route_screen
        transition: FadeTransition()
        Main_Screen:
            id: main_screen
            name: "main_screen_name"
            manager: screen_management
        Input_Screen:
            id: tire_setup_screen_id
            name: "tire_setup_screen_name"
            manager: screen_management
        Route_Screen:
            id: route_screen
            name: "route_input_screen_name"
    
    ##############################################################
    ##############################################################
    
    # Screen 1: Main Screen
    # working ok
    <Main_Screen>:
        canvas:
            Color:
                rgb: [.30, .30, .30]
            Rectangle:
                pos: self.pos
                size: self.size
    
        BoxLayout:
            orientation: 'vertical'
            Button:
                id: timer_indicator
                background_disabled_down: ('0.00.00,000')
                background_color: .52, .52, .52, 1
                bold: 1
                color: .0078,.67,.69,1
                font_size: 100
                text: str(root.update_val.timer_update)
                #text: root.update_val.test
                pos_hint: {'x': .2}
                size_hint: [.8, 1]
    
    
            Button:
                background_color: .52, .52, .52, 1
                bold: 1
                color: .0078,.67,.69,1
                font_size: 100
                text: str(root.update_val.dist_travel)
                pos_hint: {'x': .2}
                size_hint: [.8, 1]
            Button:
                background_color: .52, .52, .52, 1
                bold: 1
                color: .0078,.67,.69,1
                font_size: 100
                text: str(root.update_val.average_mph)
                pos_hint: {'x': .2}
                size_hint: [.8, 1]
    
        Button:
            background_color: .52, .52, .52, 1
            bold: 1
            color: .0078,.67,.69,1
            size_hint: .2, 1
            pos_hint: {"x": 0, "center_y": .5}
            on_release: app.root.current = "tire_setup_screen_name"
            text: " INPUTS "
            font_size: 30
    
    ##############################################################
    ##############################################################
    
    # Screen 2: Input Screen
    # I will need to print self.update_val.temp value in this creen
    
    <Input_Screen>:
        canvas:
            Color:
                rgb: [.30, .30, .30]
            Rectangle:
                pos: self.pos
                size: self.size
        Button:
            background_color: .52, .52, .52, 1
            bold: 1
            color: .0078,.67,.69,1
            font_size: 30
            size_hint: 0.2, .5
            text: "MAIN"
            pos_hint: {'x':0, 'y': 0}
            on_release: app.root.current = "main_screen_name"
        Button:
            background_color: .52, .52, .52, 1
            bold: 1
            color: .0078,.67,.69,1
            font_size: 30
            size_hint: .2, .5
            text: "ROUTES"
            pos_hint: {'x':0, 'y': .5}
            on_release: app.root.current = "route_input_screen_name"
    
        GridLayout:
            cols: 2
            pos: (205,150)
            size_hint: (.8, .75)
    
            Button:
                background_color: .52, .52, .52, 1
                bold: 1
                color: .0078,.67,.69,1
                font_size: 30
                text: "     TIRE\nTEMP (°C)"
                size_hint_x: None
                width: 150
            Button:
                background_color: .52, .52, .52, 1
                bold: 1
                color: .0078,.67,.69,1
                font_size: 100
                text: "000.000" # self.update_val.temp value it will be here
    
    ##############################################################
    ##############################################################
    
    # Screen 3: Route Screen
    # self.update_val.dist_travel_2 will be printed in this screen
    <Route_Screen>:
        canvas:
            Color:
                rgb: [.30, .30, .30]
            Rectangle:
                pos: self.pos
                size: self.size
    
        Button:
            background_color: .52, .52, .52, 1
            bold: 1
            color: .0078,.67,.69,1
            font_size: 30
            size_hint: 0.2, .5
            text: "INPUTS"
            pos_hint: {'x':0, 'y': 0}
            on_release: app.root.current = "tire_setup_screen_name"
    
        BoxLayout:
            orientation: 'vertical'
            Button:
                background_color: .52, .52, .52, 1
                bold: 1
                color: .0078,.67,.69,1
                font_size: 50
                text: "000.000 MPH" # self.update_val.dist_travel_2 value
                pos_hint: {'x': .2}
                size_hint: [.8, 1]
    

    输出

    【讨论】:

      猜你喜欢
      • 2014-10-10
      • 2015-01-21
      • 2021-09-30
      • 2021-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多