Textvariable in tkinter CheckButton - python

I'm writing a GUI program where I want to create several check buttons with text from a list. The problem is that I have many lists, and I therefore want the user to be able to go to the "next page" and see a different set of check buttons based on a different list. However, to do this I need some kind of textvariable in my check buttons so the text is updated every time a user goes to the next page. Though, as far as I know, there is no such option.
Is this possible to do, or do I need to create a separate check button and a separate label with the textvariable in it?
Help would be much appreciated. Thanks in advance!

Only possible approach I can think of is doing config on a checkbutton. Assuming you are using standard tk checkbuton, you can call:
checkbutton.config(text=newtext)
where newtext is the new text, obviously.
Add the call to the callback bound to the next and previous page buttons. If you really need to use a variable, add a property to a class based on checkbutton and modify its setter to call the config function on asignment.

Related

Step-by-step tkinter GUI layout

How do I make a step-by-step GUI Layout with Tkinter Python 3.7? What I mean is that I want to have the user enter some information, press the "NEXT" button and enter some more information, etc. I don't think there's really a feasible way to completely change the layout like this with Tkinter, so I'm hoping there's something I'm missing. How do I do this?
I don't think there's really a feasible way to completely change the layout like this with Tkinter,
That is incorrect. This is trivially easy with Tkinter. Create a function or class for each step. All of the widgets for that step should be inside a single frame.
You then just need to call the first function or class to create the frame. When the user clicks "next", destroy the frame and create the next frame. And so on.

How can I create a read-only text widget with TkInter and still be able to modify the widget's content programmatically?

I want to use Tk's text widget to display part of the state of my program. (A label widget will not do, because the tag feature of the text widget will save a lot of work. A canvas widget will not do, because I don't want to have to lay out a lot of text manually.)
I do not want the user to be able to directly modify the contents of the text widget. They can change the state of the program by interacting with it in other ways, but the text widget is for display only.
If I set the state of the text widget to disabled, then not only is the user unable to interact with it, but I also cannot modify its contents programmatically (specifically, I cannot insert text).
The obvious workaround is decorate any code that updates the contents of the text widget with code the enables and disables the widget. But this is kludgy: I should be able to modify the contents without offering the user an opportunity to interfere, however brief that opportunity may be.
Is there a way to do this?
The "kludgy workaround" isn't kludgy at all -- that's exactly how you do it, and how it was designed to work.
However, there is another solution. You can remove all of the built-in key and mouse bindings from the widget, and then re-implement only the ones you care about (for example, you might want the user to highlight and copy a block of text). This is simple and effective, but if you want to restore some of the bindings it starts to become very tedious to re-implement the bindings you care about (cut, copy, paste, page up, page down, moving the cursor, etc).
To remove all of the default bindings you can remove the class bind tag like this:
t.bindtags((t, root, "all"))
For more information about bind tags, see these answers:
https://stackoverflow.com/a/11542200/7432
https://stackoverflow.com/a/3513906/7432
https://stackoverflow.com/a/11459001/7432
you could constantly delete then insert the text like so:
import tkinter
root = tkinter.Tk()
text = tkinter.Text(root, width=40)
text.grid(row=0, column=0, stciky=tkinter.W)
while True:
text.delete(0.0, tkinter.END)
text.insert(tkinter.END, your_text)
where your_text is the text you want to insert

Better Method of Creating Multi Line Text Entry?

I need to create a message box for a user in a GUI with tkinter. For 3/4 of my entries, Entry(master, options. . .,) works. But for a message box, I need a multi line entry.
How would I do this? I tried ScrolledText(root).pack(), but it doesn't have the same commands/variables as Entry.
It is not explicitly mentioned in the documentation, but even if the tkinter.Entry widget's content can be scrolled, it can only be scrolled horizontally meaning that you can not use the yscrollcommandoption unlike with Canvas, Text and Listbox widgets.
This means technically your goal is not feasible, I mean you can not write multiple lines inside an Entry widget so that you scroll them vertically but only horizontally:
(if you need the code of this screenshot, please let me know).
Billal is right, however i would recomend simply using a Textbox.
go to: http://www.tutorialspoint.com/python/tk_text.htm
for more information

Clear whole root

I am new to tkinter and I was wondering if there is a way to clear whole root (window). I tried with root.destroy() , but I want to have a chance to undo(to callback some widgets). I also tried .pack_forget() and .grid_forget() , but it takes a lot of time and later may cause many bugs in program.
Thank you for help.
If you plan on literally destroying everything in the root window, my recommendation is to make a single frame be a child of the root window, and then put everything inside that frame. Then, when you need to clear the root window you only have to delete this one widget, and it will take care of deleting all of the other widgets.
If instead of destroying the widgets you want to merely hide them, the best solution is to use grid, so that you can use grid_forget to remove them from view, and grid to make them visible again. You can use pack and pack_forget, but pack doesn't remember where the widget was, making it more difficult to restore them without a lot of work.
If your program is made of logical groups of widgets, use frames to create the groups, and then you can destroy or call grid_forget on the entire frame at once, rather than having to do that for each individual widget.
for ele in root.winfo_children():
ele.destroy()

On-value-change type of event for widgets or use .trace_variable() technique?

Is there an on-value-change type of event for data input widgets like Entry, Text, Spinner, Checkbutton, Radiobutton? By on-value-change, I mean the ability to detect when the value of a widget has changed due to keyboard input or cut/delete/paste (and Text edit_undo/edit_redo) activity? I see no such event described in the Tkinter event documentation [1].
Is the proper technique to link Tkinter variables to widget values I want to monitor and use these variables' .trace_variable( 'w', ... ) methods to bind to value changes? This seems like the right approach, but I haven't seen a lot of trace_variable() use in the Tkinter application source code that I've studied ... leading me to be cautious about using this approach.
[1] http://infohost.nmt.edu/tcc/help/pubs/tkinter/events.html
Different widgets call for different solutions. For example, check buttons and radio buttons have a command option, and with an entry widget you can use the built-in validation features.
For all the widgets that can be tied to a variable, doing a variable trace is a common solution. The text widget is one exception since you can't associate it with a variable without a lot of effort.
In the tcl/tk world I associate all my widgets to a single array (tcl's name for a hash map / dictionary) and then put a single trace on the array. Unfortunately tkinter doesn't directly support tcl arrays. However, support is somewhat easy to hack in. For more information see my response to this question: How to run a code whenever a Tkinter widget value changes?

Categories

Resources