tkinter弹窗相关:RuntimeError: main thread is not in main loop

工作环境:界面上多个小组件,包含几个需要实时改变状态的组件。此时需要加入一个弹窗,在网上搜到弹窗的一个Demo并学习,得到如下代码:

from tkinter import *

win = Tk()
#设置窗口大小
win.geometry("700x250")
win.title("子窗口")
def open_win():
    def clsose_Win():
        top.quit()
        top.destroy()
    #创建用于打开Toplevel窗口的按钮
    top= Toplevel(win)
    top.geometry("700x250")
    top.title("子窗口")
    #在Toplevel窗口中创建一个标签
    Label(top, text= "Hello World!").pack()
    Button(top, text= "关闭", background= "white", foreground= "blue", font= ('Helvetica 13 bold'), command= clsose_Win).pack(pady= 50)

Label(win, text= "单击按钮以打开弹出窗口", font= ('Helvetica 18')).place(relx=.5, rely=.5, anchor= CENTER)
Button(win, text= "点击我", background= "white", foreground= "blue", font= ('Helvetica 13 bold'), command= open_win).pack(pady= 50)
win.mainloop()

此时可以达成如下效果:

         随后掌握了该Demo后,运用在实际项目中,发现多了一下关于线程的奇奇怪怪的报错,此时重新回来研究该Demo。为了模拟实际情况的开发,在父窗口加入一些利用线程,实时可变动的动态组件,例如:计时器,此时Demo代码为:

from tkinter import *
from threading import Thread,Timer
import time

win = Tk()
#设置窗口大小
win.geometry("700x250")
win.title("父窗口")
def open_win():
    def clsose_Win():
        top.quit()
        top.destroy()
    #创建用于打开Toplevel窗口的按钮
    top= Toplevel(win)
    top.geometry("700x250")
    top.title("子窗口")
    #在Toplevel窗口中创建一个标签
    Label(top, text= "Hello World!").pack()
    Button(top, text= "关闭", background= "white", foreground= "blue", font= ('Helvetica 13 bold'), command= clsose_Win).pack(pady= 50)
    top.mainloop()
def start_timer():
    global WorkTime
    WorkTime=time.time()
    TimeTick()

def TimeTick():
    Timer(1, TimeTick).start()
    update_timer()

def update_timer():
    seconds = int(time.time() - WorkTime)  # 计算经过的秒数
    hh = seconds // 3600  # 计算小时数
    mm = (seconds % 3600) // 60  # 计算分钟数
    ss = seconds % 60  # 计算秒数
    l1.configure(text="{:02d}:{:02d}:{:02d}".format(hh, mm, ss), foreground='red')

l1 = Label(win, text= "", font= ('Helvetica 18'))
l1.pack(side='top')
b1 = Button(win, text= "点击我", background= "white", foreground= "black", font= ('Helvetica 13 bold'), command= open_win).pack(side = "bottom")
b2 = Button(win, text= "计时", background= "white", foreground= "black", font= ('Helvetica 13 bold'), command=lambda:start_timer()).pack(side = "bottom")
win.mainloop()

         由此得到效果为:

         与此同时,点击生成的新窗口,同时通过点击按钮来关闭子窗口,发现程序立马报错,计时器也随之停止,报错信息为:RuntimeError: main thread is not in main loop

        在本人的实际情况,由于该界面不是整个项目的main函数,所以根据该报错信息找了很久也没找到问题所在。

        后面了解,这个报错是由于窗口的mainloop退出了,而导致的该报错,随后看到这个关闭按钮内的代码块:

    def clsose_Win():

        top.quit()

        top.destroy()

        由于最初,并不了解这两个方法的具体作用,就直接拿来用了,这是作为初学者的大忌。一定了解陌生的方法对应的作用,才能使用。

        这下清楚了,这两个方法都是控制窗口关闭的函数,区别是,quit()会导致整个程序的推出,即父窗口:win.mainloop(),被终止,故,l1.config就无法正常执行,才产生的报错。所以这里,我们需要的是安全退出子窗口,则不需要quit函数,将改行注释掉,需求正常通过。。。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值