Reputation: 1412
I am trying to write a simple GUI to plot data from a csv
file, which I read into a pandas DataFrame
. I am completely new to GUI programming, and I am having a hard time getting my head around event-driven setups like Tkinter.
As a simple exercise, I want to set up a couple of buttons, one to open a file and read in the DataFrame
, and another to print out the resulting DataFrame
. My first naive attempt didn't work:
import pandas as pd
import tkFileDialog
import Tkinter as tk
def open_events_db():
file_path_string = tkFileDialog.askopenfilename()
eventsdb = pd.read_csv(file_path_string,encoding='utf-8')
return eventsdb
def print_events_db(eventsdb):
print eventsdb
def main():
root=tk.Tk()
eventsdb = tk.Button(text='File Open', command=open_events_db).pack(fill=tk.X)
tk.Button(text='Print DB', command=lambda:print_events_db(eventsdb)).pack(fill=tk.X)
tk.mainloop()
if __name__=="__main__":
main()
I can read in the file fine, and open it, but in hindsight obviously I can't return eventsdb
from the file open button and have it as an argument to the print button.
I don't think it's unreasonable to have buttons that operate on that DB, though, so what is the proper way to pass variables around within the GUI?
Upvotes: 2
Views: 4916
Reputation: 385970
Functions called from buttons and event handers don't return their data. Instead, they must set global variables or class attributes.
def open_events_db():
global eventsdb
file_path_string = tkFileDialog.askopenfilename()
eventsdb = pd.read_csv(file_path_string,encoding='utf-8')
def print_events_db():
global eventsdb
print eventsdb
...
tk.Button(text='Print DB', command=print_events_db).pack(fill=tk.X)
It's generally considered poor programming to rely on global variables. Since python is an object oriented language, it makes sense to write your app as a class. You would then use instance attributes rather than global variables.
import Tkinter as tk
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
open_button = tk.Button(text='File Open', command=self.open_events_db)
print_button = tk.Button(text='Print DB', command=self.print_events_db)
open_button.pack(fill=tk.X)
print_button.pack(fill=tk.X)
def open_events_db(self):
file_path_string = tkFileDialog.askopenfilename()
self.eventsdb = pd.read_csv(file_path_string,encoding='utf-8')
def print_events_db():
print self.eventsdb
def main():
root=tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
if __name__=="__main__":
main()
Upvotes: 5