我正在使用eel创建一个桌面应用程序。但是,我在同时运行函数时遇到问题。
鳗鱼的想法是它允许电子通过JS与Python通信。因此,我在鳗鱼UI中创建了一个按钮,该按钮运行程序的一部分(多个异步aiohttp会话)。运行这些函数的函数被定义为异步的,即async def main():
。 main()
运行的所有功能也是异步的。这是该程序的概述:
import eel
import asyncio
from aiohttp import ClientSession
options = {
'mode': 'custom',
'args': ['node_modules/electron/dist/electron.exe', '.'],
}
@eel.expose
async def start_program(): # this is run when the user clicks the run button
await main()
@eel.expose
async def test_print(): # this is run when the user clicks the test button
print("test")
async def main():
tasks = []
loop = asyncio.get_event_loop()
for i in range(instances):
task = asyncio.ensure_future(launch(url))
tasks.append(task)
loop.run_until_complete(asyncio.wait(tasks))
async def launch(url):
done = False
async with ClientSession() as session:
while not done:
async with session.get(url, timeout=40) as initial:
html_text = await initial.text()
if x in html_text:
done = True
await session.close()
if __name__ == "__main__":
eel.init('web')
eel.start('html/index.html', options=options)
然后在我的JavaScript中,我有:
async function start_program_js() { // this is run when the user clicks the run button
await eel.start_program()();
}
async function test_print_js() { // this is run when the user clicks the test button
await eel.test_print()();
}
因此,所需的输出是,一旦我已经按下“运行”按钮,然后单击“测试”按钮,它将打印“测试”。但是,目前,它们都没有运行。通过将async def main():
更改为def main():
,将async def start_program():
更改为def start_program():
,将async def test_print():
更改为def test_print():
,可以使“运行”工作。然后在JS中将其更改为
function start_program_js() { // this is run when the user clicks the run button
eel.start_program();
}
function test_print_js() { // this is run when the user clicks the test button
eel.test_print();
}
但是,现在我的问题是,如果我已经单击“运行”,则“测试”按钮将不执行任何操作。它本身可以工作,但是如果正在运行“ run”,则不能工作。
我认为我首先详细介绍的异步方法会起作用,但是使用该方法并单击“运行”会导致此错误:
Traceback (most recent call last):
File "src\gevent\greenlet.py", line 766, in gevent._greenlet.Greenlet.run
File "C:\Users\x\AppData\Local\Programs\Python\Python37-32\lib\site-packages\eel\__init__.py", line 209, in _process_message
'value': return_val }))
File "C:\Users\x\AppData\Local\Programs\Python\Python37-32\lib\json\__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "C:\Users\x\AppData\Local\Programs\Python\Python37-32\lib\json\encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "C:\Users\x\AppData\Local\Programs\Python\Python37-32\lib\json\encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "C:\Users\x\AppData\Local\Programs\Python\Python37-32\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type coroutine is not JSON serializable
2019-06-03T13:00:59Z <Greenlet at 0x4f4b4b0: _process_message({'call': 6.074835210306471, 'name': 'start_program', 'ar, <geventwebsocket.websocket.WebSocket object at 0x0)> failed with TypeError
C:\Users\x\AppData\Local\Programs\Python\Python37-32\lib\site-packages\gevent\libuv\loop.py:193: RuntimeWarning: coroutine 'start_program' was never awaited
super(loop, self)._run_callbacks()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
有人知道我该如何解决这个问题?
谢谢。
编辑:我刚刚注意到自述文件中有一个异步部分。我试图复制它,但是无法正常工作。我尝试过
@eel.expose
def start_program(): # this is run when the user clicks the run button
eel.spawn(main)
@eel.expose
def test_print(): # this is run when the user clicks the test button
eel.spawn(test_print_x)
def test_print_x():
print("test")
但是,我遇到了与以前相同的问题,即它没有运行“测试”按钮功能。