import PySimpleGUI as sG
import threading
import time
def gui():
sG.theme('DarkAmber')
layout = [
[sG.InputText('https://www.baidu.com', key='_text_'), sG.FileBrowse('导入', key='_file_'), sG.Button('查询'),
sG.Button('数据可视'), sG.Cancel('退出')],
[sG.Table(values=[[]])]
]
window = sG.Window('WebInfoGUI', layout, size=(1200, 700))
while True:
event, values = window.read()
if event in (sG.WIN_CLOSED, None, '退出'):
print(values)
break
window.close()
def job():
i = 0
while True:
i=i+2
print(i)
time.sleep(2)
#想要的效果是:关闭gui界面时同时终止线程thread2
# 或者点击退出时终止线程thread2
if __name__ == '__main__':
thread1 = threading.Thread(target=gui, args=())
thread2 = threading.Thread(target=job, args=())
thread1.start()
thread2.start()
下图是关闭了gui界面,程序仍然运行
gui不要用子线程执行,应该放到主线程里执行
子线程的deamon要设置成true,那么当主线程退出时,子线程也自动结束
Thread 对象数据属性有name(线程名),ident(线程标识符),daemon(线程是否是守护线程)等。主要对象包括start(),run()和join()等。start表示开始执行该线程,run()定义线程功能,通常在子类中被应用开发者重写,join (timeout=None)表示直到启动的线程终止之前一直挂起,除非给出timeout秒,否则会一直阻塞。
import threading
import time
def read():
for x in range(5):
print('在%s,正在听音乐' % time.ctime())
time.sleep(1.5)
def write():
for x in range(5):
print('在%s,正在看电视' % time.ctime())
time.sleep(1.5)
def main():
music_threads = [] # 用来存放执行read函数线程的列表
TV_threads = [] # 用来存放执行write函数线程的列表
for i in range(1,2): # 创建1个线程用于read(),并添加到read_threads列表
t = threading.Thread(target=read) # 执行的函数如果需要传递参数,threading.Thread(target=函数名,args=(参数,逗号隔开))
music_threads.append(t)
for i in range(1,2): # 创建1个线程执行write(),并添加到write_threads列表
t = threading.Thread(target=write) # 执行的函数如果需要传递参数,threading.Thread(target=函数名,args=(参数,逗号隔开))
TV_threads.append(t)
for i in range(0,1): # 启动存放在read_threads和write_threads列表中的线程
music_threads[i].start()
TV_threads[i].start()
if __name__ == '__main__':
main()
为了让线程更好的封装,可以用threading模块下的Thread类,继承这个类,然后实现run方法,线程就回自动运行run方法中的代码。
import threading
import time
count = 0
class MyThread(threading.Thread):
def __init__(self , threadName):
super(MyThread,self).__init__(name=threadName)
"""一旦这个MyThread类被调用,自动的就会运行底下的run方法中的代码,
因为这个run方法所属的的MyThread类继承了threading.Thread"""
def run(self):
global count
for i in range(100):
count += 1
time.sleep(0.3)
print(self.getName() , count)
for i in range(2):
MyThread("MyThreadName:" + str(i)).start()
在Python中,可以通过以下方式来终止线程:
示例代码:
import threading
import time
def task(event):
while not event.is_set():
# 线程执行的任务
print("Thread is running...")
time.sleep(1)
print("Thread is stopped.")
# 创建Event实例
stop_event = threading.Event()
# 创建并启动线程
thread = threading.Thread(target=task, args=(stop_event,))
thread.start()
# 在需要结束线程的时候设置Event,线程会在下一次wait()方法调用时检测到该Event并退出循环
stop_event.set()
# 等待线程结束
thread.join()
示例代码:
import threading
import time
import tkinter as tk
def task(flag):
while flag:
# 线程执行的任务
print("Thread is running...")
time.sleep(1)
print("Thread is stopped.")
# 创建并启动线程
flag = True
thread = threading.Thread(target=task, args=(flag,))
thread.start()
# GUI界面
def quit_thread():
global flag
flag = False
root = tk.Tk()
btn = tk.Button(root, text="Quit", command=quit_thread)
btn.pack()
root.mainloop()
# 等待线程结束
thread.join()
以上是两种终止Python线程的方式,具体方法可以根据实际情况进行选择。