python DearPyGui中的MessageBox

xfb7svmp  于 2023-10-15  发布在  Python
关注(0)|答案(1)|浏览(129)

我正在使用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)

任何帮助都值得推荐。提前感谢您

v09wglhw

v09wglhw1#

下面的代码可能会有帮助
pythonic popup messagebox in dearpygui (asyncio or sync way)
target:pythonic popup messagebox in dearpygui

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()

和Pillcio方式:

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())

相关问题