python tkinter在小部件之间传递数据帧

问题描述 投票:0回答:1

我的Python tkinter程序有几个小部件。在1个窗口小部件中创建的数据帧(例如PyDataTest1),其名称由用户选择,也应该在其他窗口小部件中可用。但是,如果小部件有另一个类,那似乎并非如此。我编写了3个python模块:PyDataTestMain,PyDataTest1和PyDataTest2。 PyDataTest2的代码是 - 保持示例简单 - 与PyDataTest1相同(我只用PyDataTest2替换了PyDataTest1)。如果我在小部件p1中保存数据帧,我可以在小部件p3中检索它,但不能在小部件p2和p4中检索它。我需要更改哪些也可以在那里使用它?

'''
    PyDataTestMain.py
'''

#%% Import libraries
import tkinter as tk
import tkinter.ttk as ttk
from PyDataTest1 import PyDataTest1
from PyDataTest2 import PyDataTest2

#%% Main class
class PyDataTestMain(ttk.Frame):
    def __init__(self, master = None):
        # Construct the Frame object.
        ttk.Frame.__init__(self, master)
        self.grid(sticky=tk.N+tk.S+tk.E+tk.W)
        self.createWidgets()

    #%% Create widgets
    def createWidgets(self):
        # Get top window 
        self.top = self.winfo_toplevel()

        # Make it stretchable         
        self.top.rowconfigure(0, weight=1)
        self.top.columnconfigure(0, weight=1)

        # Add several PyDataTest widgets
        self.p1 = PyDataTest1(self).grid(row = 0, column = 0, sticky = tk.W, padx =5, pady=5)
        self.p2 = PyDataTest2(self).grid(row = 1, column = 0, sticky = tk.W, padx =5, pady=5)
        self.p3 = PyDataTest1(self).grid(row = 2, column = 0, sticky = tk.W, padx =5, pady=5)
        self.p4 = PyDataTest2(self).grid(row = 3, column = 0, sticky = tk.W, padx =5, pady=5)

#%% Allow the class to run stand-alone.
if __name__ == "__main__":
    PyDataTestMain().mainloop()

'''
    PyDataTest1.py
'''

#%% Import libraries
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.messagebox as messagebox
import pandas as pd

#%% Main class
class PyDataTest1(ttk.Frame):
    def __init__(self, master = None):
        # Construct the Frame object.
        ttk.Frame.__init__(self, master)
        self.grid(sticky=tk.N+tk.S+tk.E+tk.W)
        self.createWidgets()

    def save(self):
        var = self.pythonVar.get()

        global glb
        glb = globals()
        glb[var] = pd.DataFrame({'AAA' : [1., 2., 3., 4.], 'BBB' : [43., 32., 21., 10.]})

        messagebox.showinfo("Info","pandas dataframe saved as " + var)

    def listVars(self):
        variables= [var for var in globals() if isinstance(eval(var), pd.core.frame.DataFrame)]
        self.comboboxDataframes['values'] = variables

    #%% Create widgets
    def createWidgets(self):
        # Get top window 
        self.top = self.winfo_toplevel()

        # Make it stretchable         
        self.top.rowconfigure(0, weight=1)
        self.top.columnconfigure(0, weight=1)

        # Allow to enter a name and save the data in the base workspace
        ttk.Label(self, text = "Variable").grid(row = 0, column = 0, sticky = tk.W, padx =5, pady=5)
        self.pythonVar = tk.StringVar()
        self.pythonVar.set('d')
        ttk.Entry(self, textvariable=self.pythonVar).grid(row = 0, column = 1, sticky = tk.W, padx =5, pady=5)
        # Save button
        ttk.Button(self, text = "Save", command=self.save).grid(row = 0, column = 2, sticky = tk.W, padx =5, pady=5)

        # Combobox showing dataframes stored
        ttk.Label(self, text = "Dataframes").grid(row = 1, column = 0, sticky = tk.W, padx =5, pady=5)
        self.comboboxDataframes = ttk.Combobox(self, postcommand=self.listVars)
        self.comboboxDataframes.grid(row = 1, column = 1, sticky = tk.W, padx =5, pady=5)    

#%% Allow the class to run stand-alone.
if __name__ == "__main__":
    PyDataTest1().mainloop()

我调整了代码并将所有内容放在一个文件中。

'''
    PyDataTestMain.py
'''

#%% Import libraries
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.messagebox as messagebox
import pandas as pd

