Skip to content
Advertisement

Issue with folder path in tkinter (python)

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.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement