如何在DearPyGUI中制作动态小部件?

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

很有可能在桌子上尝试动态小部件的问题:

import dearpygui.dearpygui as dpg
from typing_extensions import Union, Optional, Any
# * Local Imports
import database
from units import __prog_name__, __prog_version__, __prog_author__

# ! Initializing
dpg.create_context()

# ! Functions
def start() -> None:
    dpg.start_dearpygui()
    dpg.destroy_context()

# ! Window Functions
def load_table(
    sender: Optional[Union[int, str]],
    app_data: Optional[Any],
    table_name: str
):
    print([sender, app_data, table_name])
    if dpg.does_item_exist(f'{table_name}_table'):
        dpg.delete_item(f'{table_name}_table')
    with dpg.table(
        tag=f'{table_name}_table',
        resizable=True,
        policy=dpg.mvTable_SizingStretchProp,
        row_background=True,
        borders_innerH=True,
        borders_outerH=True,
        borders_innerV=True,
        borders_outerV=True
    ):
        column_names = [column.name for column in database.metadata.tables[table_name].columns.values()]
        for column_name in column_names:
            dpg.add_table_column(label=column_name)
        result = database.connection.execute(database.sqla.text(f"SELECT * FROM '{table_name}';"))
        for row in result:
            with dpg.table_row():
                for value in row:
                    dpg.add_text(str(value))

# ! Main Window
with dpg.window(tag="hippodrome_app"):
    with dpg.tab_bar(label="Hippodrome Tabs"):
        with dpg.tab(label="Horses"):
            load_table(None, None, 'Horses')
            dpg.add_button(label="Update", callback=(lambda sender, app_data: load_table(sender, app_data, 'Horses')))
        with dpg.tab(label="Jockeys"):
            load_table(None, None, 'Jockeys')
            dpg.add_button(label="Update", callback=(lambda sender, app_data: load_table(sender, app_data, 'Jockeys')))
        with dpg.tab(label="Races"):
            load_table(None, None, 'Races')
            dpg.add_button(label="Update", callback=(lambda sender, app_data: load_table(sender, app_data, 'Races')))

# ! Settings
dpg.create_viewport(title=f'{__prog_name__} v{__prog_version__}', width=800, height=350)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.set_primary_window("hippodrome_app", True)

# ! Start
if __name__ == "__main__":
    start()

程序第一次启动时,表加载正常,没有问题。 但是当您点击更新按钮时,会显示错误:

Exception:
Error:     [1011]
Command:   add_*
Item:      104
Label:
Item Type: mvAppItemType::mvTable
Message:   Parent could not be deduced.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\Romanin\AppData\Local\Programs\Python\Python312\Lib\site-packages\dearpygui\dearpygui.py", line 2601, in table
    widget = internal_dpg.add_table(label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, width=width, height=height, indent=indent, parent=parent, before=before, source=source, callback=callback, show=show, pos=pos, filter_key=filter_key, delay_search=delay_search, header_row=header_row, clipper=clipper, inner_width=inner_width, policy=policy, freeze_rows=freeze_rows, freeze_columns=freeze_columns, sort_multi=sort_multi, sort_tristate=sort_tristate, resizable=resizable, reorderable=reorderable, hideable=hideable, sortable=sortable, context_menu_in_body=context_menu_in_body, row_background=row_background, borders_innerH=borders_innerH, borders_outerH=borders_outerH, borders_innerV=borders_innerV, borders_outerV=borders_outerV, no_host_extendX=no_host_extendX, no_host_extendY=no_host_extendY, no_keep_columns_visible=no_keep_columns_visible, precise_widths=precise_widths, no_clip=no_clip, pad_outerX=pad_outerX, no_pad_outerX=no_pad_outerX, no_pad_innerX=no_pad_innerX, scrollX=scrollX, scrollY=scrollY, no_saved_settings=no_saved_settings, **kwargs)

