tkinter 多线程+异步实现


import tkinter as tk
import asyncio
import random
import threading

class MainWindow(tk.Tk):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.geometry('500x500')
        self.a=tk.StringVar(value='0')
        self.b=tk.StringVar(value='1')

        self.label=tk.Label(self,width=20,height=2,bg='gray',textvariable=self.a)
        self.label.place(x=100,y=30)

        self.label2=tk.Label(self,width=20,height=2,bg='green',textvariable=self.b)
        self.label2.place(x=100,y=100)

        self.btn=tk.Button(self,text='start',command=self.start)
        self.btn.place(x=100,y=300)

    async def f1(self):
        while True:
            a=random.randint(100,1000)
            self.a.set(str(a))
            await asyncio.sleep(1)
    async def f2(self):
        while True:
            b=random.randint(10,99)
            self.b.set(str(b))
            await asyncio.sleep(3)

    async def main(self):
        tasks=[
            asyncio.create_task(self.f1()),
            asyncio.create_task(self.f2())
        ]
        await asyncio.wait(tasks)

    def run_thread(self):
        asyncio.run(self.main())

    def start(self):
        t=threading.Thread(target=self.run_thread)
        t.start()



if __name__ == '__main__':
    MainWindow().mainloop()
#上面的例子没有加入停止线程和异步事件循环。下面的例子加入了该功能
import threading
import tkinter as tk
import asyncio
import random

class Scal:
    def __init__(self,id):
        self.id=id
        self.flag=False
    async def start_scal(self):
        while not self.flag:
            await asyncio.sleep(3)
            print(self.id,'---',random.randint(10,100))
            print('--'*30)
    def stop(self):
        self.flag=True #用来退出循环
        loop=asyncio.get_event_loop()
        loop.stop()
        print('异步停止了')

async def run_asyan():
    tasks=[
        asyncio.create_task(obj.start_scal()),
        asyncio.create_task(obj2.start_scal()),
        asyncio.create_task(obj3.start_scal()),
        asyncio.create_task(obj4.start_scal()),
    ]
    await asyncio.wait(tasks)

def run_task():
    asyncio.run(run_asyan())

def on_colsing():
    obj.stop()
    obj2.stop()
    obj3.stop()
    obj4.stop()
    root.destroy()


def fun():
    t.start()


root=tk.Tk()

obj=Scal(1)
obj2=Scal(2)
obj3=Scal(3)
obj4=Scal(4)





root.geometry("500x400")
tk.Entry(root).pack()
tk.Button(root,text='click',command=fun).pack(pady=20)
t=threading.Thread(target=run_task)
root.protocol("WM_DELETE_WINDOW",on_colsing)


root.mainloop()
'''
#守护线程是一种特殊类型的线程,它的生命周期与主线程相关联。当所有的非守护线程结束时,守护线程会随##之自动结束。

#具体来说,守护线程的存在并不会阻止程序的退出。当所有的非守护线程结束时,Python 解释器会自动退#出,而不管守护线程是否还在执行。

守护线程通常用于执行一些后台任务或服务,它们不会阻塞程序的正常退出。例如,你可以创建一个守护线程用于定时更新某个数据,而不需要显式地停止守护线程。

需要注意的是,守护线程的特性决定了它们可能无法完整地执行完任务。因为它们会在程序退出时被强制终止,所以不能依赖守护线程来执行一些关键任务,比如文件的保存或数据库的操作。这些任务应该交给非守护线程来处理,以确保它们能够完整地执行。

在 Python 的 threading 模块中,可以通过设置线程对象的 daemon 属性为 True 来将线程设置为守护线程。例如,`threading.Thread(daemon=True)`。

总结起来,守护线程的主要特点是:
- 它的生命周期与主线程相关联。
- 当所有的非守护线程结束时,守护线程会随之自动结束。
- 它通常用于执行一些后台任务或服务,不会阻塞程序的正常退出。
- 它可能无法完整地执行完任务,不应该用于关键任务。
'''
import threading
import tkinter as tk
import asyncio
import random