#%% Main class
class PyDataTestMain(ttk.Frame):
    def __init__(self, master = None):
        # Construct the Frame object.
        ttk.Frame.__init__(self, master)
        self.grid(sticky=tk.N+tk.S+tk.E+tk.W)
        self.createWidgets()

    #%% Create widgets
    def createWidgets(self):
        # Get top window 
        self.top = self.winfo_toplevel()

        # Make it stretchable         
        self.top.rowconfigure(0, weight=1)
        self.top.columnconfigure(0, weight=1)

        # Add several PyDataTest widgets
        self.p1 = PyDataTest1(self)
        self.p1.grid(row = 0, column = 0, sticky = tk.W, padx =5, pady=5)

        self.p2 = PyDataTest2(self)
        self.p2.grid(row = 1, column = 0, sticky = tk.W, padx =5, pady=5)

        self.p3 = PyDataTest1(self)
        self.p3.grid(row = 2, column = 0, sticky = tk.W, padx =5, pady=5)

        self.p4 = PyDataTest2(self)
        self.p4.grid(row = 3, column = 0, sticky = tk.W, padx =5, pady=5)

class PyDataTest1(ttk.Frame):
    def __init__(self, master = None):
        # Construct the Frame object.
        ttk.Frame.__init__(self, master)
        self.grid(sticky=tk.N+tk.S+tk.E+tk.W)
        self.createWidgets()

    def save(self):
        var = self.pythonVar.get()

        #global glb
        #glb = globals()
        self.glb = {}
        self.glb[var] = pd.DataFrame({'AAA' : [1., 2., 3., 4.], 'BBB' : [43., 32., 21., 10.]})

        messagebox.showinfo("Info","pandas dataframe saved as " + var)

    def listVars(self):
        #variables= [var for var in globals() if isinstance(eval(var), pd.core.frame.DataFrame)]
        variables= [var for var in self.glb() if isinstance(eval(var), pd.core.frame.DataFrame)]
        self.comboboxDataframes['values'] = variables

    #%% Create widgets
    def createWidgets(self):
        # Get top window 
        self.top = self.winfo_toplevel()

        # Make it stretchable         
        self.top.rowconfigure(0, weight=1)
        self.top.columnconfigure(0, weight=1)

        # Allow to enter a name and save the data in the base workspace
        ttk.Label(self, text = "Variable").grid(row = 0, column = 0, sticky = tk.W, padx =5, pady=5)
        self.pythonVar = tk.StringVar()
        self.pythonVar.set('d')
        ttk.Entry(self, textvariable=self.pythonVar).grid(row = 0, column = 1, sticky = tk.W, padx =5, pady=5)
        # Save button
        ttk.Button(self, text = "Save", command=self.save).grid(row = 0, column = 2, sticky = tk.W, padx =5, pady=5)

        # Combobox showing dataframes stored
        ttk.Label(self, text = "Dataframes").grid(row = 1, column = 0, sticky = tk.W, padx =5, pady=5)
        self.comboboxDataframes = ttk.Combobox(self, postcommand=self.listVars)
        self.comboboxDataframes.grid(row = 1, column = 1, sticky = tk.W, padx =5, pady=5)    

class PyDataTest2(ttk.Frame):
    def __init__(self, master = None):
        # Construct the Frame object.
        ttk.Frame.__init__(self, master)
        self.grid(sticky=tk.N+tk.S+tk.E+tk.W)
        self.createWidgets()

    def save(self):
        var = self.pythonVar.get()

        #global glb
        #glb = globals()
        glb = {}
        glb[var] = pd.DataFrame({'AAA' : [1., 2., 3., 4.], 'BBB' : [43., 32., 21., 10.]})

        messagebox.showinfo("Info","pandas dataframe saved as " + var)

    def listVars(self):
        variables= [var for var in globals() if isinstance(eval(var), pd.core.frame.DataFrame)]
        self.comboboxDataframes['values'] = variables

    #%% Create widgets
    def createWidgets(self):
        # Get top window 
        self.top = self.winfo_toplevel()

        # Make it stretchable         
        self.top.rowconfigure(0, weight=1)
        self.top.columnconfigure(0, weight=1)

        # Allow to enter a name and save the data in the base workspace
        ttk.Label(self, text = "Variable").grid(row = 0, column = 0, sticky = tk.W, padx =5, pady=5)
        self.pythonVar = tk.StringVar()
        self.pythonVar.set('d')
        ttk.Entry(self, textvariable=self.pythonVar).grid(row = 0, column = 1, sticky = tk.W, padx =5, pady=5)
        # Save button
        ttk.Button(self, text = "Save", command=self.save).grid(row = 0, column = 2, sticky = tk.W, padx =5, pady=5)

        # Combobox showing dataframes stored
        ttk.Label(self, text = "Dataframes").grid(row = 1, column = 0, sticky = tk.W, padx =5, pady=5)
        self.comboboxDataframes = ttk.Combobox(self, postcommand=self.listVars)
        self.comboboxDataframes.grid(row = 1, column = 1, sticky = tk.W, padx =5, pady=5)    


