Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get_value returns a string representation instead of the object itself #2291

Open
Nonoreve opened this issue Feb 21, 2024 · 2 comments
Open
Labels
state: pending not addressed yet type: bug bug

Comments

@Nonoreve
Copy link

Version of Dear PyGui

Version: 1.9.1
Operating System: Manjaro (using virtual env)

My Issue/Question

For UI items holding a list of things to display (like listboxes), we can use the argument items=() to give them arbitrary python objects to be displayed. dpg.add_listbox(items=items, num_items=len(items))
When displaying, the string representation of these objects is used to show these objects.
When using get_value(listbox), the result is always a string and not the object that was given.

The problem is that I want to use a listbox to display a list of object whose string representation is the same, and select one from the list to see its details.
Because of the str return from get_value(), I have no way to tell which item was selected without inserting information (like indices) directly in the string displayed by the item.

To Reproduce

Run the code below, select an item from the list and click the button. The results are printed to the console.

Expected behavior

From what I saw I dearpygui's source code, the value is directly converted when creating the item or setting values, and stored as a string. It could be changed to store the python object and only get the string representation when drawing. Then, when getting the value, return the orginal, untouched object.

Standalone, minimal, complete and verifiable example

This is a stripped version of my app. I made sure it runs well.

import dearpygui.dearpygui as dpg


class Entry:
	def __init__(self, entry):
		self.entry = entry

	def __repr__(self):
		print(f"__repr__ called on {id(self)}")
		return "AAAAA"


def compare_callback(sender, app_data, user_data):
	items = user_data
	selection = dpg.get_value(duplicate_documents_listbox)
	print(f"selection={(selection)},  type={type(selection)}, id={id(selection)}")


dpg.create_context()
dpg.create_viewport()
dpg.setup_dearpygui()

with dpg.window(no_close=True, modal=True):
	dpg.add_text(label='duplicate_text', default_value='There are similar entries already in the database :')
	items = [Entry("a"), Entry("b"), Entry(1), Entry("a"), Entry("42"), Entry(True)]
	duplicate_documents_listbox = dpg.add_listbox(label="", tag='duplicate_documents', items=items, default_value='', num_items=len(items))
	dpg.add_button(label="Compare new and selected one", user_data=(items), tag='compare_entries', callback=compare_callback)


dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
@Nonoreve Nonoreve added state: pending not addressed yet type: bug bug labels Feb 21, 2024
@Nonoreve
Copy link
Author

It is also a more generic solution to
#1236
because it allows for telling apart the selected item (like an index result would) for all the other widgets using an "items=()" list without adding a parameter.

@v-ein
Copy link
Contributor

v-ein commented Feb 21, 2024

DPG cannot really convert Python objects to strings when the listbox is rendered (because it doesn't hold GIL at that point). This means Python objects would have to be converted to strings somewhere else, just like now they are converted on creation and on configure_item calls. If the objects are mutable, this might lead to undesired (and unexpected) effects.

Given that it's pretty easy to make your own custom listbox using child_window and add_selectable, I don't really see much sense in complicating the existing listbox implementation with references to Python objects and all that.

The PR #1995 (when corrected and merged) is supposed to provide an index of the selected item, which allows you to store your list of Python objects separately and to retrieve the selected object by index. IMHO this would be a more elegant solution to your problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
state: pending not addressed yet type: bug bug
Projects
None yet
Development

No branches or pull requests

2 participants