I am having an issue of finding the bug in my code in relation to the folder path using filedialog. I have the following code
import tkinter import tkinter.ttk from tkinter import filedialog from tkinter import * global user_input def create_widgets_in_first_frame(): # Create the label for the frame first_window_label = tkinter.ttk.Label(first_frame, text='Window 1') first_window_label.grid(column=0, row=0, pady=10, padx=10, sticky=(tkinter.N)) folder_path = StringVar() # Create the button for the frame first_window_quit_button = tkinter.Button(first_frame, text = "Quit", command = quit_program) first_window_quit_button.grid(column=1, row=1, pady=10, sticky=(tkinter.N)) #var = IntVar() entry1 = tkinter.Entry(first_frame) entry1.grid(column=0, row=1, pady=10,sticky=(tkinter.N)) user_input = entry1.get() first_window_diffbutton = tkinter.Button(first_frame, text="Price difference",command=avgprice) first_window_diffbutton.grid(column=2, row=1, pady=10,sticky=(tkinter.N)) def browse_button(): # Allow user to select a directory and store it in global var # called folder_path global folder_path filename = filedialog.askdirectory() folder_path.set(filename) return filename def call_first_frame_on_top(): # This function can be called only from the second window. # Hide the second window and show the first window. second_frame.grid_forget() first_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E)) def quit_program(): root_window.destroy() def avgprice(): path1=browse_button() size=user_input import pandas as pd from pathlib import Path import glob import os import matplotlib.pyplot as plt import numpy as np import csv path = Path(path1) filenames = glob.glob(path1 + "/*.csv") %matplotlib inline for filename in filenames: headers = ['time', 'size', 'price', 'type'] dtypes = {'time': 'str', 'size': 'float', 'price': 'float','type': 'str'} parse_dates = ['time'] parse_dates = ['time'] btcnow = pd.read_csv(filename, header=None, names=headers, dtype=dtypes, parse_dates=parse_dates) now3 = pd.DataFrame(btcnow, columns=['size','time','unix','price']) now4=now3[['time','price','size']] df6= now4.loc[now4["size"] == size,'size'] df7= now4.loc[now4["size"] == size, "time"] df8= now4.loc[now4["size"] == size, "price"] result1= [df6,df7,df8] result1 = pd.concat(result1, axis=1, sort=True) result1.columns = ['size','orig_time','price'] df10=result1.groupby('orig_time').last().reset_index() df10 = df10[['size','orig_time','price']] from datetime import datetime, timedelta time_interval = timedelta(minutes = 5) df = now3[[ 'time', 'size', 'price']] # extract time size for merge df_time_size=df.loc[:, ['time', 'size']].copy() df_time_size.loc[:, 'time'] = df_time_size.loc[:, 'time'] + time_interval # inner join dataframe by size&time df = df_time_size.merge(df[['time', 'size', 'price']], how = 'inner') df['orig_time'] = df['time'] - time_interval df=df.groupby('time').last().reset_index() df1= df.loc[df["size"] == size, "price"] df2= df.loc[df["size"] == size, "time"] df3= df.loc[df["size"] == size, "size"] df4=df.loc[df["size"] == size, "orig_time"] frames = [df3,df1,df2,df4] result = pd.concat(frames, axis=1, sort=True) a=pd.merge(result,df10, on="orig_time") b=a[['size_x' ,'price_x','time','orig_time','price_y']].copy() b.rename(columns = {'size_x':'size' ,'price_x':'price','time':'time','orig_time':'orig_time','price_y':'orig_price'}, inplace = True) b['diff']=abs(b['price']-b['orig_price']) list1=[] list1=(b['diff']) print('size', size, list1) ############################### # Main program starts here :) # ############################### # Create the root GUI window. root_window = tkinter.Tk() # Define window size window_width = 200 window_heigth = 100 # Create frames inside the root window to hold other GUI elements. All frames must be created in the main program, otherwise they are not accessible in functions. first_frame=tkinter.ttk.Frame(root_window, width=window_width, height=window_heigth) first_frame['borderwidth'] = 2 first_frame['relief'] = 'sunken' first_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E)) # Create all widgets to all frames create_widgets_in_first_frame() # Hide all frames in reverse order, but leave first frame visible (unhidden). # Start tkinter event - loop root_window.mainloop()
The following error shows up:
Exception in Tkinter callback Traceback (most recent call last): File "C:UsersNatalieAnaconda3libtkinter__init__.py", line 1705, in __call__ return self.func(*args) File "<ipython-input-8-e64cca04b689>", line 42, in avgprice path1=browse_button() File "<ipython-input-8-e64cca04b689>", line 27, in browse_button folder_path.set(filename) NameError: name 'folder_path' is not defined
Advertisement
Answer
To use
folder_path.set(...)
you have to first create
folder_path = StringVar()
global
doesn’t create variable but it is only used in function to inform this function to use external/global variable when you use =
to assign value (instead of creating local variable).
The same problem you will have with user_input
.
So you could create variables at start
root_window = tkinter.Tk() user_input = '' # it creates global variable folder_path = StringVar() # it creates global variable
and it resolves problem with these variables
EDIT: I found that you use folder_path = StringVar()
in create_widgets_in_first_frame
but it create local variable. You have to uses global
to inform function to assign StringVar()
to external/glboal variable
def create_widgets_in_first_frame(): global folder_path # inform function to assign value (`=`) to external variable `folder_path` folder_path = StringVar()
and then it will create global folder_path
and you don’t have to create it at start.