我正在编写一个 Python 程序,它会定期从网站上抓取一个数字,然后通过 Pystray 显示在系统托盘中。我可以让它做我想做的事,threading
但它会更好用asyncio
吗?如果是这样,怎么做?
来自 Pystray 手册:
调用
pystray.Icon.run()
是阻塞的,它必须从应用程序的主线程执行。原因是 OSX 的系统托盘图标实现将失败,除非从主线程调用,并且它还需要运行应用程序 runloop。pystray.Icon.run()
将启动运行循环。
这是否意味着asyncio
不兼容并且对于此应用程序必须有一个单独的线程?
这是一个使用的工作演示threading
:
from pystray import Icon as icon, Menu as menu, MenuItem as item
from PIL import Image, ImageDraw, ImageFont
import threading
import time
import random
def make_number_icon(number):
# draws the number as two digits in red on a transparent background
img = Image.new('RGBA', (64,64), color=(0,0,0,0))
fnt = ImageFont.truetype(r'C:\Windows\Fonts\GOTHICB.TTF', 58)
d = ImageDraw.Draw(img)
d.text((0,-8), f"{number:02}", font=fnt, fill='red')
return img
def update_icon(icon, _=None):
# web-scraping replaced with an RNG for demo
count = random.randrange(100)
icon.icon = make_number_icon(count)
icon = icon("Pystray test",
icon=make_number_icon(0),
menu=menu(item("Update now", update_icon),
item("Quit", icon.stop)))
def update_periodically_forever():
global icon
while True:
update_icon(icon)
time.sleep(2) # shortened from 60 for demo
# I understand daemon=True cleans up this thread when we reach EOF
update_thread = threading.Thread(target=update_periodically_forever, daemon=True)
update_thread.start()
# this is a blocking call; we stay here until icon.stop() is called
icon.run()
它看起来像什么:
update_icon
应该大约每 60 秒调用一次。这是函数最后一次调用后 60 秒还是函数从上次调用返回后 60 秒都没有关系。