SystemError: <built-in function add_table> returned a result with an exception set

During handling of the above exception, another exception occurred:

Exception: Error: [1009] Message:       No container to pop.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "D:\Users\Romanin\Desktop\Hippodrome\app.py", line 48, in <lambda>
    dpg.add_button(label="Update", callback=(lambda sender, app_data: load_table(sender, app_data, 'Horses')))
                                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Users\Romanin\Desktop\Hippodrome\app.py", line 24, in load_table
    with dpg.table(
  File "C:\Users\Romanin\AppData\Local\Programs\Python\Python312\Lib\contextlib.py", line 137, in __enter__
    return next(self.gen)
           ^^^^^^^^^^^^^^
  File "C:\Users\Romanin\AppData\Local\Programs\Python\Python312\Lib\site-packages\dearpygui\dearpygui.py", line 2605, in table
    internal_dpg.pop_container_stack()
SystemError: <built-in function pop_container_stack> returned a result with an exception set

我明白为什么会发生这种情况,在方法

load_table(...)
中调用的上下文管理器第一次在上下文管理器
dpg.tab(label="...")
内打开,但是当应用程序打开时,该上下文管理器关闭。

如何完全更新表格(小部件)?

我尝试不删除该表,而是只删除它的子小部件,因为当时我不明白问题是什么:

    dpg.delete_item(f'{table_name}_table', children_only=True)
python widget contextmanager dearpygui
1个回答
0
投票

我又坐了几个小时,然后我发现了这个选项。

您需要为表格、表格后面的按钮以及父窗口小部件指定

tag
参数。 然后,在表格中,传递
parent
(父窗口小部件的标签)和
before
(表格位于其前面的窗口小部件)作为参数。

import dearpygui.dearpygui as dpg
from typing_extensions import Union, Optional, Any
# * Local Imports
import database

# ! Initializing
dpg.create_context()

# ! Functions
def start() -> None:
    dpg.start_dearpygui()
    dpg.destroy_context()

# ! Window Functions
def load_table(
    sender: Optional[Union[int, str]],
    app_data: Optional[Any],
    table_name: str
):
    print([sender, app_data, table_name])
    if dpg.does_item_exist(f'{table_name}_table'):
        dpg.delete_item(f'{table_name}_table')
    with dpg.table(
        tag=f'{table_name}_table',
        resizable=True,
        policy=dpg.mvTable_SizingStretchProp,
        row_background=True,
        borders_innerH=True,
        borders_outerH=True,
        borders_innerV=True,
        borders_outerV=True,
        parent=f"{table_name}_table_tab",
        before=f"{table_name}_table_update_button"
    ):
        column_names = [column.name for column in database.metadata.tables[table_name].columns.values()]
        
        for column_name in column_names:
            dpg.add_table_column(label=column_name)
        
        result = database.connection.execute(database.sqla.text(f"SELECT * FROM '{table_name}';"))
        
        for row in result:
            with dpg.table_row():
                for value in row:
                    dpg.add_text(str(value))
    dpg.add_button(
        label="Update",
        tag=f"{table_name}_table_update_button",
        callback=(lambda sender, app_data: load_table(sender, app_data, 'Races'))
    )

# ! Main Window
with dpg.window(tag="hippodrome_app"):
    with dpg.tab_bar(label="Hippodrome Tabs"):
        with dpg.tab(label="Horses", tag="Horses_table_tab"):
            load_table(None, None, 'Horses')
        with dpg.tab(label="Jockeys", tag="Jockeys_table_tab"):
            load_table(None, None, 'Jockeys')
        with dpg.tab(label="Races", tag="Races_table_tab"):
            load_table(None, None, 'Races')

# ! Settings
dpg.create_viewport(title=f'Dinamic Widgets', width=800, height=350)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.set_primary_window("hippodrome_app", True)

# ! Start
if __name__ == "__main__":
    start()
© www.soinside.com 2019 - 2024. All rights reserved.