我正在使用 DearPyGui 库在 python 中创建用户界面。
在运行我的算法的函数中,该算法需要用户的一些输入(是/否问题)。是否可以在 DearPyGui 中轻松实现这样的消息框而不中断函数流程?
类似这样的:
def runAlgorithm():
a = 2 + 2
user_choice = dpg.messageBox("Do you want to add or subtract the values", ["add", "subtract"]
if user_choice == "add":
a = a + a
else:
a = a - a
print("The user has selected %s and the result is %d"%(user_choice, a)
据我了解 DearPyGui 到目前为止,这是不可能的,我必须编写这样的东西,这是相当庞大且不可读的,特别是在可能需要一些用户输入的算法中,这会极大地破坏其可读性。
def choiceAdd(sender, app_data, user_data):
a = user_data[0]
print("The user has selected %s and the result is %d"%("add", a + a)
def choiceSub(sender, app_data, user_data):
a = user_data[0]
print("The user has selected %s and the result is %d"%("subtract", a - a)
def runAlgorithm():
a = 2 + 2
with dpg.window():
dpg.add_button("add", callback = choiceAdd, user_data = [a])
dpg.add_button("subtract", callback = choiceSub, user_data = [a]
user_choice = dpg.messageBox("Do you want to add or subtract the values", ["add", "subtract"]
if user_choice == "add":
a = a + a
else:
a = a - a
print("The user has selected %s and the result is %d"%(user_choice, a)
建议任何帮助。 先谢谢你了
下面的代码也许有帮助
dearpygui 中的 pythonic 弹出消息框(异步或同步方式)
目标:dearpygui 中的 pythonic 弹出消息框
do_sth_step1(...)
user_response = msgbox('Confirm?') # Yes/No
if user_response == 'Yes':
do_sth_step2(...)
解决方案:
import time
import inspect
import dearpygui.dearpygui as dpg
dpg.create_context()
dpg_callback_queue = []
def msgbox():
def on_msgbox_btn_click(sender, data, user_data):
nonlocal resp
resp = dpg.get_item_label(sender)
dpg.hide_item(popup)
# dpg.delete_item(popup)
with dpg.popup(parent=dpg.last_item(), modal=True) as popup:
dpg.add_text('goto step 2?')
with dpg.group(horizontal=True):
dpg.add_button(label='Yes', callback=on_msgbox_btn_click)
dpg.add_button(label='No', callback=on_msgbox_btn_click)
dpg.show_item(popup)
resp = None
while not resp:
# print('waiting for response ...')
time.sleep(0.01) # sleep main thread also
handle_callbacks_and_render_one_frame() # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
return resp
def on_btn_click(sender, data, user_data):
print('do sth step 1 ...')
resp = msgbox()
if resp == 'Yes':
print('do sth step 2 ...')
print('done!')
def main():
with dpg.window(tag='prim'):
dpg.add_button(label='Submit', callback=on_btn_click)
dpg.create_viewport(title='test msgbox', width=600, height=300)
# start_dpg()
dpg.setup_dearpygui()
dpg.set_primary_window('prim', True)
dpg.show_viewport()
dpg.configure_app(manual_callback_management=True)
while dpg.is_dearpygui_running():
handle_callbacks_and_render_one_frame()
dpg.destroy_context()
def run_callbacks():
global dpg_callback_queue
while dpg_callback_queue:
job = dpg_callback_queue.pop(0)
if job[0] is None:
continue
sig = inspect.signature(job[0])
args = []
for i in range(len(sig.parameters)):
args.append(job[i+1])
result = job[0](*args)
def handle_callbacks_and_render_one_frame():
global dpg_callback_queue
dpg_callback_queue += dpg.get_callback_queue() or [] # retrieves and clears queue
# print(f'jobs: {jobs}')
run_callbacks()
dpg.render_dearpygui_frame()
if __name__ == '__main__':
main()
和异步方式:
import asyncio
import inspect
import dearpygui.dearpygui as dpg
dpg.create_context()
async def msgbox():
def on_msgbox_btn_click(sender, data, user_data):
# print('clicked msgbox button')
nonlocal resp
resp = dpg.get_item_label(sender)
dpg.hide_item(popup)
# dpg.delete_item(popup)
with dpg.popup(parent=dpg.last_item(), modal=True) as popup:
dpg.add_text('goto step 2?')
with dpg.group(horizontal=True):
dpg.add_button(label='Yes', callback=on_msgbox_btn_click)
dpg.add_button(label='No', callback=on_msgbox_btn_click)
dpg.show_item(popup)
resp = None
while not resp:
# print('waiting for response ...')
await asyncio.sleep(0.01)
return resp
async def on_btn_click(sender, data, user_data):
print('do sth step 1 ...')
resp = await msgbox()
if resp == 'Yes':
print('do sth step 2 ...')
print('done')
async def main():
with dpg.window(tag='prim'):
dpg.add_button(label='Submit', callback=on_btn_click)
dpg.create_viewport(title='test msgbox', width=600, height=300)
# start_dpg()
dpg.setup_dearpygui()
dpg.set_primary_window('prim', True)
dpg.show_viewport()
dpg.configure_app(manual_callback_management=True)
while dpg.is_dearpygui_running():
jobs = dpg.get_callback_queue() # retrieves and clears queue
await run_callbacks(jobs)
dpg.render_dearpygui_frame()
await asyncio.sleep(0.01)
dpg.destroy_context()
async def run_callbacks(jobs):
if jobs is None:
pass
else:
for job in jobs:
if job[0] is None:
continue
sig = inspect.signature(job[0])
args = []
for i in range(len(sig.parameters)):
args.append(job[i+1])
result = job[0](*args)
if inspect.isawaitable(result):
asyncio.create_task(result)
if __name__ == '__main__':
asyncio.run(main())