You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Kivy开发:如何跨类访问全局变量?飞行计算APP遇阻

解决Kivy跨Screen传递数据的问题

刚上手Kivy和面向对象编程时,遇到不同Screen之间无法共享变量的问题太常见了。你尝试的全局变量方案容易踩作用域的坑,而且不是最佳实践,我给你几个更可靠的方案:

方案1:通过ScreenManager获取其他Screen实例直接访问属性

这个方法最简单,适合你的场景:

步骤1:在输入Screen中把计算结果存为实例属性

修改Takeoff_3Window的TO_4Btn方法,把计算好的HWC1和XWC1存在当前Screen的实例里,而不是全局变量:

def TO_4Btn(self, math):
    # 先调用校验方法,注意这里要调用方法,不是判断函数对象
    is_valid = self.advance_TO3()
    if is_valid:
        # 从控件获取输入值(确保先转成数值类型)
        rwy_val = float(self.rwy1.text)
        wd_val = float(self.wd1.text)
        wv_val = float(self.wv1.text)
        
        angle_diff = abs(rwy_val - wd_val)
        # 把结果存为当前Screen的实例属性
        self.HWC1 = round((wv_val * math.cos(math.radians(angle_diff))), 1)
        self.XWC1 = round((wv_val * math.sin(math.radians(angle_diff))), 1)
        
        self.manager.current = "TakeoffResult"  # 这里要对应你在ScreenManager里给结果Screen起的名字
    else:
        pass

步骤2:在结果Screen中获取输入Screen的实例并读取属性

修改Takeoff_ResultWindow的TOR_Page1方法,通过self.manager.get_screen()拿到输入Screen的实例,直接读取里面的属性:

def TOR_Page1(self):
    # 获取输入Screen的实例(参数是你在ScreenManager中注册的该Screen的name)
    takeoff_input_screen = self.manager.get_screen("Takeoff_3Window")
    
    # 读取计算好的结果
    hwc_val = takeoff_input_screen.HWC1
    xwc_val = takeoff_input_screen.XWC1
    
    # 赋值给Label
    self.tor_hwc.text = f"Wind (HWC): {hwc_val}"
    self.tor_xwc.text = f"Wind (XWC): {xwc_val}"
    
    # 其他变量同理,比如从对应的输入Screen中读取(比如TOM、Elevation1等)
    # 假设这些值也存在对应的Screen实例属性里
    self.tor_tom.text = f"TOM: {takeoff_input_screen.TOM}"
    # ... 其他Label赋值

方案2:创建共享数据类(更规范的长期方案)

如果你的应用后续会有更多Screen需要共享数据,推荐用一个专门的类来存储所有共享数据:

步骤1:定义共享数据类

class FlightData:
    def __init__(self):
        # 初始化所有需要共享的变量
        self.HWC1 = 0.0
        self.XWC1 = 0.0
        self.TOM = 0.0
        self.Elevation1 = 0.0
        self.QNH_1 = 0.0
        # ... 其他需要共享的变量

步骤2:在App类中初始化数据实例并传递给所有Screen

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager

class FlightPlanningApp(App):
    def build(self):
        # 创建共享数据实例
        self.flight_data = FlightData()
        
        sm = ScreenManager()
        # 添加Screen时把数据实例传递过去
        sm.add_widget(Takeoff_3Window(name="Takeoff_3Window", flight_data=self.flight_data))
        sm.add_widget(Takeoff_ResultWindow(name="TakeoffResult", flight_data=self.flight_data))
        # ... 添加其他Screen
        
        return sm

步骤3:在每个Screen中接收并使用共享数据

修改Takeoff_3Window的初始化和计算方法:

class Takeoff_3Window(Screen):
    rwy1 = ObjectProperty(None)
    wd1 = ObjectProperty(None)
    wv1 = ObjectProperty(None)
    
    def __init__(self, flight_data, **kwargs):
        super().__init__(**kwargs)
        self.flight_data = flight_data  # 保存共享数据实例
    
    def TO_4Btn(self, math):
        is_valid = self.advance_TO3()
        if is_valid:
            rwy_val = float(self.rwy1.text)
            wd_val = float(self.wd1.text)
            wv_val = float(self.wv1.text)
            
            angle_diff = abs(rwy_val - wd_val)
            # 把结果存到共享数据类里
            self.flight_data.HWC1 = round((wv_val * math.cos(math.radians(angle_diff))), 1)
            self.flight_data.XWC1 = round((wv_val * math.sin(math.radians(angle_diff))), 1)
            # 其他输入数据也存到共享类里
            self.flight_data.TOM = ...  # 从对应控件获取值
            
            self.manager.current = "TakeoffResult"

修改Takeoff_ResultWindow的初始化和展示方法:

class Takeoff_ResultWindow(Screen):
    tor_tom = ObjectProperty(None)
    tor_cog = ObjectProperty(None)
    tor_hwc = ObjectProperty(None)
    tor_xwc = ObjectProperty(None)
    # ... 其他控件
    
    def __init__(self, flight_data, **kwargs):
        super().__init__(**kwargs)
        self.flight_data = flight_data
    
    def TOR_Page1(self):
        # 直接从共享数据类读取值
        self.tor_hwc.text = f"Wind (HWC): {self.flight_data.HWC1}"
        self.tor_xwc.text = f"Wind (XWC): {self.flight_data.XWC1}"
        self.tor_tom.text = f"TOM: {self.flight_data.TOM}"
        # ... 其他Label赋值

对你原有代码的小提示

你之前的代码里有个小错误:if advance_TO3 is True:这里,advance_TO3是函数对象,应该改成调用方法if self.advance_TO3()(假设advance_TO3方法返回布尔值表示校验是否通过)。

全局变量方案失效大概率是因为作用域问题——比如在Takeoff_ResultWindow里没有正确导入这些全局变量,或者赋值时没有正确声明global(比如在TO_4Btn里虽然写了global HWC1, XWC1,但如果HWC1之前没定义过,可能会有问题)。不过还是推荐上面的两种方案,代码更清晰也更易维护。

内容的提问来源于stack exchange,提问作者Matt S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:26:14