【问题标题】:Issue with folder path in tkinter (python)tkinter(python)中的文件夹路径问题
【发布时间】:2020-01-09 21:47:25
【问题描述】:

我在使用 filedialog 在我的代码中查找与文件夹路径相关的错误时遇到问题。 我有以下代码

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()

出现以下错误:

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Natalie\Anaconda3\lib\tkinter\__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

【问题讨论】:

  • 您在开始时没有定义folder_path,因此当您尝试在browse_button() 中使用它时它可能不存在 - 特别是您使用set() 这可能意味着您需要StringVar()
  • 移动 global folder_path def create_widgets_in_first_frame():。阅读scopes-and-namespaces
  • global folder_path 不会创建变量 - 它只会在您使用 = 时通知函数为外部/全局变量赋值。此外,您需要StringVar() 才能使用set() - 所以您必须在使用folder_path.set() 之前创建folder_path = StringVar()
  • 顺便说一句:有时最好在开始时使用一些默认值创建所有变量 - 即。你可以在root_window = tkinter.Tk()之后创建folder_path = StringVar(value="")

标签: python tkinter directory path


【解决方案1】:

使用

folder_path.set(...)

你必须先创建

folder_path = StringVar()

global 不创建变量,但仅在函数中用于通知该函数在您使用= 赋值时使用外部/全局变量(而不是创建局部变量)。

user_input 会遇到同样的问题。

所以你可以在开始时创建变量

root_window = tkinter.Tk()

user_input = ''   # it creates global variable
folder_path = StringVar()  # it creates global variable

它解决了这些变量的问题


编辑:我发现你在create_widgets_in_first_frame 中使用了folder_path = StringVar(),但它创建了局部变量。您必须使用global 通知函数将StringVar() 分配给外部/glboal 变量

def create_widgets_in_first_frame():
    global folder_path  # inform function to assign value (`=`) to external variable `folder_path`
    folder_path = StringVar()

然后它将创建全局folder_path,您不必在开始时创建它。

【讨论】:

    猜你喜欢
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 2013-06-08
    • 1970-01-01
    • 1970-01-01
    • 2019-05-17
    • 1970-01-01
    相关资源
    最近更新 更多