mainloop覆盖tkinter中的循环

时间:2018-01-18 18:17:30

标签: python python-3.x tkinter

一切正常但时间不会更新,我认为这是因为mainloop会覆盖while循环。请帮忙,我已经搜索了很长时间但一无所获。

while循环低于主代码:

def loop1():
    Time = time.strftime("%H:%M:%S")
    while Time != Alarm:
        Time = time.strftime("%H:%M:%S")
        alarm = Tk()
        label3 = Label(alarm, text=Time)
        label3.grid(column=0, row=0)
        alarm.mainloop()
        #Get new time
        Time = time.strftime("%H:%M:%S")
        #Change to next second
        label3.config(text=Time)

主要代码:

#Import libraries
from tkinter import *
import time

Time = time.strftime("%H:%M:%S")

def loop1():
    Time = time.strftime("%H:%M:%S")
    while Time != Alarm:
        Time = time.strftime("%H:%M:%S")
        alarm = Tk()
        label3 = Label(alarm, text=Time)
        label3.grid(column=0, row=0)
        alarm.mainloop()
        #Get new time
        Time = time.strftime("%H:%M:%S")
        #Change to next second
        label3.config(text=Time)

initalarm = Tk()
label1 = Label(initalarm,text="What time do you want to wake up?")
label2 = Label(initalarm,text="Use this form.\nExample: 06:30:00")
Alarm = Entry()
start = Button(initalarm, text="Set Alarm", command=loop1)
label1.pack()
label2.pack()
Alarm.pack()
start.pack()

4 个答案:

答案 0 :(得分:3)

mainloop没有覆盖任何内容。它只是在根窗口被销毁之前不会返回。或者更确切地说,在调用root.quit()之前它不会返回,这会在根窗口被销毁时自动发生。

答案 1 :(得分:0)

不要与框架作斗争,使用它。使用Tk进行GUI编程是事件驱动的,即您不能在长时间运行的循环中直接控制程序的控制流。而是为不同的事件设置处理程序,这些事件在事件发生时从Tk的主循环调用。事件的示例是按钮按下或当某个给定时间过去时。这可用于定期获取主循环调用的一些处理程序,以更新显示并最终激活警报。

import tkinter as tk
from tkinter.font import nametofont
from tkinter.simpledialog import askstring
from datetime import datetime as DateTime


def update_display(time_label, alarm_time):
    now = DateTime.now().strftime('%H:%M:%S')
    if now >= alarm_time:
        time_label['foreground'] = 'yellow'
    time_label['text'] = now
    time_label.after(500, update_display, time_label, alarm_time)


def main():
    root = tk.Tk()
    root.title('Alarm Clock')

    font = nametofont('TkTextFont').copy()
    font['size'] *= 5

    time_label = tk.Label(root, text='--:--:--', font=font)
    time_label.pack()

    alarm_time = askstring(
        'When?', 'What time do you want to wake up?\nExample: 06:30:00'
    )
    if alarm_time is not None:
        update_display(time_label, alarm_time)
        root.mainloop()


if __name__ == '__main__':
    main()

如果我做对了,代码大致与问题中的代码一起尝试了,但实际有用的闹钟程序需要Python中的面向对象编程,如果它不应该变得难以理解并且跟随混乱。 / p>

此外,我不会将时间作为字符串操作,而是作为来自datetime模块的对象操作,或者至少作为自“{epoch”与time模块以来的秒数操作。字符串形式最好留给用户输入和输出。并且应该验证用户输入。在目前的形式中,很容易意外地输入无效的警报时间。

答案 2 :(得分:-1)

根据我的理解,您正在寻找要更新的标签,直到达到闹钟时间。如果这是真的,那么你的代码有两个错误

  1. alarm = Tk()应移出while循环
  2. 您应该使用alarm.update()而不是alarm.mainloop()
  3.   

    更新了loop1定义:

    def loop1():
        Time = time.strftime("%H:%M:%S")
        alarm = Tk()
        while Time != Alarm:
            Time = time.strftime("%H:%M:%S")
            label3 = Label(alarm, text=Time)
            label3.grid(column=0, row=0)
            alarm.update()
            #Get new time
            Time = time.strftime("%H:%M:%S")
            #Change to next second
            label3.config(text=Time)
    
      

    主要代码:

    #Import libraries
    from tkinter import *
    import time
    
    Time = time.strftime("%H:%M:%S")
    
    def loop1():
        Time = time.strftime("%H:%M:%S")
        alarm = Tk()
        while Time != Alarm:
            Time = time.strftime("%H:%M:%S")
            label3 = Label(alarm, text=Time)
            label3.grid(column=0, row=0)
            alarm.update()
            #Get new time
            Time = time.strftime("%H:%M:%S")
            #Change to next second
            label3.config(text=Time)
    
    initalarm = Tk()
    label1 = Label(initalarm,text="What time do you want to wake up?")
    label2 = Label(initalarm,text="Use this form.\nExample: 06:30:00")
    Alarm = Entry()
    start = Button(initalarm, text="Set Alarm", command=loop1)
    label1.pack()
    label2.pack()
    Alarm.pack()
    start.pack()
    

答案 3 :(得分:-1)

root.mainloop()或您的alarm.mainloop()工作的方式是它将使自己的循环更新根(或警报)窗口。无论何时运行命令(如root.bind或按钮命令),它都会暂停主循环

因为mainloop正在循环,这样做是自己的事情,它永远不会到达{{1 }}或root.mainloop()(除非发生一些奇怪的错误)。

一个非常简单的解决办法就是通过一个循环来做你自己的“主循环”然后使用alarm.mainloop()root.update()(这是由mainloop命令反复运行的,但您可以“自定义”循环)

使用它仍然允许绑定和按钮命令工作。不要在循环之前调用alarm.update(),而是在循环内部调用alarm.mainloop()