运行 使用 tkinter 的按钮命令函数
Run a function on button command using tkinter
首先,我是初学者。我有一个基本脚本 (get grades()
),它包含一个 .csv 文件和特定的 class 部分(最少 1 个,最多 3 个)。我写了这个函数来清理课程成绩,输出是一个只包含学号、class 部分和成绩的 .txt。然后,此文本文件就可以上传到我大学的系统了。
我正在尝试为这个脚本创建一个 GUI,但我被卡住了。谷歌搜索,我设法获得了一个基本的 GUI,但即使我可以进入 class 部分并浏览文件,我也无法将其设为 运行 我的功能。当我单击按钮获取成绩时,GUI 崩溃了。你能给我指出正确的方向吗?提前谢谢你。
tkinter 代码
import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showinfo
import tkinter
from tkinter import *
from tkinter import filedialog as fd
from get_grades import get_grades
from functools import partial
# root window
root = tk.Tk()
root.geometry("500x450")
root.title('Grades')
# store sections
sections = tk.StringVar()
file_name = tk.StringVar()
def save_sections():
""" callback when the sections button clicked
"""
msg = f'You entered sections: {sections.get()}'
showinfo(
title='Information',
message=msg
)
# Sign in frame
signin = ttk.Frame(root)
signin.pack(padx=10, pady=10, fill='x', expand=True)
# sections
sections_label = ttk.Label(signin, text="sections:")
sections_label.pack(fill='x', expand=True)
sections_entry = ttk.Entry(signin, textvariable=sections)
sections_entry.pack(fill='x', expand=True)
sections_entry.focus()
# login button
section_button = ttk.Button(signin, text="save sections", command=save_sections)
section_button.pack(fill='x', expand=True, pady=10)
def get_file_name(file_entry):
file_name = fd.askopenfilename(title="Select file", filetypes=(("CSV Files", "*.csv"),))
file_entry.delete(0, END)
file_entry.insert(0, file_name)
entry_csv = Entry(root, text="", width=50)
entry_csv.pack(fill='x', expand=True)
file_label = ttk.Label(root, text="Input CSV")
file_button = ttk.Button(root, text="Browse...", width=10, command=lambda: get_file_name(entry_csv))
file_button.pack(fill='x', expand=True, pady=10)
grades_button = ttk.Button(root, text="Get grades", width=10, command=lambda: get_grades(entry_csv, sections))
grades_button.pack(fill='x', expand=True, pady=10)
# infinite loop
root.mainloop()
get_grades.py
import pandas as pd
from datetime import datetime
def get_grades(file, section1=True, section2=False, section3=False):
sections = []
if section1:
sections.append(section1)
if section2:
sections.append(section2)
if section3:
sections.append(section3)
else:
return "missing sections"
# get file
df = pd.read_csv(file)
# delete the first two rows
df = df.drop([df.index[0], df.index[1]])
# important columns are "SIS User ID", "Section", and the name of the test, which changes by course
# first, rename the assignment column
df = df.rename(columns={df.columns[5]: "Grade"})
df = df[df.Student != "Student, Test"]
# select columns
df = df[["SIS User ID", "Section", "Grade"]]
df = df[df['Section'].isin(sections)]
# cleaning
df = df.replace("0.0", "NVD")
df = df.fillna("NA")
# deleting decimal
df['SIS User ID'] = df['SIS User ID'].astype(str).apply(lambda x: x.replace('.0', ''))
# save to txt and csv
# file name
date_time = datetime.now().strftime("%Y_%m_%d-%I_%M_%S_%p")
filename = str(date_time) + "_" + str(sections)
df.to_csv(str(filename + ' .txt'), sep='\t', index=False)
print("done! file " + str(filename) + ".txt saved")
您正在将一个 Entry 小部件和一个 StringVar 传递给您的函数。但是您的函数需要字符串对象。
您必须获取输入框和 StringVar 的值。幸运的是,两种情况下调用的方法相同。这是.get()
方法。
grades_button = ttk.Button(root, text="Get grades", width=10, command=lambda: get_grades(entry_csv.get(), sections.get()))
这应该将正确的值传递给 get_grades()
。但可以肯定的是,您应该将值打印到控制台,只是为了检查。这也会暗示您的代码存在问题。
首先,我是初学者。我有一个基本脚本 (get grades()
),它包含一个 .csv 文件和特定的 class 部分(最少 1 个,最多 3 个)。我写了这个函数来清理课程成绩,输出是一个只包含学号、class 部分和成绩的 .txt。然后,此文本文件就可以上传到我大学的系统了。
我正在尝试为这个脚本创建一个 GUI,但我被卡住了。谷歌搜索,我设法获得了一个基本的 GUI,但即使我可以进入 class 部分并浏览文件,我也无法将其设为 运行 我的功能。当我单击按钮获取成绩时,GUI 崩溃了。你能给我指出正确的方向吗?提前谢谢你。
tkinter 代码
import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showinfo
import tkinter
from tkinter import *
from tkinter import filedialog as fd
from get_grades import get_grades
from functools import partial
# root window
root = tk.Tk()
root.geometry("500x450")
root.title('Grades')
# store sections
sections = tk.StringVar()
file_name = tk.StringVar()
def save_sections():
""" callback when the sections button clicked
"""
msg = f'You entered sections: {sections.get()}'
showinfo(
title='Information',
message=msg
)
# Sign in frame
signin = ttk.Frame(root)
signin.pack(padx=10, pady=10, fill='x', expand=True)
# sections
sections_label = ttk.Label(signin, text="sections:")
sections_label.pack(fill='x', expand=True)
sections_entry = ttk.Entry(signin, textvariable=sections)
sections_entry.pack(fill='x', expand=True)
sections_entry.focus()
# login button
section_button = ttk.Button(signin, text="save sections", command=save_sections)
section_button.pack(fill='x', expand=True, pady=10)
def get_file_name(file_entry):
file_name = fd.askopenfilename(title="Select file", filetypes=(("CSV Files", "*.csv"),))
file_entry.delete(0, END)
file_entry.insert(0, file_name)
entry_csv = Entry(root, text="", width=50)
entry_csv.pack(fill='x', expand=True)
file_label = ttk.Label(root, text="Input CSV")
file_button = ttk.Button(root, text="Browse...", width=10, command=lambda: get_file_name(entry_csv))
file_button.pack(fill='x', expand=True, pady=10)
grades_button = ttk.Button(root, text="Get grades", width=10, command=lambda: get_grades(entry_csv, sections))
grades_button.pack(fill='x', expand=True, pady=10)
# infinite loop
root.mainloop()
get_grades.py
import pandas as pd
from datetime import datetime
def get_grades(file, section1=True, section2=False, section3=False):
sections = []
if section1:
sections.append(section1)
if section2:
sections.append(section2)
if section3:
sections.append(section3)
else:
return "missing sections"
# get file
df = pd.read_csv(file)
# delete the first two rows
df = df.drop([df.index[0], df.index[1]])
# important columns are "SIS User ID", "Section", and the name of the test, which changes by course
# first, rename the assignment column
df = df.rename(columns={df.columns[5]: "Grade"})
df = df[df.Student != "Student, Test"]
# select columns
df = df[["SIS User ID", "Section", "Grade"]]
df = df[df['Section'].isin(sections)]
# cleaning
df = df.replace("0.0", "NVD")
df = df.fillna("NA")
# deleting decimal
df['SIS User ID'] = df['SIS User ID'].astype(str).apply(lambda x: x.replace('.0', ''))
# save to txt and csv
# file name
date_time = datetime.now().strftime("%Y_%m_%d-%I_%M_%S_%p")
filename = str(date_time) + "_" + str(sections)
df.to_csv(str(filename + ' .txt'), sep='\t', index=False)
print("done! file " + str(filename) + ".txt saved")
您正在将一个 Entry 小部件和一个 StringVar 传递给您的函数。但是您的函数需要字符串对象。
您必须获取输入框和 StringVar 的值。幸运的是,两种情况下调用的方法相同。这是.get()
方法。
grades_button = ttk.Button(root, text="Get grades", width=10, command=lambda: get_grades(entry_csv.get(), sections.get()))
这应该将正确的值传递给 get_grades()
。但可以肯定的是,您应该将值打印到控制台,只是为了检查。这也会暗示您的代码存在问题。