通过Tkinter类传递数据帧 [英] Pass data frame through Tkinter classes

查看:98
本文介绍了通过Tkinter类传递数据帧的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Python 2.7和Tkinter.我几乎是面向对象程序的新手.我有一个带有许多Tkinter窗口的长程序,有时我要求用户加载用Pandas读取的Excel文件,并希望永久使用和更新该值( data 变量) .我现在的操作方式是使用全局变量,但是我知道它很危险,效率低下而且根本不够优雅.

I am using Python 2.7 and Tkinter. I am almost new to Object Oriented programs. I have a long program with many Tkinter windows and at some point I ask the user to load an Excel file that I read with Pandas, and want to permanently use and update that value (of a data variable). The way that I am doing it now is with global variables but I know that it is dangerous, inefficient and not elegant at all.

即使我可以按照我的gui类的构建方式执行controller.show_frame(framename),但我最终还是自己构建了一些框架,以使数据变量能够自我更新.

Even though I could do controller.show_frame(framename) given the way my gui class is built, I ended up building some of the frames myself just so the data variable would update itself.

我阅读并尝试了Stack Overflow中的一些答案,但可能将其实现错误:

I read and tried some answers in Stack Overflow but may have implemented them wrong:

  • 试图在gui类中创建一个字典,类似于self.app_data = {data=[],filename=""}并从其他窗口更新它,这是因为我认为该类gui仅实例化一次,并且可以创建所有其他窗口类所以这没有用.也许我在那儿做错了. (代码中未显示).
  • 尝试按照建议的方式进行操作此处,但我无法使其正常运行.
  • Tried creating a dictionary inside the gui class, something like self.app_data = {data=[],filename=""} and updating it from other windows, the thing here is that I think that the class gui is instanced only once and it kind of creates all of the other window classes so this did not work. Maybe I did something wrong there. (not shown on the code).
  • Tried to do something as what was suggested here but I could just not make it work.

主机是我需要用于其他目的的某种中间步骤;以下代码是我的程序的简化.

Main frame is some sort of intermediate step that I need for other purposes; the following code is a simplification of my program.

我知道这是可怕的噩梦代码!谢谢:)

I know this is an awful nightmare code! Thank you :)

import Tkinter as tk
import pandas as pd 
import tkFileDialog
import tkMessageBox
global data, strat_columns, filename
data = pd.DataFrame([])
strat_columns = []
filename = ""

class gui(tk.Tk):

    data = pd.DataFrame([])
    filename = ""
    def __init__(self):
        tk.Tk.__init__(self)
        container = tk.Frame(self)
        container.pack(side="top",fill="both",expand=True)
        self.frames = {}

        for F in (main_frame, first_frame):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")
        self.show_frame(main_frame)

    def show_frame(self,sel_frame):
        frame = self.frames[sel_frame]
        frame.tkraise()

    def get_page(self, page_class):
        return self.frames[page_class]


class main_frame(tk.Frame):

    def __init__(self,parent,controller):

        tk.Frame.__init__(self,parent)
        self.parent = parent 
        self.controller = controller
        button_new = tk.Button(self,
                           text="New window",
                           command=lambda: self.button_new_callback())
        button_new.pack()

    def button_new_callback(self,*args,**kwargs):
        self.controller.show_frame(first_frame)


class first_frame(tk.Frame):

    def __init__(self,parent,controller):
        tk.Frame.__init__(self,parent)
        self.controller = controller
        self.parent = parent
        self.show_frame = controller.show_frame
        statusText.set("Press Browse button and browse for file, then press the Go button")
        label = tk.Label(self, text="Please load a file: ")
        label.pack()
        entry = tk.Entry(self, width=50)
        entry.pack()
        button_go = tk.Button(self,
                           text="Go",
                           command=lambda: self.button_go_callback(entry,statusText,message))
        button_browse = tk.Button(self,
                               text="Browse",
                               command=lambda: self.button_browse_callback(entry))
        button_go.pack()
        button_browse.pack()
        message = tk.Label(self, textvariable=statusText)
        message.pack()

    def button_browse_callback(self,entry):
        global filename
        filename = tkFileDialog.askopenfilename()
        entry.delete(0, tk.END)
        entry.insert(0, filename)

    def button_go_callback(self,entry,statusText,message):
        global data
        input_file = entry.get()
        data = pd.read_excel(filename)
        sf = second_frame(self.parent, self)
        sf.grid(row=0, column=0, sticky="nsew")
        sf.tkraise()

class second_frame(tk.Frame):
     pass

if __name__ == "__main__":

    my_gui = gui()
    my_gui.mainloop()
    my_gui.title("TEST")

在我看来,

推荐答案

您正在过多地使用数据和GUI.如果将来您想要显示其他内容怎么办?我将使用一种更通用的方法:我将创建一个DataProvider类,该类将为您读取并返回数据:

in my opinion your are tying too much the data and the GUI. What if in the future you want to display something else? I would use a more generic approach: I would a create a DataProvider class that would read and return the data for you:

数据提供者

import pandas as pd

    class DataProvider(object):

        def __init__(self):
            self._excel = {}
            self._binary = {}

        def readExcel(self, filename):
            self._excel[filename] = pd.read_excel(filename)

        def excel(self):
            return self._excel

        def readBinary(self, filename):
            self._binary[filename] = open(filename,"rb").read()

        def binary(self):
            return self._binary

使用此类,您可以获得在GUI中显示的数据:

Using this class you can obtain the data that you can present in your GUI:

gui.py

from Tkinter import *
from DataProvider import *
import binascii

#example data
dp = DataProvider()
dp.readExcel("file.xlsx")
dp.readBinary("img.png")


root = Tk()
frame = Frame(root)
frame.pack()

bottomframe = Frame(root)
bottomframe.pack( side = BOTTOM )

w = Label(bottomframe, text=dp.excel()["file.xlsx"])
w.pack()


w = Label(bottomframe, text=binascii.hexlify(dp.binary()["img.png"][:5]))
w.pack()

root.mainloop()

如果一切正常,则应该有一个小的GUI,显示Excel文件的内容和图像的前几个字节.

If all works well you should have a small GUI showing the content of the Excel file and the first few bytes of the image.

让我知道是否一切正常,或者您需要更多信息.

Let me know if all works fine or if you need more info.

谢谢

这篇关于通过Tkinter类传递数据帧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