Dot in a selected radiobutton with bg, fg specified disappears - python

Beginner question: I'm trying to change the colour of my GUI, particularly the radiobuttons. I need inverted colours, so black background, white text.
self.radiobuttonVariable = Tkinter.IntVar()
radiobutton1 = Tkinter.Radiobutton(self, text=u'E', variable = self.radiobuttonVariable,
bg='black', fg='white' activebackground='black', activeforeground='white',
value = 1, command = self.RadioSelect)
radiobutton1.grid(column=2, row=1, sticky='ES')
This looks just fine, but when I press the button, it's the dot is there only as long I'm pressing it, disappears as soon as I let it go. The variable doesn't change, it stays on the right value, just that the dot disappears. No issue whatsoever when I remove the colour-management options. Any ideas?

As far as I can tell, specifying the foreground (presumably for the text) also sets the selected "dot color". You can set the selectcolor attribute of the element to color the "background" of the radiobutton so that you can see the white dot.
For example, selectcolor='red' in Windows:
Be aware that the manpage indicates that coloring all radio buttons with selectcolor (instead of only the selected button) may be Windows-only:
Under Windows, this color is used as the background for the indicator regardless of the select state.
That being said, I got the same effect in linux under Python 2.7 and 3.3:
I just used red to distinguish the part of the widget that selectcolor affected, you'd probably want selectcolor='black' or something a bit lighter to show the depression selectcolor='#222222' (below):

Related

tkinter: button color does not update

The button3 of my GUI is calling a function which takes quite long to calculate stuff. So in the meantime I want to change the buttons text and color:
self.button3.config(foreground='red')
self.button3['text'] = 'PLEASE WAIT ...'
self.button3.update_idletasks()
The text of the button does indeed change, but the color stays the same. Why?
Your button probably remains in its active state during the long calculation. So you may want to set its activeforeground color to red:
self.button3.config(activeforeground='red')
activeforeground = What foreground color to use when the button is
active. The default is system specific. (activeForeground/Background)
(Tkinter Button documentation)

Odd Tkinter mouse-over behavior

