如何在tkinter中显示数据帧

7

我对Python和tkinter都很陌生。

我利用了stackoverflow网站上的代码(在tkinter中切换两个框架),创建了一个程序,根据用户选择的选项调用并叠放新的框架。下面是我简化后的代码,实际上还有很多框架。

import tkinter as tk                
from tkinter import font  as tkfont 
import pandas as pd

class My_GUI(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")


        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, Page_2):
            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]
        frame.tkraise()

class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="Welcome to....", font=controller.title_font)
        label.pack(side="top", fill="x", pady=10)

        button1 = tk.Button(self, text="Option selected",
                            command=lambda: controller.show_frame("Page_2"))
        button1.pack()



class Page_2(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="The payment options are displayed below", font=controller.title_font)
        label.pack(side="top", fill="x", pady=10)

        #I want the able to be display the dataframe here

        button = tk.Button(self, text="Restart",
                           command=lambda: controller.show_frame("StartPage"))
        button.pack()

a = {'Option_1':[150,82.50,150,157.50,78.75],
     'Option2':[245,134.75,245,257.25,128.63]}
df = pd.DataFrame(a,index=['a',
                    'b',
                    'c',
                    'd',
                    'e']) 

print(df.iloc[:6,1:2])

if __name__ == "__main__":
    app = My_GUI()
    app.mainloop()

当页面2出现时,我希望它显示下面的代码所示的数据框。
a = {'Option_1':[150,82.50,150,157.50,78.75],
     'Option2':[245,134.75,245,257.25,128.63]}
df = pd.DataFrame(a,index=['a',
                    'b',
                    'c',
                    'd',
                    'e']) 

print(df.iloc[:6,1:2])

我已经在Stack Overflow(例如如何在tkinter窗口(确切地说是tk框架)中显示pandas dataframe,但没有提供答案)和其他网站上搜索了类似问题的答案,但没有成功。

当我选择Page_2时,我应该在哪里放置我的数据框代码以出现在我想要的区域?

2个回答

17

请查看 pandastable,它是一个非常不错的库,可用于显示和处理Pandas表格。

这里是一个代码示例,来自他们的文档

from tkinter import *
from pandastable import Table, TableModel

class TestApp(Frame):
        """Basic test frame for the table"""
        def __init__(self, parent=None):
            self.parent = parent
            Frame.__init__(self)
            self.main = self.master
            self.main.geometry('600x400+200+100')
            self.main.title('Table app')
            f = Frame(self.main)
            f.pack(fill=BOTH,expand=1)
            df = TableModel.getSampleData()
            self.table = pt = Table(f, dataframe=df,
                                    showtoolbar=True, showstatusbar=True)
            pt.show()
            return

app = TestApp()
#launch the app
app.mainloop()

这里有一个屏幕截图 (也来自他们的文档):

pandastable文档中的截图


5
作为一个开始,您可以查看LabelText小部件,这些小部件通常用于在GUI中显示文本。
您可以尝试以下内容:
class Page_2(tk.Frame):
    def __init__(self, parent, controller):
        # ... your code ...
        global df # quick and dirty way to access `df`, think about making it an attribute or creating a function that returns it
        text = tk.Text(self)
        text.insert(tk.END, str(df.iloc[:6,1:2]))
        text.pack()
        # lbl = tk.Label(self, text=str(df.iloc[:6,1:2])) # other option
        # lbl.pack()                                      #

最终,问题的关键在于您想要多么华丽:小部件是高度可定制的,因此您可以实现非常令人满意的外观,而不仅仅是此示例的基本外观。
编辑: 我添加了一个Combobox小部件来选择要显示的选项和一个Button,将其打印到您选择的“display”小部件中。
from tkinter import ttk # necessary for the Combobox widget

# ... your code ...

class Page_2(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="The payment options are displayed below", font=controller.title_font)
        label.pack(side="top", fill="x", pady=10)

        global df
        tk.Label(self, text='Select option:').pack()
        self.options = ttk.Combobox(self, values=list(df.columns))
        self.options.pack()
        tk.Button(self, text='Show option', command=self.show_option).pack()

        self.text = tk.Text(self)
        self.text.pack()

        tk.Button(self, text="Restart",
                  command=lambda: controller.show_frame("StartPage")).pack()

    def show_option(self):
        identifier = self.options.get() # get option
        self.text.delete(1.0, tk.END)   # empty widget to print new text
        self.text.insert(tk.END, str(df[identifier]))

显示的文本是数据框列的默认string表现形式;自定义文本留作练习。

@ Pier Paolo。谢谢您的建议。已经添加到我的数据框中了。是否可以设置让用户进行编辑? - bagpuss
@bagpuss:一般来说,是的。但你需要更具体地说明:用户应该做什么?他们应该选择加载哪个数据框,还是选择显示哪些列/行,或者完全是其他事情? - Pier Paolo
@ Pier Paolo。我不希望用户具有任何编辑功能,例如无法更改要加载的数据框,无法更改数据框内容,无法格式化数据框-完全锁定显示的数据框。当该框架显示时,它应显示该特定选项的数据框(基于我的编码),因此无需更改它。 - bagpuss
@bagpuss:看一下这里(http://www.tkdocs.com/tutorial/text.html)和这里(http://effbot.org/tkinterbook/entry.htm)。 - Pier Paolo
2
@ Pier Paolo:感谢您提供的链接和所有建议。 - bagpuss
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接