tkinter界面卡死的解决办法

简介: 0、如果点击按钮,运行了一个比较耗时的操作,那么界面会卡死 import tkinter as tk import time def onclick(text, i): time.

 0、如果点击按钮,运行了一个比较耗时的操作,那么界面会卡死

import tkinter as tk
import time

def onclick(text, i):
   time.sleep(3)
   text.insert(tk.END, '按了第{}个按钮\n'.format(i))

   
   
root = tk.Tk()

text = tk.Text(root)
text.pack()

tk.Button(root, text='按钮1', command=lambda :onclick(text,1)).pack()
tk.Button(root, text='按钮2', command=lambda :onclick(text,2)).pack()

root.mainloop()

 

解决办法:

方式一、直接开线程

import tkinter as tk
import time
import threading


songs = ['爱情买卖','朋友','回家过年','好日子']
movies = ['阿凡达','猩球崛起']

def music(songs):
    global text # 故意的,注意与movie的区别
    for s in songs:
        text.insert(tk.END, "听歌曲:%s \t-- %s\n" %(s, time.ctime()))
        time.sleep(3)

def movie(movies, text):
    for m in movies:
        text.insert(tk.END, "看电影:%s \t-- %s\n" %(m, time.ctime()))
        time.sleep(5)

    
def thread_it(func, *args):
    '''将函数打包进线程'''
    # 创建
    t = threading.Thread(target=func, args=args) 
    # 守护 !!!
    t.setDaemon(True) 
    # 启动
    t.start()
    # 阻塞--卡死界面!
    # t.join()


root = tk.Tk()

text = tk.Text(root)
text.pack()

tk.Button(root, text='音乐', command=lambda :thread_it(music, songs)).pack()
tk.Button(root, text='电影', command=lambda :thread_it(movie, movies, text)).pack()

root.mainloop()

 

方式二、继承 threading.Thread 类

import tkinter as tk
import time
import threading


songs = ['爱情买卖','朋友','回家过年','好日子']
movies = ['阿凡达','猩球崛起']

def music(songs):
    global text # 故意的,注意与movie的区别
    for s in songs:
        text.insert(tk.END, "听歌曲:%s \t-- %s\n" %(s, time.ctime()))
        time.sleep(3)

def movie(movies, text):
    for m in movies:
        text.insert(tk.END, "看电影:%s \t-- %s\n" %(m, time.ctime()))
        time.sleep(5)

class MyThread(threading.Thread):
    def __init__(self, func, *args):
        super().__init__()
        
        self.func = func
        self.args = args
        
        self.setDaemon(True)
        self.start()    # 在这里开始
        
    def run(self):
        self.func(*self.args)
    

root = tk.Tk()

text = tk.Text(root)
text.pack()

tk.Button(root, text='音乐', command=lambda :MyThread(music, songs)).pack()
tk.Button(root, text='电影', command=lambda :MyThread(movie, movies, text)).pack()

root.mainloop()

 

三、或者,搞一个界面类:

import tkinter as tk
import time
import threading

songs = ['爱情买卖','朋友','回家过年','好日子'] 
films = ['阿凡达','猩球崛起']

class Application(tk.Tk): def __init__(self): super().__init__() self.createUI() # 生成界面 def createUI(self): self.text = tk.Text(self) self.text.pack() tk.Button(self, text='音乐', command=lambda :self.thread_it(self.music, songs)).pack(expand=True, side=tk.RIGHT) # 注意lambda语句的作用! tk.Button(self, text='电影', command=lambda :self.thread_it(self.movie, films)).pack(expand=True, side=tk.LEFT) # 逻辑:听音乐 def music(self, songs): for x in songs: self.text.insert(tk.END, "听歌曲:%s \t-- %s\n" %(x, time.ctime())) print("听歌曲:%s \t-- %s" %(x, time.ctime())) time.sleep(3) # 逻辑:看电影 def movie(self, films): for x in films: self.text.insert(tk.END, "看电影:%s \t-- %s\n" %(x, time.ctime())) print("看电影:%s \t-- %s" %(x, time.ctime())) time.sleep(5) # 打包进线程(耗时的操作) @staticmethod def thread_it(func, *args): t = threading.Thread(target=func, args=args) t.setDaemon(True) # 守护--就算主界面关闭,线程也会留守后台运行(不对!) t.start() # 启动 # t.join() # 阻塞--会卡死界面! app = Application() app.mainloop()

 

