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.
 
						