多线程可以将运行时间长的任务放到后台,转而执行其他任务,以提高效率基础概念可以看一下菜鸟的教程
https://www.runoob.com/python3/python3-multithreading.html
这里我做了一个简单的界面,便于理解多线程
界面是依赖tkinter库实现的。
其中包含三个按键和四个文本框
实现的功能是:
主线程使界面一直显示
开启线程1 的按钮 控制 线程1 在左上角文本框中每隔三秒打印一次时间
开启线程1 的按钮 控制 线程1 在右上角文本框中每隔三秒打印一次时间
选择文件的按钮 新建一个线程用于选择一个文件,并把文件目录打印在中间文本框里
还有无需按钮触发直接启动的线程,任务是在最下方文本框里每隔两秒打印一次时间
效果是:证明线程是并行的,即同一时间可以执行多项任务
虽然电脑是单核的,但是多线程之间切换的速度非常快以至于感受不到任务在切换执行,因此形成一种同时执行的感觉
比如上图中,19:22,19:25,19:27三个时间都同时在两个文本框中打印,说明几个线程在同步进行。
这里建立线程的技巧是:
在button的command函数上不传递参数,而是调用一个传递参数并建立线程的函数
如果command函数带参数,则线程会在程序运行开始时自动执行,如果按下按钮,则会再建一个线程,相当于多建了一个线程。
from tkinter import *
from tkinter import scrolledtext,filedialog
import threading
import time
class MY_THREADING_TK():
#构造函数
def __init__(self,tkname):
self.tkname = tkname
#对窗口进行控件初始化
def tk_init(self):
#父窗口属性
self.tkname.title('多线程测试')
self.tkname.geometry('700x400+200+100')
#控件
#文本框
self.text_one=scrolledtext.ScrolledText(self.tkname,width=38,height=10)
self.text_one.place(x=50,y=100)
self.text_two=scrolledtext.ScrolledText(self.tkname,width=38,height=10)
self.text_two.place(x=350,y=100)
self.file_path_text=Text(self.tkname,width=40,height=2)
self.file_path_text.place(x=300,y=250)
self.auto_print_text=scrolledtext.ScrolledText(self.tkname,width=80,height=5)
self.auto_print_text.place(x=50,y=300)
#标签
button_one=Button(self.tkname,text='开启线程1',width=20,bg='lightblue',command=self.new_thread_one)
button_one.place(x=100,y=50)
button_two=Button(self.tkname,text='开启线程2',width=20,bg='lightblue',command=self.new_thread_two)
button_two.place(x=400,y=50)
file_button=Button(self.tkname,text='选择文件',width=20,bg='lightblue',command=self.file_choose_thread)
file_button.place(x=100,y=250)
def new_thread_one(self):
new_thread=threading.Thread(target=self.thread,args=(self.text_one,3))
new_thread.start()
def new_thread_two(self):
new_thread=threading.Thread(target=self.thread,args=(self.text_two,3))
new_thread.start()
def file_choose_thread(self):
new_thread=threading.Thread(target=self.file_thread)
new_thread.start()
def auto_print_time_thread(self):
new_thread=threading.Thread(target=self.print_time)
new_thread.start()
def print_time(self):
while True:
self.auto_print_text.insert(END,time.ctime(time.time())+'\n')
self.auto_print_text.see(END)
self.auto_print_text.update()
time.sleep(2)
def thread(self,text,sec):
text.delete('1.0','end')
while True:
text.insert(END,time.ctime(time.time())+'\n')
text.see(END)
text.update()
time.sleep(sec)
def file_thread(self):
self.file_path_text.insert(END,filedialog.askopenfilename())
mastertk = Tk() #新建一个父窗口
my_tk = MY_THREADING_TK(mastertk)
my_tk.tk_init()
my_tk.auto_print_time_thread()
mastertk.mainloop()
另有需要注意的是,线程1、线程2之间无干涉,但是如果建立线程选择文件,但是又没选中,停留在文件选择对话框的时候,是不能执行线程1、2的,这是因为filedialog这个类本身不支持多线程。