【问题标题】:How to display a dataframe in tkinter如何在 tkinter 中显示数据框
【发布时间】:2017-12-01 14:37:33
【问题描述】:

我是 Python 新手,甚至是 tkinter 新手。

我使用了来自 stackoverflow (Switch between two frames in 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()

当 Page_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])

我已经搜索过,例如How to display a pandas dataframe in a tkinter window (tk frame to be precise)(未提供答案)和其他网站寻求类似问题的答案,但没有成功。

当我选择 Page_2 时,我将如何以及在何处放置我的数据框代码选择以显示在我想要的区域中?

【问题讨论】:

    标签: python-3.x dataframe tkinter


    【解决方案1】:

    查看pandastable。 这是一个非常漂亮的库,用于显示和处理 pandas 表。

    这是一个代码示例from their documentation

    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()
    

    这里是截图(也是from their docs):

    【讨论】:

      【解决方案2】:

      首先,您可以查看 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 将其打印到您选择的“显示”小部件。

      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 表示;自定义文本留作练习。

      【讨论】:

      • @皮尔保罗。谢谢您的建议。这已添加到我的数据框中。是否可以设置它以便用户可以编辑?
      • @bagpuss:一般来说,是的。但是您必须对此更具体:用户应该做什么?他们应该选择要加载的数据框,还是应该选择要显示的列/行,还是完全其他?
      • @皮尔保罗。我不希望用户具有任何编辑功能,例如无法更改要加载的数据框,无法更改数据框内容,无法格式化数据框 - 完全锁定显示的数据框。显示框架时,它应该显示该特定选项的数据框(基于我的编码),因此无需更改它。
      • @bagpuss:我编辑了我的答案。请让我知道我是否理解您的要求。
      • @Pier Paolo:感谢链接并感谢所有建议。
      猜你喜欢
      • 2015-09-12
      • 2016-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多