pfalcon / picotui

Lightweight, pure-Python Text User Interface (TUI) widget toolkit with minimal dependencies. Dedicated to the Pycopy project.
https://github.com/pfalcon/pycopy
MIT License
811 stars 70 forks source link

WDropDown: Set lines show and get selected value #12

Closed peterjschroeder closed 7 years ago

peterjschroeder commented 7 years ago

Is it possible to change the amount of lines shown in the drop down list from 3 to something else? Also, how do you get the value of the currently selected item?

pfalcon commented 7 years ago

Is it possible to change the amount of lines shown in the drop down list from 3 to something else?

Implemented in https://github.com/pfalcon/picotui/commit/d9034f27b508f2ef68a0b32988f57e0320eb1134

pfalcon commented 7 years ago

Also, how do you get the value of the currently selected item?

Picotui is written with following ideas in mind: a) the best documentation is executable documentation (i.e. the source code itself); b) Python is very readable language, so every Python programmer enjoys reading Python code. It shouldn't take more than a minute to figure that the current index of selected item for WDropDown is stored in self.choice, and given that the original items list is saved in self.items, you can index it: https://github.com/pfalcon/picotui/blob/master/picotui/widgets.py#L372

peterjschroeder commented 7 years ago

Thank you for implementing that option.

I am a semi-beginner with python. I struggled with urwid for many hours to get some things displayed, just to find out there are no dropdown menus :-/ Than I came across your library and was able to display everything I needed easily.

The keyword wasn't what I was really looking for. How to point to it is what I can't figure out.

Example from my code:

    d.add(2, 5, "Height:")
    c.execute('SELECT Height FROM ' + table_name + ' WHERE Height IS NOT NULL AND Height <> ""')
    heights = list(set(c.fetchall()))
    heights.sort()
    heights.insert(0, ('All',))
    d.add(16, 5, WDropDown(20, ["%s" % items[0] for items in heights], dropdown_h=round(cheight/4)))

I need to get the value here

d.add(round(cwidth/2), cheight-6, "Height: %s", Pointer)

I tried d.choice and d.items. Neither of them point to anything.

I also tried

    m = WDropDown(20, ["%s" % items[0] for items in heights], dropdown_h=round(cheight/4))
    d.add(16, 5, m)
    d.add(round(cwidth/2), cheight-6, "Height %s:" % m.choice)

But it always returns 0 and doesn't change when I arrow up and down.

Any pointers would be appreciated.

pfalcon commented 7 years ago

Sorry, from code snippets above, I'm not sure what you'd like to achieve. Can you explain that in plain words (better, itemized, 1) ... 2) ... 3) ... ) ?

peterjschroeder commented 7 years ago

1) Display a label for the listbox.

d.add(2, 5, "Height:")

1.5) The listbox list of items is assembled from a sqlite table, that is what this stuff is

c.execute('SELECT Height FROM ' + table_name + ' WHERE Height IS NOT NULL AND Height <> ""')
heights = list(set(c.fetchall()))
heights.sort()
heights.insert(0, ('All',))

2) Setup and display the listbox.

d.add(16, 5, WDropDown(20, ["%s" % items[0] for items in heights], dropdown_h=round(cheight/4)))

3) Display the current selected listbox item somewhere else on the screen.

d.add(round(cwidth/2), cheight-6, "Height: %s", Pointer)

3 is where I am stuck, I can't figure out what the Pointer would be.

My WIP source is attached. Figure Finder.py.txt

pfalcon commented 7 years ago

I see. In Picotui, that would be done using event handlers, but adding support for events is done on as-needed basis. I added it for dropdown in https://github.com/pfalcon/picotui/commit/1f40aa27f501b05b499a3e451123866c3a73ada9 . The usage example for that is coming too, I just need to change few more things to make a good example. Btw, while working on the example, I "noticed" that there's inconsistency in how current selection is accessed in various widgets, so there may be a breaking change to fix that in some next version.

pfalcon commented 7 years ago

Before the example is ready, you can get a rough idea of how event handlers work here: https://github.com/pfalcon/picotui/blob/master/picotui/widgets.py#L526

peterjschroeder commented 7 years ago

Excellent, thank you. A usage example would be greatly appreciated.

peterjschroeder commented 7 years ago

I just realized I gave the wrong example. It was ListBox I was trying to get the current selected value from. But that is okay, the same method could probably be applied to that too.

I've read the different values in the code, and I understand what equals what. What I don't get is how to get them properly.

I create the main screen like so.

d = Dialog(0, 0, cwidth, cheight)

I than add each type of widget

d.add(16, 2, WDropDown(20, ["%s" % items[0] for items in types], dropdown_h=round(cheight/4)))
d.add(2, 3, "Manufacturer:")
d.add(2, 9, WListBox(round(cwidth/2.26), cheight-11, ["%s" % items[0] for items in figures]))

Okay, Now I have a screen with 3 widgets. From what I'm gathering d.add make the widgets children of the main dialog.

The only things I can grab from Dialog, is from the parent. How would I access the children? Is there a pointer from dialog to the children that I've overlooked?

If I do something like this

m = WListBox(round(cwidth/2.26), cheight-11, ["%s" % items[0] for items in figures]) d.add(2, 9, m)

I now have access to the child. So I can do something like this (m.choice). But that is only the current value when I call m = WListBox which would be 0. m is no longer affect, because the dialog is where the real code is at.

pfalcon commented 7 years ago

Ok, an example for using "changed" event is posted at https://github.com/pfalcon/picotui/blob/master/examples/example_on_changed.py .

This ticket already has too many different things covered, so let me close it now. If there're further issues, please open a separate ticket for each.

peterjschroeder commented 7 years ago

Thank you.