Python 在使用存储变量时,是否可以保持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

在Jupyter笔记本中,我使用tkinter收集用户输入,以便其他代码可以生成输出文件。我已经创建了一个submit按钮来存储变量,但是我必须在其余代码能够使用它们并运行到输出之前关闭tkinter窗口

我希望能够一直运行到输出文件,然后在不关闭和重新启动的情况下输入新的输入。我怎样才能让tkinter窗口一直打开


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