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

Tkinter多页面框架中读取控制器类共享变量为空是什么原因?

问题根因
  • 所有页面实例是在AppMain初始化阶段就批量创建完成的,PageOne的__init__方法会在程序启动时立刻执行,此时你还没有上传解析XML,shared_data['tc']就是初始化的空列表,你看到的空打印是程序启动时的输出,不是跳转页面时的输出。
  • 你后续上传文件修改shared_data后调用show_frame切换页面,只是把已经创建好的PageOne实例放到顶层显示,不会重新执行__init__方法,自然不会读取到最新的共享变量值。
  • 额外注意:你当前代码中解析XML时只传了文件名,若选择的XML文件不在当前工作目录下会触发FileNotFoundError,建议直接使用选择的完整路径。
修复方案
  1. 把PageOne中读取共享变量的逻辑从__init__中拆分出来,做成独立的刷新方法
  2. 修改AppMain的show_frame方法,切换到对应页面时主动调用刷新方法,读取最新的共享变量
  3. 修复XML路径读取的错误
修改后可运行代码
import os, easygui
import xml.etree.ElementTree as ET
import tkinter as tk

LARGE_FONT = ("Verdana", 12)


class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

    # 新增刷新方法,每次切换到该页面时调用
    def update_view(self):
        print("Second TC:", self.controller.shared_data['tc'])
        for i in self.controller.shared_data['tc']:
            print("****: ", i)
            print("Name:", i['Name'], "Id:", i['Id'])


class StartPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

        label = tk.Label(self, text='File Upload: Press the button to open the XML file.', font=LARGE_FONT)
        label.place(relx=.01, rely=.01)

        # Function to separate the tc "Child_4" inside the xml file
        def separate_tc(xml_name):
            file_xml = ET.parse(xml_name)
            # Get the name and id attributes that the Child_4 tag contains
            self.controller.shared_data['tc'] = [
                {"Name": signal.attrib["Name"],
                 "Id": signal.attrib["Id"],
                 } for signal in file_xml.findall(".//Child_4")
            ]
            print('First TC:', self.controller.shared_data['tc'])
            controller.show_frame("PageOne")

        # Function to open xml file
        def open_file():
            try:
                xml_name = easygui.fileopenbox(title='Select XML file', default='*.xml')
                if not xml_name: # 处理用户点击取消的情况
                    return
                separate_tc(xml_name) # 直接传完整路径,不需要转basename
            except FileNotFoundError:
                print('XML file was not loaded.')

        button_open = tk.Button(self, text="Open File XML", command=open_file)
        button_open.place(relx=.01, rely=.05)


class AppMain(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        tk.Tk.wm_title(self, 'Analysis of a XML')

        self.shared_data = {'tc': []}

        container = tk.Frame(self)
        container.pack(side='top', fill='both', expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        for F in (StartPage, PageOne):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame("StartPage")

    def show_frame(self, page_name):
        '''Show a frame for the given page name'''
        frame = self.frames[page_name]
        # 新增逻辑:如果页面有update_view方法就调用,刷新最新数据
        if hasattr(frame, 'update_view'):
            frame.update_view()
        frame.tkraise()


if __name__ == "__main__":
    app = AppMain(None)
    app.title('Analysis of XML')
    app.geometry("1024x920")
    app.mainloop()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:15:02