解决python tkinter界面卡死的问题


Posted in Python onJuly 17, 2019

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

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

解决python tkinter界面卡死的问题

解决办法:

方式一、直接开线程

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

以上这篇解决python tkinter界面卡死的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
利用python操作SQLite数据库及文件操作详解
Sep 22 Python
Python排序搜索基本算法之希尔排序实例分析
Dec 09 Python
解决py2exe打包后,总是多显示一个DOS黑色窗口的问题
Jun 21 Python
python文件转为exe文件的方法及用法详解
Jul 08 Python
python中用logging实现日志滚动和过期日志删除功能
Aug 20 Python
python实现最大优先队列
Aug 29 Python
django rest framework serializer返回时间自动格式化方法
Mar 31 Python
Python定时任务APScheduler原理及实例解析
May 30 Python
python中如何打包用户自定义模块
Sep 23 Python
python批量修改文件名的示例
Sep 27 Python
matplotlib对象拾取事件处理的实现
Jan 14 Python
python热力图实现简单方法
Jan 29 Python
Python 实现数据结构-堆栈和队列的操作方法
Jul 17 #Python
Python 实现数据结构-循环队列的操作方法
Jul 17 #Python
Python图像处理PIL各模块详细介绍(推荐)
Jul 17 #Python
python中dict使用方法详解
Jul 17 #Python
python中tkinter的应用:修改字体的实例讲解
Jul 17 #Python
python对矩阵进行转置的2种处理方法
Jul 17 #Python
使用Filter过滤python中的日志输出的实现方法
Jul 17 #Python
You might like
两种php去除二维数组的重复项方法
2015/11/04 PHP
实例化php类时传参的方法分析
2020/06/05 PHP
autoIMG 基于jquery的图片自适应插件代码
2011/03/12 Javascript
js(jQuery)获取时间的方法及常用时间类搜集
2013/10/23 Javascript
利用javascript打开模态对话框(示例代码)
2014/01/11 Javascript
JavaScript截取字符串的Slice、Substring、Substr函数详解和比较
2014/03/20 Javascript
模拟一个类似百度google的模糊搜索下拉列表
2014/04/15 Javascript
字段太多jquey快速清空表单内容方法
2014/08/21 Javascript
jQuery中hide()方法用法实例
2014/12/24 Javascript
分享一则javascript 调试技巧
2015/01/02 Javascript
JavaScript数组常用方法
2015/03/02 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(二)
2015/12/10 Javascript
JavaScript仿商城实现图片广告轮播实例代码
2016/02/06 Javascript
Angular.js中angular-ui-router的简单实践
2017/07/18 Javascript
JS关于刷新页面的相关总结
2018/05/09 Javascript
配置eslint规范项目代码风格
2019/03/11 Javascript
axios异步提交表单数据的几种方法
2019/08/11 Javascript
js实现图片跟随鼠标移动效果
2019/10/16 Javascript
jQuery实现本地存储
2020/12/22 jQuery
[01:01:52]DOTA2-DPC中国联赛正赛 iG vs LBZS BO3 第一场 3月4日
2021/03/11 DOTA
python数据结构之二叉树的遍历实例
2014/04/29 Python
举例讲解Python中的迭代器、生成器与列表解析用法
2016/03/20 Python
Python wxPython库使用wx.ListBox创建列表框示例
2018/09/03 Python
python hough变换检测直线的实现方法
2019/07/12 Python
python实现图片二值化及灰度处理方式
2019/12/07 Python
Django关于admin的使用技巧和知识点
2020/02/10 Python
Python爬虫实现模拟点击动态页面
2020/03/05 Python
Python代码需要缩进吗
2020/07/01 Python
Numpy实现卷积神经网络(CNN)的示例
2020/10/09 Python
HTML5 source标签:媒介元素定义媒介资源
2018/01/29 HTML / CSS
Linux面试题LINUX系统类
2015/11/25 面试题
Linux中如何用命令创建目录
2015/01/12 面试题
团工委书记自荐书范文
2013/12/17 职场文书
探矿工程师自荐信
2014/01/24 职场文书
爱牙日活动总结
2014/08/29 职场文书
反腐倡廉主题教育活动总结
2015/05/07 职场文书