I've been trying to get a mouse-over event to change the background color of a butten widget in Tkinter. I got some simple code online which works for text, but fails for color. Here it is:
from Tkinter import *
root - Tk()
b = Button(root, text='foo')
b.pack()
def enterB(event):
b.configure(text='bar', background='red')
def leaveB(event):
b.configure(text='foo')
b.bind('<Enter>', enterB)
b.bind('<Leave>', leaveB)
root.mainloop()
When I put my mouse over the button, the text changes to 'bar', but the background color stays gray. When my mouse leaves the area over the button, the background color changes to red, and the text changes to 'foo'. This is the opposite of what should happen.
If I put background='blue' in the b.configure statement in the leaveB function, and leave the rest the same, leaving the button will leave the button blue, and it will never be red.
Can anyone tell me what's happening?
Thanks.
Firstly, I guess that's a typo on line 2, it should be root = Tk()
That program works properly for me, other than the act that on removing the mouse from the button the background stays red. Which can be changed by slightly modifying leaveB function as follows:
def leaveB(event):
b.configure(text="foo", background="SystemButtonFace")
Where "SystemButtonFace" is the default button face color if you are on Windows
I had the same problem (actually I was bothered with the button color not changing after a click unless you left it with the mouse). The solution was to set the activebackground color. In my understanding this is the color which is shown when the mouse is over the button (see http://www.tutorialspoint.com/python/tk_button.htm)
So what I did was:
def enterB(event):
b.configure(text='bar', background='red')
b.configure(activebackground='red');
This way the button already turns red when the mouse is over it. Of course you have to reset the color in the leaveB function to make it change back to grey once you left the button.
If you are on a Mac, you can't change the background color or relief style of a button. You can change the highlightbackground color, however. This is a limitation of tk on macs, thus I would recommend wx instead.

Python gui - make invisible label visible [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
In Tkinter is there any way to make a widget not visible?
I have a label looks like:
Lab = Label(text = "Update ID")
Lab.pack(side = LEFT)
I want this label invisible but would like to make it visible when particular button is clicked.
I have a button looks like:
Button1 = Button(buttons, text = "Update Item", command = self.Update_item)
Button6.pack(side = LEFT, padx = 5, pady = 3)
I want the label invisible but would like to make it visible when 'Button1' is clicked.
Any feedbacks would be appreciated.
There are a couple ways to accomplish this. For one, you can use the lift and lower attributes to change the stacking order. For example, if the label is a child of a frame and y ou lower it, it will go "behind" the frame and thus become invisible. T
A second option is to completely remove the label from the display. You can use grid_remove if you are using the grid geometry manager. The nice thing about this method is that grid remembers where the widget was, so to restore it you can call widget.grid() and all of the previous options (sticky, row, column, etc) will be used.
There is also pack_forget() and grid_forget(), but they have the disadvantage of truly forgetting about the widget. It is removed from the display and the information about where it was placed is forgotten. This means you must re-apply all of the proper options to get the widget to appear in the same place.

How to changes fonts using ttk themed widgets in windows

On OS X, ttk.Style().configure('TLabelframe.label', font='helvetica 14 bold') works to change the font used by the ttk.LabelFrame widget. On Windows, ttk.Style().configure('TLabelframe.label', font='arial 14 bold') has no effect other than returning the same font info to ttk.Style().lookup('TLabelframe.label','font').
I've tried different font names and formats, creating a derived style, using TkDefaultFont and just changing the size, and different widgets (TButton.label, TCheckbutton.label). So far, no matter what I've tried, it always appears to use TkDefaultFont in the default size.
Changing the font setting in python27/tcl/tk8.5/ttk/xpTheme.tcl (the default theme on windows) does change the font being displayed. Removing the -font TkDefaultFont setting from the theme settings does not change what is displayed.
Any suggestions as to how this actually works?
Edit: I hadn't tried changing the font for the Label widget before, and that one actually works.
I believe the code in this area is buggy and will open a ticket. Using 'TLableframe.Label' (note uppercase 'L' in 'Label' works. 'TButton.label' and 'TButton.Label' don't work, but just 'TButton' does; 'TCheckbutton' is the same. I was unable to change the fonts for 'TEntry' with any combination, including adding 'textarea.'
It looks like for ttk.LabelFrame, you have to create a separate ttk.Label widget, and then assign it to the LabelFrame using the labelwidget= operand. You can set whatever font/style on the Label widget that you desire and that will be reflected in the LabelFrame. Note, you don't call the geometry manager for the Label widget. Just instantiate it, then assign it to the LabelFrame.
This also means that you can assign almost any widget you want, such as a ttk.Checkbutton, if you wanted to control the state of child controls within the LabelFrame. You'd have to write the code for this, but visually, it'd enable/disable the child controls based on the state of the Checkbutton.
Source: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-LabelFrame.html

Create resizable/multiline Tkinter/ttk Labels with word wrap

Is it possible to create a multi-line label with word wrap that resizes in sync with the width of its parent? In other words the wordwrap behavior of Notepad as you change the width of the NotePad window.
The use case is a dialog that needs to present a block of multi-line text (instructions) in its entirety without having the text clipped or resorting to scrollbars. The parent container will have enough vertical space to accomodate narrow widths.
I've been experimenting with Tkinter Label and Message widgets and the ttk Label widget without success. It seems that I need to hard code a pixel wraplength value vs. have these controls auto wordwrap when their text reaches the right edge of their containers. Certainly Tkinters geometry managers can help me auto-resize my labels and update their wraplength values accordingly?
Should I be looking at the Text widget instead? If so, is it possible to hide the border of a Text widget so I can use it as a multi-line label with wordwrap?
Here's a prototype of how one might do what I described above. It was inspired by Bryan Oakley's tip to use the Text widget and the following post on Stackoverflow:
In python's tkinter, how can I make a Label such that you can select the text with the mouse?
from Tkinter import *
master = Tk()
text = """
If tkinter is 8.5 or above you'll want the selection background to appear like it does when the widget is activated. Comment this out for older versions of Tkinter.
This is even more text.
The final line of our auto-wrapping label that supports clipboard copy.
""".strip()
frameLabel = Frame( master, padx=20, pady=20 )
frameLabel.pack()
w = Text( frameLabel, wrap='word', font='Arial 12 italic' )
w.insert( 1.0, text )
w.pack()
# - have selection background appear like it does when the widget is activated (Tkinter 8.5+)
# - have label background color match its parent background color via .cget('bg')
# - set relief='flat' to hide Text control borders
# - set state='disabled' to block changes to text (while still allowing selection/clipboard copy)
w.configure( bg=master.cget('bg'), relief='flat', state='disabled' )
mainloop()
Use Message widget:
The Message widget is a variant of the Label, designed to display multiline messages. The message widget can wrap text, and adjust its width to maintain a given aspect ratio.
No, there is no feature built-in to Tk to auto-word-wrap labels. However, it's doable by binding to the <Configure> event of the label and adjusting the wrap length then. This binding will fire every time the label widget is resized.
The other option, as you suggest, is to use a text widget. It is possible to entirely turn off the border if you so desire. This has always been my choice when I want word-wrapped instructional text.
Here is the code:
entry = Label(self, text=text,
anchor=NW, justify=LEFT,
relief=RIDGE, bd=2)
def y(event, entry=entry):
# FIXME: make this a global method, to prevent function object creation
# for every label.
pad = 0
pad += int(str(entry['bd']))
pad += int(str(entry['padx']))
pad *= 2
entry.configure(wraplength = event.width - pad)
entry.bind("<Configure>", y )
The tkinter.Message widget suggested by some people does NOT use TTK styling, which means that it's gonna look like garbage inside a TTK (themed) interface.
You could manually apply the background and foreground colors from your TTK theme to the tkinter.Message (by instantiating ttk.Style() and requesting the active themes' TLabel foreground and background colors from that style object), but it's not worth it... because the ancient Message widget has ZERO advantages over TTK's regular ttk.Label.
The tkinter.Message widget has an "aspect ratio" property that defines how many pixels until it wraps.
The ttk.Label instead has a wraplength= property which determines how many pixels until the words wrap. You should also use its anchor= and justify= properties to customize it to your exact desires. With these properties you can make your Label behave as the old Message widget did.
Example: ttk.Label(root, text="foo", wraplength=220, anchor=tkinter.NW, justify=tkinter.LEFT). Creates a beautifully styled label which permanently wraps its text after 220 pixels wide.
As for automatically updating the wraplength? Well, you should attach to the <Configure> event as people have said... However, if you have a completely fluid window (which resizes itself to fit all content), or a grid/frame that is fluid and contains the label, then you can't automatically calculate it that way, because the parent WINDOW/CONTAINER itself will EXPAND whenever the label grows too wide. Which means that the label will always resize itself to the maximum width it would need to fit all text. So, updating wraplength automatically is only possible if the label itself has some constraints on how wide it can grow (either via its parent container being a fixed size/maxsize, or itself being a fixed size/maxsize). In that case, sure, you can use configure to calculate new wrapping numbers to make sure the text always wraps... However, the example code by t7ko is broken and not valid anymore, just fyi.

Categories