Reputation: 344
I currently have the below script that reads an imported csv file and displays as pandastable
in the tkinter
GUI.
As the file is imported its adds x2 additional columns self.table.addColumn("Current Status")
and self.table.addColumn("Assign Technician")
.
How can I store the updated pandastable dataframe
into a variable outside of class TestApp(tk.Frame):
so that I can call other functions on the dataframe
later in my code?
I have used the global
variable before so that I can call a variable
created from within a function outside of it later but not sure if thats what I need for this purpose.
import csv
import tkinter as tk
import tkinter.ttk as tkrttk
from tkinter import *
from tkinter import filedialog
import pandas as pd
from pandastable import Table, TableModel
root = tk.Tk()
root.geometry("2000x1000")
root.title('Workshop Manager')
def select_input_file():
global input_file_path
input_file_path = filedialog.askopenfilename(
filetypes=(("CSV files", "*.csv"),))
app = TestApp(root, input_file_path)
app.place(bordermode = INSIDE,height = 500, width = 2000, x =0, y=50)
class TestApp(tk.Frame):
def __init__(self, parent, input_file_path, editable = True, enable_menus = True):
super().__init__(parent)
self.table = Table(self, showtoolbar=False, showstatusbar=False)
self.table.importCSV(input_file_path)
self.table.show(input_file_path)
self.table.addColumn('Current Status')
self.table.addColumn('Assign Technician')
self.table.autoResizeColumns()
root.mainloop()
Upvotes: 1
Views: 507
Reputation: 11171
Avoid global
to achieve this.
Currently, all your stateful variables exist in the module (file). You can do the same for your table, outside of TestApp
, and then pass it though __init__
:
import csv
import tkinter as tk
import tkinter.ttk as tkrttk
from tkinter import *
from tkinter import filedialog
import pandas as pd
from pandastable import Table, TableModel
table = Table(showtoolbar=False, showstatusbar=False)
root = tk.Tk()
root.geometry("2000x1000")
root.title('Workshop Manager')
def select_input_file():
global input_file_path
input_file_path = filedialog.askopenfilename(
filetypes=(("CSV files", "*.csv"),))
app = TestApp(root, input_file_path)
app.place(bordermode = INSIDE,height = 500, width = 2000, x =0, y=50)
class TestApp(tk.Frame):
def __init__(self, parent, input_file_path, editable = True, enable_menus = True, table=table):
super().__init__(parent)
self.table = table
self.table.importCSV(input_file_path)
self.table.show(input_file_path)
self.table.addColumn('Current Status')
self.table.addColumn('Assign Technician')
self.table.autoResizeColumns()
root.mainloop()
Your table object is now accessible to anything that can see the module namespace. Here table
is a mutable object, and all changes will be reflected to any function that accesses that object.
One suggestion: it is preferable to separate out your definitions (classes, functions) from your stateful bits that are created at run time. This will greatly help clarify dependencies. It is typical to use the line if __name__ == "__main__":
at the bottom of the file to start the "script" part of your app, keeping all definitions above. I've seen some packages (looking at you, Flask!) break this convention a bit, and it can cause headaches.
On that note, your select_input_file
function has a few issues. There's no good reason to create an app instance there. A better option would be to make this a method in the App
class for example.
Upvotes: 0
Reputation: 10192
You don't necessarily need a global
variable here. You can directly access the member attributes of a class by using the object itself. So in this case, you can access the table
attr of the class TestApp
using app.table
, which would look something like this,
def select_input_file():
#...
app = TestApp(root, input_file_path)
app.place(bordermode = INSIDE,height = 500, width = 2000, x =0, y=50)
df = app.table # contains the updated table which can be passed to other functions
newFunc( df ) # sample call
Upvotes: 1