hoffstadt / DearPyGui

Dear PyGui: A fast and powerful Graphical User Interface Toolkit for Python with minimal dependencies
https://dearpygui.readthedocs.io/en/latest/
MIT License
12.63k stars 669 forks source link

right-align table cells #2211

Closed sailfish009 closed 7 months ago

sailfish009 commented 8 months ago

Is your feature request related to a problem? Please describe. I would like to be able to right-align table cells.

Describe the solution you'd like Neither the :> operator nor the rjust() method provided by Python seem to work.

Describe alternatives you've considered None

Additional context None

v-ein commented 8 months ago

Under the cover, DearPyGui uses the Dear ImGui library, which does not provide any means to right-align content.

If you need to right-align plain text, use a button instead (with label=your_text), and apply a theme to it that:

  1. Right-aligns text;
  2. Makes background transparent.

If you put such a button into each cell in the column, and make all the buttons the same width, it all will look like right-aligned text.

You can make the button auto-stretch to the column width by specifying width=-1 on the button. Careful: if you're using the auto-fit policy (FixedFit), you need at least one cell to have width different from -1, otherwise the column won't be able to auto-size.

v-ein commented 8 months ago

Use dpg.show_style_editor() to figure out the theme constants for alignment and button colors.

v-ein commented 7 months ago

@sailfish009, do you need anything else on this issue? If not, I'd suggest that the ticket be closed.

sailfish009 commented 7 months ago

Hi, I'll keep this short for time's sake and share my progress as follows. I'm currently taking a 2-pronged approach. Based on adding a button to each cell and applying a theme to it. This works fine for displaying numbers with leading zeros, but unfortunately, it's not what the customer wants.

Notice the different positions of the 1s in the horizontal direction in the number representations below.

1/99 # method 1: Customers want them to align properly in this display 01/99 # method 2: This approach works fine. But it's not right aligned in the strict sense.

If the width of the space character in method 1 is the same as the width of the zero character in method 2, I thought I could solve the problem, so I tried using the Unicode character '\u2007' instead of the space character. As a result, the screen did not display the space as normal, but instead displayed the '?' on the screen.

This first approach didn't work out so well.

For the second approach, I checked the position of the button when each row was created. The position at creation was [0,0], and after creation, I checked the position of the first button and the spacing between each button to get the following number.

627, 24 # Position of the first button 49 # Pixel spacing in the vertical direction to the next button 24 # Pixel spacing in the horizontal direction to the next button

I'm going to test these values at button creation time by applying them like this add_button(..., pos=[627+49i, 24+24j], ...)

v-ein commented 7 months ago

Honestly, I don't get it what you've tried to do so far and what works and what doesn't.

Doesn't a theme with the following style work for you?

dpg.add_theme_style(dpg.mvStyleVar_ButtonTextAlign, 1.0, 0.5)
sailfish009 commented 7 months ago

I tested a code similar to the one you've shown, but it didn't work. I'll check the code you're looking at and share the results. Thank you.

sailfish009 commented 7 months ago

I wrote a simple example code and it works fine, thank you. Now I need to apply this code to the actual code.

import pandas as pd
import dearpygui.dearpygui as dpg

####################################################

d = dict()
d['A'] = [17, 1, 1]
d['B'] = [2 , 2, 2]
d['C'] = [3 , 3, 3]
d['D'] = [99 , 99, 99]
df = pd.DataFrame.from_dict(d)
arr = df.to_numpy()

####################################################

BACKGROUND_COLOUR = (0,0,0)

dpg.create_context()

with dpg.theme(tag="__button_right"):
    with dpg.theme_component(dpg.mvButton):
        dpg.add_theme_style(dpg.mvStyleVar_ButtonTextAlign, 1.00, category=dpg.mvThemeCat_Core)
        dpg.add_theme_color(dpg.mvThemeCol_Button, BACKGROUND_COLOUR, category=dpg.mvThemeCat_Core)
        dpg.add_theme_color(dpg.mvThemeCol_ButtonActive, BACKGROUND_COLOUR, category=dpg.mvThemeCat_Core)
        dpg.add_theme_color(dpg.mvThemeCol_ButtonHovered, BACKGROUND_COLOUR, category=dpg.mvThemeCat_Core)
        dpg.add_theme_color(dpg.mvThemeCol_Text, [29, 151, 236])

with dpg.window(tag="Primary Window"):
    with dpg.table(label='DataFrameTable'):
        for i in range(df.shape[1]):
            dpg.add_table_column(label=df.columns[i])
        for i in range(df.shape[0]):
            with dpg.table_row():
                for j in range(df.shape[1]):
                    if j == 3:
                        b = dpg.add_button(label=f"{arr[i,j-3]}/{arr[i,j]}", width=100)
                        dpg.bind_item_theme(b, "__button_right")
                    else:
                        dpg.add_button(label=f"{arr[i,j]}")

dpg.create_viewport(title='Custom Title', width=600, height=200)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.set_primary_window("Primary Window", True)
dpg.start_dearpygui()
sgelb commented 6 months ago

I ran into the same problem but did not like the workaround presented here. For my use case - floats with known max digits - it does work nicely using f-strings, no need for mis-using buttons. Also no problems with dpg.table(policy=dpg.mvTable_SizingFixedFit)

some_number=123.245
max_width = 6
dpg.add_text(f"{some_number: >{max_width}.2f}")