Horizontally oriented listbox using Python and Tkinter - python

I want to provide a listbox where the user can select (multiple) characters (usually close to 15). Quite often some of these will be sequenced, so a listbox is easier than a validated text entry field.
Since the character combination has a meaning to the user, it is user friendly to orient the listbox horizontally.
Is there an easy way e.g. a theme, setting or subclass of the Tkinter listbox so I do not have to build my own?

No, there is no setting, subclass or theme that will let you do that with a listbox.
What you might want to use instead is a set of check buttons with the indicator turned off so they each appear as a button with a single letter. You can then pack them all horizontally in a frame. With the indicator off, the button will appear sunken when selected, or normal otherwise.

Related

Python change listbox colors in real time

Win7, Python 2.7, Tkinter
I have several list boxes on the screen at once, and I am setting up a way to let the user change the colors (background, text color, border width, border color, etc...) There are more then just list boxes, there are label frames, progress bars, window frames, to name a few.
The listbox (and other widgets) labels are declared in a globals file, thuis:
globs.lb1 = tk.Listbox(root, ...
I can change the attributes easily enough, but what is the best method to update all the widgets?
Currently, in my Settings.py file, I am manually setting each list box, (and other widgets) but, or course, if I add a widget later, I must remember to change the Settings.py file.
I would like to use ttk, I think ttk allows me to change the style, then ttk will remember which widgets use that style, but there is no Listbox in ttk.
If there were an event or something of that nature I could setup for each list box...
Thanks, Mark.
Option 1: define a subclass of Listbox that registers each listbox you create so that when a user changes settings, you can iterater through the set/list of listboxes.
Option 2: use a ttk.Combobox or a ttk.Treeview (with only top-level items and not expansion for subitems). I think one could think of a treeview as a supercharged listbox, with multiple columns and possible hierarchical relationships.

Tkinter: make a 'disabled' widget look even more 'disabled'

I have this collection of Listboxes (see image). The 2nd and 3rd Listboxes are disabled by default until the user adds an item to the 1st Listbox and selects it, at which point the two other Listboxes can be edited.
Image here
The problem i have is that the 'disabled' state of this Listboxes look too much as a 'normal' one, and im worried it might not be intuitive enough for the user that he must work on the first Listbox first.
Is there a way to make the disabled state of a widget look even more disabled?
I was thinking, maybe change the color of the widget to something more darker... but i'm not a graphic designer so i really have no clue.
Is it even possible to change the appearence of disabled widgets in the first place?
Thanks in advance

Tkinter text widget search and show

i was able to create a text widget with a search, and highlight every finding. The only thing i miss is a button like "Next" which jumps to the next finding.
So far i was not even able to show (jump) to the first finding.
I can move the cursor there, but i cant move the screen.
The text widget has a huge ammount of text, and i use a scrollbars if that can help.
Is there any way to move the screen or scrollbar to the curzor? Or to a tag? Or to a finding?
Thanks, Gábor
You can call the yview methods to scroll the widget by a particular amount. However, for this specific use case the text widget has the see method, which arranges for a given index to be visible.
From the official tcl/tk documentation (upon which Tkinter is built):
[see] Adjusts the view in the window so that the character given by
index is completely visible. If index is already visible then the
command does nothing. If index is a short distance out of view, the
command adjusts the view just enough to make index visible at the edge
of the window. If index is far out of view, then the command centers
index in the window.

Scroll a group of widgets in Tkinter

I want to make a whole column of various widgets scrollable in a Tkinter GUI, like so:
Tkinter can only attach scrollbars to certain widgets, of which, frames are not included. Making a scollable column is a common practice in interfaces, and there should be a simple solution, but so far, all I have been able to find is this hacky example of a scrollable frame, using a canvas widget. A similar hacky solution was used in a similar stack overflow question.
Is there a commonly accepted way in Tkinter to make a column, or a group of widgets, that is scrollable?
The solution using the canvas is the commonly accepted way to solve this problem. It's really not all that hacky, and the end result can be indistinguishable from having a native scrolling container widget.
If you're making a single column, another option is to use a text widget, and use the widget's ability to embed other widgets. Insert a widget, then insert a newline, insert another widget, etc. You then get the scrolling ability for free. The only thing you need to worry about is configuring the width of the embedded windows, which isn't too hard to do.

Change the focus from one Text widget to another

I'm new to Python and I'm trying to create a simple GUI using Tkinter.
So often in many user interfaces, hitting the tab button will change the focus from one Text widget to another. Whenever I'm in a Text widget, tab only indents the text cursor.
Does anyone know if this is configurable?
This is very easy to do with Tkinter.
There are a couple of things that have to happen to make this work. First, you need to make sure that the standard behavior doesn't happen. That is, you don't want tab to both insert a tab and move focus to the next widget. By default events are processed by a specific widget prior to where the standard behavior occurs (typically in class bindings). Tk has a simple built-in mechanism to stop events from further processing.
Second, you need to make sure you send focus to the appropriate widget. There is built-in support for determining what the next widget is.
For example:
def focus_next_window(event):
event.widget.tk_focusNext().focus()
return("break")
text_widget=Text(...)
text_widget.bind("<Tab>", focus_next_window)
Important points about this code:
The method tk_focusNext() returns the next widget in the keyboard traversal hierarchy.
the method focus() sets the focus to that widget
returning "break" is critical in that it prevents the class binding from firing. It is this class binding that inserts the tab character, which you don't want.
If you want this behavior for all text widgets in an application you can use the bind_class() method instead of bind() to make this binding affect all text widgets.
You can also have the binding send focus to a very specific widget but I recommend sticking with the default traversal order, then make sure the traversal order is correct.
It is really simple in PyQt4 simply use this one single line below and you will be able to change focus by pressing tab button:
self.textEdit.setTabChangesFocus(True)
The focus traversal is somewhat customizable, usually letting the X windows manager handle it (with focus follows mouse, or click). According to the manual it should be possible to bind an event to the key press event, for tab presses, and triggering a focusNext event in those cases.

Categories