Python Asyncio loop.run_,直到_在小部件视图之前完成运行 说明:
我试图在启动时创建一个标题屏幕,通过ping循环到api或站点,并向用户显示成功和失败的内容 title.pyPython Asyncio loop.run_,直到_在小部件视图之前完成运行 说明:,python,asynchronous,async-await,python-asyncio,urwid,Python,Asynchronous,Async Await,Python Asyncio,Urwid,我试图在启动时创建一个标题屏幕,通过ping循环到api或站点,并向用户显示成功和失败的内容 title.py class TitleDisplay: def __init__(self): self.loop = asyncio.get_event_loop() self.sysc = syscheck.Syscheck() self.statustext = "" palette = [
class TitleDisplay:
def __init__(self):
self.loop = asyncio.get_event_loop()
self.sysc = syscheck.Syscheck()
self.statustext = ""
palette = [
('body', 'white', 'black'),
('header', 'black', 'light gray'),
('title', 'white', 'black'),
('syscheck', 'white', 'black'),
('exit', 'white', 'dark cyan'),
]
async def update_check(self, widget_ref):
widget = widget_ref()
if not widget:
# widget is dead; the main loop must've been destroyed
return
statuses = self.sysc.check()
async for status in statuses:
# simulate `next` with async iteration
self.statustext += status
widget.set_text(self.statustext)
async for other_response in self.sysc.check():
break
def setup_view(self):
fonts = urwid.get_all_fonts()
utf8 = urwid.get_encoding_mode() == "utf8"
for name, fontcls in fonts:
font = fontcls()
if not (font.utf8_required and not utf8):
if fontcls == urwid.Thin6x6Font:
exit_font = font
# Create BigText
self.bigtext = urwid.BigText(u"Title", exit_font)
bt = SwitchingPadding(self.bigtext, 'left', None)
bt = urwid.AttrWrap(bt, 'title')
bt = urwid.Filler(bt, 'top', None, 7)
bt = urwid.BoxAdapter(bt, 7)
# Create syscheck
cah = urwid.Text(u"Checking APIs...\n")
self.syscheckw = urwid.Text("", wrap='any')
self.loop.run_until_complete(self.update_check(weakref.ref(self.syscheckw)))
ca = urwid.AttrWrap(self.syscheckw, 'syscheck')
chars = urwid.Pile([cah, ca])
col = urwid.Columns([('fixed', 40, chars)], 3)
l = [bt, urwid.Divider(), col]
w = urwid.ListBox(urwid.SimpleListWalker(l))
# Frame
w = urwid.AttrWrap(w, 'body')
hdr = urwid.Text("esc to quit")
hdr = urwid.AttrWrap(hdr, 'header')
w = urwid.Frame(header=hdr, body=w)
# Exit message
exit = urwid.BigText(('exit'," Quit? "), exit_font)
exit = urwid.Overlay(exit, w, 'center', None, 'middle', None)
return w, exit
def main(self):
self.view, self.exit_view = self.setup_view()
self.urwid_loop = urwid.MainLoop(
self.view,
self.palette,
event_loop=urwid.AsyncioEventLoop(loop=self.loop),
unhandled_input=self.unhandled_input)
self.urwid_loop.run()
syscheck.py
class Syscheck():
def __init__(self):
self.param = '-n' if platform.system().lower()=='windows' else '-c'
# list of global sites to check
self.hostlist = [
"google.com", # list is ~10 items but shortened for brevity
]
async def ping(self, host):
# Building the command. Ex: "ping -c 1 google.com"
command = f"ping {self.param} 1 {host}"
proc = await asyncio.create_subprocess_shell(command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
status = await proc.wait()
return (status == 0)
async def check(self):
# begin with pings
connfailed = False
for host in self.hostlist:
status = f"Pinging {host}... "
yield status
pingstat = await self.ping(host)
if not pingstat:
connfailed = True
status = ("[ OK ]\n" if pingstat else "[ FAILED ]\n")
yield status
预期/实际结果
我希望出现大文本,然后syscheck小部件会说
pinging google.com…
,并在完成时添加[失败]
或[确定]
。相反,所有这些ping都是在显示标题屏幕之前完成的,然后所有内容都显示为状态消息已完成。这很可能是一个一旦解决就显得微不足道的问题——我只是一个简单的路人。如果我想尝试一下,我想这可能与syscheck.py中的wait proc.wait()
或title.py中的run\u直到完成有关。找到了答案,非常简单。你不想循环。运行直到完成,你想要一个循环
aloop = asyncio.get_event_loop()
ev_loop = urwid.AsyncioEventLoop(loop=aloop)
loop = urwid.MainLoop(frame, palette, screen,
unhandled_input=unhandled, event_loop=ev_loop)
aloop.create_task(generate_output())
如定义所示。哎呀