目录
相关文章
|
存储 Java
map中存储的是引用,而不是对象本身
该内容是关于Java编程中验证Map存储引用而非复制对象的示例。创建大型List导致内存增加,说明List确实占用空间。通过Person类示例,将不同对象放入Map,改变一个对象的属性后,比较原对象与Map中的键值对,发现两者相等,证明Map保存的是对象引用。
274 5
|
Python
【python】通过多线程解决tkinter gui中按键卡住的问题
【python】通过多线程解决tkinter gui中按键卡住的问题
430 0
|
API 容器 Kubernetes
当 K8s 集群达到万级规模,阿里巴巴如何解决系统各组件性能问题?
作者 | 阿里云容器平台高级技术专家 曾凡松(逐灵) 本文主要介绍阿里巴巴在大规模生产环境中落地 Kubernetes 的过程中,在集群规模上遇到的典型问题以及对应的解决方案,内容包含对 etcd、kube-apiserver、kube-controller 的若干性能及稳定性增强,这些关键的增强是阿里巴巴内部上万节点的 Kubernetes 集群能够平稳支撑 2019 年天猫 618 大促的关键所在。
|
JSON JavaScript Linux
【MCP教程系列】如何自己打包MCP服务并部署到阿里云百炼上
本文章以阿里云百炼的工作流为例,介绍如何将其封装为MCP服务并部署到平台。主要步骤包括:1)使用Node.js和TypeScript搭建MCP服务;2)将项目打包并发布至npm官方平台;3)在阿里云百炼平台创建自定义MCP服务;4)将服务添加到智能体中进行测试。通过这些步骤,您可以轻松实现工作流的MCP化,并在智能体中调用自定义服务。
3750 0
|
机器学习/深度学习 缓存
Block Transformer:通过全局到局部的语言建模加速LLM推理
Block Transformer是一种优化自回归语言模型推理效率的新架构,通过块级自注意力来平衡全局和局部依赖,提高吞吐量。模型包含嵌入器、块解码器和令牌解码器,其中块解码器处理全局依赖,令牌解码器处理局部细节。这种方法减轻了KV缓存的延迟和内存开销,尤其是在长序列处理中。实验显示,尽管Block Transformer参数量增加,但推理速度显著提升,尤其是在大块长度和优化的组件比例下,实现了性能与速度的平衡。
663 7
|
运维 监控 数据可视化
Docker容器可视化管理工具 - WGCLOUD基础介绍
WGCLOUD是新一代运维监测平台,它可以监控Docker容器的各种性能数据,比如内存,cpu,Image,运行时间,运行状态,端口映射等信息
|
11月前
|
算法 API 网络安全
京东 API 接口调用失败的常见原因及解决方法
京东API为电商开发提供了丰富的功能,如商品信息获取、订单管理和物流查询等。然而,实际开发中常遇接口调用失败的问题。本文深入探讨了常见原因及解决方法,包括网络问题(如不稳定连接和防火墙限制)、权限问题(如密钥无效和接口权限不足)、参数问题(如缺失或格式不匹配)及服务器端问题(如维护和版本不兼容),并附带代码示例,帮助开发者快速定位和解决问题,提升应用的稳定性和可靠性。
2110 5
|
Java 数据库 Python
python flask 简单示例
python flask 简单示例
225 2
|
监控 安全 网络协议
|
存储 边缘计算 安全
边缘计算中的数据安全与隐私保护:挑战与应对策略
边缘计算中的数据安全与隐私保护:挑战与应对策略
1092 0