class Scal:
    def __init__(self,id):
        self.id=id

    async def start_scal(self):
        while True:
            await asyncio.sleep(random.randint(1,3))
            print(self.id,'---',random.randint(10,100))
            print('--'*30)
    def stop(self):
        loop=asyncio.get_event_loop()
        loop.stop()
        print('异步停止了')

async def run_asyan():
    tasks=[
        asyncio.create_task(obj.start_scal()),
        asyncio.create_task(obj2.start_scal()),
        asyncio.create_task(obj3.start_scal()),
        asyncio.create_task(obj4.start_scal()),
    ]
    await asyncio.wait(tasks)

def run_task():
    asyncio.run(run_asyan())

def on_colsing():
    obj.stop()
    obj2.stop()
    obj3.stop()
    obj4.stop()
    root.destroy()


def fun():
    t.start()


root=tk.Tk()

obj=Scal(1)
obj2=Scal(2)
obj3=Scal(3)
obj4=Scal(4)





root.geometry("500x400")
tk.Entry(root).pack()
tk.Button(root,text='click',command=fun).pack(pady=20)
t=threading.Thread(target=run_task,daemon=True)
root.protocol("WM_DELETE_WINDOW",on_colsing)


root.mainloop()


#子线程用法
import threading
import asyncio
import random
import time
import tkinter as tk

class MyThread(threading.Thread):
    def __init__(self):
        super(MyThread, self).__init__()
        self.flag=False

    def run(self):
        while not self.flag:
            print('子线程执行中......')
            time.sleep(14)

    def stop(self):
        self.flag=True

t=MyThread()
t.start()

#主线程等一段时间后,停止子线程
time.sleep(2)
t.stop()

#等待子线程结束
t.join()
print("主线程结束")


#使用线程池和协程实现高并发

import asyncio
import time
from concurrent.futures import ThreadPoolExecutor
def download_pic(url):
    print(f"下载图片{url}")
    time.sleep(1)
    print(f"结束下载图片{url}")

async def main():
    ex= ThreadPoolExecutor(1000)
    loop=asyncio.get_running_loop()
    tasks=[]
    for i in range(10000):
        t=loop.run_in_executor(ex,download_pic,i)
        tasks.append(t)
    await asyncio.wait(tasks)

asyncio.run(main())


#启动异步的几种方法

import asyncio
a=0
async def f():
    global a
    while True:
        if a==10:
            break
        print('hello world')
        a+=1
        await asyncio.sleep(2)

#第一种调用方法python3.7以上
# async def main():
#     task=[asyncio.create_task(f())]
#     await asyncio.wait(task)
#
# asyncio.run(main())


#第二种调用方法python3.7以上
# tasks=[f()] #用协程对象,不能用task对象
# asyncio.run(asyncio.wait(tasks))


#第三种调用方法python3.6版本
loop=asyncio.get_event_loop()
loop.run_until_complete(f())

import asyncio
import threading

import tkinter as tk






async def scal(times,id,cur,goal,advance,callback=None):
    for i in range(times):
        while True:
            if callback is not None: #设置回调函数,用来更新界面
                callback(cur)
            cur+=1
            if cur>=goal:
                print(f'{id}称量结束')

                break
            elif cur>goal-advance:
                print(f'id-{id}精称门开{cur}')
                await asyncio.sleep(0.3)
                print(f'id-{id}精称门关,值为{cur}')
            else:
                print(f'id-{id}两个门开{cur}')
                await asyncio.sleep(0.3)
                print(f'id -{id}两个门关{cur}')
        cur=0
        print("="*30)
        await asyncio.sleep(5)





class Win(tk.Tk):
    def __init__(self):
        super(Win, self).__init__()
        self.geometry("800x600")

        self.var=tk.StringVar()
        label=tk.Label(self,textvariable=self.var,width=20,height=3,bg='green')
        label.place(x=100,y=100)

        self.t = threading.Thread(target=self.fun2,daemon=True)
        self.after(3000,self.fun)

    def callback(self,m):
        self.var.set(str(m))


    async def main(self):
        tasks=[
            asyncio.create_task(scal(3,1,0,20,10,self.callback))
        ]
        await asyncio.wait(tasks)

    def fun(self):
        self.t.start()

    def fun2(self):
        asyncio.run(self.main())



app=Win().mainloop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值