在
nicegui
中,我有一个按钮来启动创建类的函数。我希望在创建类期间禁用该按钮,这在我的实际代码中需要几秒钟(不是我在这里发布的示例)。我使用 nicegui
示例:以上下文管理器禁用按钮作为起点。我创建的类有一个需要 pythonnet
的属性并使用
Decimal
模块(来自
System
)。我对
pythonnet
不太熟悉,但是当我在没有
cpu_bound
的
nicegui
功能的情况下使用它时,该类就可以工作。否则,我会得到一个
TypeError: cannot pickle 'Decimal' object
。据我了解,我需要这个
cpu_bound
在类创建过程中禁用我的按钮。如何避免上面的
TypeError
?我已经尽可能简化了我的代码,以便它仍然显示错误:
from contextlib import contextmanager
from nicegui import run, ui
import clr
from System import Decimal
@contextmanager
def disable(button: ui.button):
button.disable()
try:
yield
finally:
button.enable()
class my_class:
def __init__(self, value):
self.value = Decimal(value)
def some_function():
return my_class(1)
async def get_slow_response(button: ui.button) -> None:
with disable(button):
return_value = await run.cpu_bound(some_function)
ui.button('Get slow response', on_click=lambda e: get_slow_response(e.sender))
ui.run(port=80)
我不确定它是否相关,但我注意到要导入Decimal
,我还需要有
import clr
,并且在VS Code中,系统带有“无法解析”警告。尽管正如我所说,该类本身运行良好。只需在类中删除此
Decimal
即可解决问题,但我的类需要此属性为
Decimal
,以便可以将其传递给 DLL。我在 Python 3.10.14 上使用
pythonnet
3.0.3、
nicegui
1.4.22(如果重要的话,我在 Windows 上)。
asyncio.to_thread
而不是
run.cpu_bound
获得了预期的行为。带有
contextmanager
的部分不再起作用,但代码满足了我的要求。我没有资格解释它为什么有效,但也许其他人可以对此发表评论。
import asyncio
import clr
import time
from nicegui import ui
from System import Decimal
class my_class:
def __init__(self, value):
self.value = Decimal(value)
def some_function():
time.sleep(1)
return my_class(1)
async def get_slow_response(button: ui.button) -> None:
button.disable()
return_value = await asyncio.to_thread(some_function)
button.enable()
ui.button('Get slow response', on_click=lambda e: get_slow_response(e.sender))
ui.run(port=80)