DearPyGui 中的消息框

问题描述 投票:0回答:1

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

建议任何帮助。 先谢谢你了

python user-interface messagebox dearpygui
1个回答
0
投票

下面的代码也许有帮助

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())
© www.soinside.com 2019 - 2024. All rights reserved.