tkinter2 -after和thread实现TK窗体的条件更新

在tkinter做GUI的过程中,经常有这样的需求:某些条件下窗体需要有响应变化。比如持续监听输入内容,直到输入内容做退出动作或者显示输入内容并继续要求输入。
Use tkinter without mainloop页面,作者介绍了三种方式实现,下面就after方法thread实现进行详细介绍。

2 after方法

2.1 after与after_cancel

def after(self, ms, func=None, *args):
“”“Call function once after given time.
MS specifies the time in milliseconds.
FUNC gives the function which shall be called.
Additional parameters are given as parameters to the function call. Return identifier to cancel scheduling with after_cancel.”""

after实际上相当于一个定时器,作用是一段时间后(ms)继续调用func函数。其余参数是func函数的参数,用after_cancel函数取消调用func函数。

2.2 示例

2.2.1 需求

TkInter GUI持续监听the bash input输入内容。如果输入内容为’exit’就结束while循环,如果输入内容不是’exit’,我们在GUI添加输入内容相对应的label。

2.2.2 代码
from tkinter import *

ROOT = Tk()

def ask_for_userinput():
    user_input = input("Give me your command! Just type \"exit\" to close: ")
    if user_input == "exit":
        ROOT.after_cancel(ask_for_userinput)
    else:
        label = Label(ROOT, text=user_input)
        label.pack()
        ROOT.after(100, ask_for_userinput)

LABEL = Label(ROOT, text="Hello, world!")
LABEL.pack()
ROOT.after(1000, ask_for_userinput)
ROOT.mainloop()
2.2.3 GUI

在这里插入图片描述

3 thread实现

3.1 简介

threading.Thread(target=函数名,args=(调用参数,注意最后要有一个‘,’))可以实例化一个多线程对象。

  1. 启动方法:先setDaemaon(True),后通过start开启。

在python中,主线程结束后,会默认等待子线程结束后,主线程才退出。
如果你忘记杀死子线程,那么好了,你杀主线程的时候其就会挂起等待直至子线程结束,所以为了避免这样的情况,python有两个函数管理线程:join和setDaemon。其中join会在设定的子线程thread结束后接着往后运行;而 setDaemaon(True)确保主线程结束时,杀死把子线程thread。
一般情况下,在start前面加一下setDaemon(True) 。
原文链接:https://blog.csdn.net/sm9sun/article/details/53743116

  1. 配合主线程队列使用,可以在线程间传递信息,用于更新主界面UI。

Queue的方法:首先通过empty方法判断队列是否为空,如果不为空就进入while循环,然后就从队列中取出第一条消息msg,配合地,我们往消息队列中存入消息,消息可以对应主界面UI的变化,执行完了这条消息,就继续判断队列是否仍有消息,如果有就继续执行第二条消息,若无消息则退出while循环。
这样我们就在主线程建立了一个消息队列,每隔一段时间去查看消息队列,有没有什么消息是需要主线程去做的。有一点需要特别注意,主线程消息队列里也不要干耗时操作,该队列仅仅用来更新UI。
https://blog.csdn.net/yingshukun/article/details/78838395

3.2 示例

3.2.1 需求
  • TkInter 主界面持续监听Toplevel内输入内容。如果输入内容为’exit’就结束while循环关闭Toplevel,如果输入内容不是’exit’,我们在主界面添加输入内容相对应的label。
3.2.2 代码
from tkinter import *
import threading,queue

class App(threading.Thread):

    def __init__(self, top):
        self.notify_queue = queue.Queue()
        self.top = Toplevel(top)
        self.loop_active = True
   		#在UI线程启动消息队列循环
        self.process_msg()
        threading.Thread.__init__(self)
        self.setDaemon(True)
        self.start()


    def run(self):
        while self.loop_active:
            user_input = input("Give me your command! Just type \"exit\" to close: ")
            label = Label(self.top, text=user_input)
            label.pack()
            if user_input == "exit":
                #loop_active = False
                self.notify_queue.put(1)
        self.top.destroy()
                
    def process_msg(self):
        self.top.after(400,self.process_msg)
        while not self.notify_queue.empty():
            try:
                msg = self.notify_queue.get()
                print(msg)
                if msg == 1:
                    self.loop_active = False
                    print(self.loop_active)
            except queue.Empty:
                pass
        
ROOT = Tk()
APP = App(ROOT)
ROOT.mainloop()
3.2.3 GUI

在这里插入图片描述

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值