Python 在使用存储变量时,是否可以保持tkinter窗口打开?
在Jupyter笔记本中,我使用tkinter收集用户输入,以便其他代码可以生成输出文件。我已经创建了一个submit按钮来存储变量,但是我必须在其余代码能够使用它们并运行到输出之前关闭tkinter窗口 我希望能够一直运行到输出文件,然后在不关闭和重新启动的情况下输入新的输入。我怎样才能让tkinter窗口一直打开Python 在使用存储变量时,是否可以保持tkinter窗口打开?,python,tkinter,calendar,global-variables,jupyter,Python,Tkinter,Calendar,Global Variables,Jupyter,在Jupyter笔记本中,我使用tkinter收集用户输入,以便其他代码可以生成输出文件。我已经创建了一个submit按钮来存储变量,但是我必须在其余代码能够使用它们并运行到输出之前关闭tkinter窗口 我希望能够一直运行到输出文件,然后在不关闭和重新启动的情况下输入新的输入。我怎样才能让tkinter窗口一直打开 from tkinter import * import datetime from datetime import timedelta from dateutil.relati
from tkinter import *
import datetime
from datetime import timedelta
from dateutil.relativedelta import relativedelta
import pandas as pd
class MyWindow:
def __init__(self, win):
self.lbl=Label(win, text="Tool")
self.lbl1=Label(win, text='ndays')
self.lbl2=Label(win, text='Date 1')
self.t1=Entry()
self.t2=Entry()
self.lbl.place(x=150, y=10)
self.lbl1.place(x=50, y=50)
self.t1.place(x=150, y=50)
self.lbl2.place(x=50, y=90)
self.t2.place(x=150, y=90)
self.b1=Button(win, text='Submit', command=self.submit)
self.b2=Button(win, text='Refresh')
self.b2.bind('<Button-1>', self.refresh)
self.b1.place(x=150, y=260)
self.b2.place(x=270, y=260)
def submit(self):
global ndays, screen
ndays=self.t1.get()
screen=self.t2.get()
#in case of refresh
def refresh(self, event):
self.t1.delete(0, 'end')
self.t2.delete(0, 'end')
window=Tk()
mywin=MyWindow(window)
window.title("Tool")
window.geometry("400x400+10+10")
window.mainloop()
在窗口上单击submit后,此代码将数据帧打印到终端中。只要窗口没有关闭,mainloop就会运行,并且不可能运行任何其他代码
from tkinter import *
import datetime
from datetime import timedelta
from dateutil.relativedelta import relativedelta
import pandas as pd
class MyWindow:
def __init__(self, win):
self.lbl=Label(win, text="Tool")
self.lbl1=Label(win, text='ndays')
self.lbl2=Label(win, text='Date 1')
self.t1=Entry()
self.t2=Entry()
self.lbl.place(x=150, y=10)
self.lbl1.place(x=50, y=50)
self.t1.place(x=150, y=50)
self.lbl2.place(x=50, y=90)
self.t2.place(x=150, y=90)
self.b1=Button(win, text='Submit', command=self.submit)
self.b2=Button(win, text='Refresh')
self.b2.bind('<Button-1>', self.refresh)
self.b1.place(x=150, y=260)
self.b2.place(x=270, y=260)
def calendar( self, screen, ndays ):
# find the of the number of days backwards.
screen = datetime.datetime.strptime(screen, '%m/%d/%y').date()
ndays=int(ndays)
thirty_back = screen + relativedelta(days=-ndays - 1)
delta1 = screen - thirty_back
# Empty lists to loop into
date_list = [] # dates
day_counter_thing = []
day_o_week = [] # real day of week
counter = [] # list for the days used
day_count = -1 # starts at -1 so that screen day can be 0
for i in range(delta1.days):
day = screen - timedelta(days=i) # know where to start the tlfb
date_list.append(day) # list of dates in the loop
day_count = day_count + 1 # add a count for each day in the loop
counter.append(day_count) # keep a list of all the day counts
day_o_week.append(day.strftime("%A")) # add the real day of the week
name = day.weekday() # name of day by index of day in week
day_counter_thing.append(name) # keep the list
max_day = max(counter) # gives you reference so that you can swap the counter after screen
# put the values from the loops into a dataframe
return pd.DataFrame({'Date': date_list, "Day": day_o_week, "Counter": day_counter_thing, "TLFB_Day": counter})
def submit(self):
print( self.calendar( self.t2.get(), self.t1.get()) )
#in case of refresh
def refresh(self, event):
self.t1.delete(0, 'end')
self.t2.delete(0, 'end')
window=Tk()
mywin=MyWindow(window)
window.title("Tool")
window.geometry("400x400+10+10")
window.mainloop()
从tkinter导入*
导入日期时间
从日期时间导入时间增量
从dateutil.relativedelta导入relativedelta
作为pd进口熊猫
类MyWindow:
定义初始(自我,赢):
self.lbl=标签(win,text=“工具”)
self.lbl1=标签(win,text='ndays')
self.lbl2=标签(win,text='date1')
self.t1=Entry()
self.t2=Entry()
自平衡位置(x=150,y=10)
self.lbl1.place(x=50,y=50)
自身t1位置(x=150,y=50)
self.lbl2.place(x=50,y=90)
自身t2位置(x=150,y=90)
self.b1=按钮(win,text='Submit',command=self.Submit)
self.b2=按钮(win,text='Refresh')
self.b2.bind(“”,self.refresh)
自身b1位置(x=150,y=260)
自身b2位置(x=270,y=260)
def日历(自身、屏幕、星期日):
#查找向后的天数。
screen=datetime.datetime.strtime(屏幕,“%m/%d/%y”).date()
ndays=int(ndays)
三十天=屏幕+相对时间(天=-ndays-1)
delta1=屏幕-三十度后
#要循环到的空列表
日期列表=[]日期
第二天(柜台)
day_o________________________________
计数器=[]#列出所用天数
day_count=-1#从-1开始,因此屏幕日期可以为0
对于范围内的i(delta1.天):
天=屏幕-时间增量(天=i)#知道从哪里开始tlfb
日期列表。附加(天)#循环中的日期列表
day_count=day_count+1#为循环中的每一天添加一个计数
计数器。附加(天数)#保留所有天数的列表
day_o_week.append(day.strftime(“%A”)#添加一周的实际日期
name=day.weekday()#按周中日期索引列出的日期名称
日期(计数器)(事物)附加(名称)#保留列表
max_day=max(计数器)#为您提供参考,以便您可以在屏幕后交换计数器
#将循环中的值放入数据帧中
返回pd.DataFrame({'Date':Date\u list,“Day”:Day\u o\u week,“Counter”:Day\u Counter\u thing,“TLFB\u Day”:Counter})
def提交(自我):
打印(self.calendar(self.t2.get(),self.t1.get())
#在刷新的情况下
def刷新(自我、事件):
self.t1.delete(0,'end')
self.t2.delete(0,“结束”)
window=Tk()
mywin=MyWindow(窗口)
窗口标题(“工具”)
窗几何(“400x400+10+10”)
window.mainloop()
另一种方法是在窗口本身中显示结果,而不是在文本对象或一系列标签中打印结果。为什么您认为在使用这些值之前需要退出窗口?没有要求你必须这样做。我正在使用jupyter,如果我试图在下面的内核中使用该变量,它只会在旁边显示*并且不会运行。我认为使用jupyter是一个重要的细节,你没有提到这个问题。我的错!不过,我现在也试过使用IDLE。当我在一个.py文件中以空闲状态运行这段代码时,我也遇到了同样的问题,即在变量可以在其他地方使用之前需要退出窗口。下一步是什么?我还是不明白为什么你不能在摧毁窗户之前使用它。
submit
函数可以在销毁窗口之前访问变量。事实上,它在被销毁后无法访问变量。好的,我从中了解了很多关于tkinter的知识。感谢您的开始,但我想我需要在前面澄清,我的程序中有更多的代码用于格式化和清理数据帧,然后将其导出到xlsx文件。在我看来,这似乎可以在def submit按钮内完成,但我犹豫是否要这样做,因为我希望有更多清晰的代码块,用于不同的功能(GUI、日期数据框创建、格式化、导出),供我以后参考。我对这一点还是很陌生——线程在某种程度上适合这里吗?我想最好的解决方案是用submit
方法处理数据。Ii可以在mywindow
类外部编写函数集或对象集,用于创建数据框、格式化和写入excel,并从类内部调用它们。这使您可以将活动的代码分开,但从一个点调用。要记住的要点是GUI界面对事件(如按钮单击)进行操作和反应。让他们也在后台工作要困难得多,而且常常是不必要的。我把它全部移到了submit方法下,它就工作了。谢谢你的评论!
from tkinter import *
import datetime
from datetime import timedelta
from dateutil.relativedelta import relativedelta
import pandas as pd
class MyWindow:
def __init__(self, win):
self.lbl=Label(win, text="Tool")
self.lbl1=Label(win, text='ndays')
self.lbl2=Label(win, text='Date 1')
self.t1=Entry()
self.t2=Entry()
self.lbl.place(x=150, y=10)
self.lbl1.place(x=50, y=50)
self.t1.place(x=150, y=50)
self.lbl2.place(x=50, y=90)
self.t2.place(x=150, y=90)
self.b1=Button(win, text='Submit', command=self.submit)
self.b2=Button(win, text='Refresh')
self.b2.bind('<Button-1>', self.refresh)
self.b1.place(x=150, y=260)
self.b2.place(x=270, y=260)
def calendar( self, screen, ndays ):
# find the of the number of days backwards.
screen = datetime.datetime.strptime(screen, '%m/%d/%y').date()
ndays=int(ndays)
thirty_back = screen + relativedelta(days=-ndays - 1)
delta1 = screen - thirty_back
# Empty lists to loop into
date_list = [] # dates
day_counter_thing = []
day_o_week = [] # real day of week
counter = [] # list for the days used
day_count = -1 # starts at -1 so that screen day can be 0
for i in range(delta1.days):
day = screen - timedelta(days=i) # know where to start the tlfb
date_list.append(day) # list of dates in the loop
day_count = day_count + 1 # add a count for each day in the loop
counter.append(day_count) # keep a list of all the day counts
day_o_week.append(day.strftime("%A")) # add the real day of the week
name = day.weekday() # name of day by index of day in week
day_counter_thing.append(name) # keep the list
max_day = max(counter) # gives you reference so that you can swap the counter after screen
# put the values from the loops into a dataframe
return pd.DataFrame({'Date': date_list, "Day": day_o_week, "Counter": day_counter_thing, "TLFB_Day": counter})
def submit(self):
print( self.calendar( self.t2.get(), self.t1.get()) )
#in case of refresh
def refresh(self, event):
self.t1.delete(0, 'end')
self.t2.delete(0, 'end')
window=Tk()
mywin=MyWindow(window)
window.title("Tool")
window.geometry("400x400+10+10")
window.mainloop()