#%% Allow the class to run stand-alone.
if __name__ == "__main__":
    PyDataTestMain().mainloop()
python tkinter parameter-passing
1个回答
0
投票

问题是你有模块中的代码,你使用globals()

globals()在模块内部提供全局变量,而不是在完整程序中。


在主文件中使用字典来保存数据 - 它可以是主类中的全局字典或字典

 self.all_dfs = {}

并将此字典作为参数发送给其他类

self.p1 = PyDataTest1(self, self.all_dfs)

self.p2 = PyDataTest2(self, self.all_dfs)

卖弄.朋友

import tkinter as tk
import tkinter.ttk as ttk
import tkinter.messagebox as messagebox
import pandas as pd
from PyDataTest1 import PyDataTest1
from PyDataTest2 import PyDataTest2

class PyDataTestMain(ttk.Frame):

    def __init__(self, master=None):
        # Construct the Frame object.
        ttk.Frame.__init__(self, master)
        self.grid(sticky=tk.N+tk.S+tk.E+tk.W)

        self.all_dfs = {
            # example dataframe at start
            #'a': pd.DataFrame(),
            #'b': pd.DataFrame(),
        }

        self.createWidgets()

    #%% Create widgets
    def createWidgets(self):
        # Get top window 
        self.top = self.winfo_toplevel()

        # Make it stretchable         
        self.top.rowconfigure(0, weight=1)
        self.top.columnconfigure(0, weight=1)

        # Add several PyDataTest widgets
        self.p1 = PyDataTest1(self, self.all_dfs)
        self.p1.grid(row=0, column=0, sticky=tk.W, padx=5, pady=5)

        self.p2 = PyDataTest2(self, self.all_dfs)
        self.p2.grid(row=1, column=0, sticky=tk.W, padx=5, pady=5)

        self.p3 = PyDataTest1(self, self.all_dfs)
        self.p3.grid(row=2, column=0, sticky=tk.W, padx=5, pady=5)

        self.p4 = PyDataTest2(self, self.all_dfs)
        self.p4.grid(row=3, column=0, sticky=tk.W, padx=5, pady=5)

#---

PyDataTestMain().mainloop()

py data test1.朋友

import tkinter as tk
import tkinter.ttk as ttk
import tkinter.messagebox as messagebox
import pandas as pd

class PyDataTest1(ttk.Frame):

    def __init__(self, master=None, dfs=None):
        # Construct the Frame object.
        ttk.Frame.__init__(self, master)
        self.grid(sticky=tk.N+tk.S+tk.E+tk.W)
        self.createWidgets()
        self.dfs = dfs
        if self.dfs is None:
            raise("Need DataFrames dictionary")

    def save(self):
        var = self.pythonVar.get()

        self.dfs[var] = pd.DataFrame({'AAA' : [1., 2., 3., 4.], 'BBB' : [43., 32., 21., 10.]})

        messagebox.showinfo("Info","pandas dataframe saved as " + var)

    def listVars(self):
        self.comboboxDataframes['values'] = list(self.dfs.keys())

    #%% Create widgets
    def createWidgets(self):
        # Get top window 
        self.top = self.winfo_toplevel()

        # Make it stretchable         
        self.top.rowconfigure(0, weight=1)
        self.top.columnconfigure(0, weight=1)

        # Allow to enter a name and save the data in the base workspace
        ttk.Label(self, text = "Variable").grid(row = 0, column = 0, sticky = tk.W, padx =5, pady=5)
        self.pythonVar = tk.StringVar()
        self.pythonVar.set('d')
        ttk.Entry(self, textvariable=self.pythonVar).grid(row = 0, column = 1, sticky = tk.W, padx =5, pady=5)
        # Save button
        ttk.Button(self, text = "Save", command=self.save).grid(row = 0, column = 2, sticky = tk.W, padx =5, pady=5)

        # Combobox showing dataframes stored
        ttk.Label(self, text = "Dataframes").grid(row = 1, column = 0, sticky = tk.W, padx =5, pady=5)
        self.comboboxDataframes = ttk.Combobox(self, postcommand=self.listVars)
        self.comboboxDataframes.grid(row=1, column=1, sticky=tk.W, padx=5, pady=5)    
© www.soinside.com 2019 - 2024. All rights reserved.