Python/ttk/tKinter - getting the value of a Checkbox - python

Following the TkDocs Tutorial (http://www.tkdocs.com/tutorial/widgets.html#checkbutton) I am trying to set up a check box, but I can't follow exactly what I should be doing to 'get' the toggled value.
self.valAStatus = StringVar()
self.checkA = ttk.Checkbutton(self.mainframe, text='A', command = lambda: self.getStatus(self.boxA, "A"),variable=self.valAStatus, onvalue='letter', offvalue='colour')
and
def getStatus(self, boxRef, value):
boxRef.insert(1, value)
What I'm not sure on is how to get the either onvalue or offvalue from the self.checkA object
I'm not sure if I am looking at the StringVar self.valAStatus
(that results in PY_VAR0 and has no attribute onvalue) or if I should be looking at the self.checkA object (that results in .40972728.40972656.40972800.41009024 and has no attribute onvalue).
I've probably missed something in the docs, but if anyone could point out what its doing, so I can get the (on|off)value I'd be obliged..

The answer is self.valAStatus.get() which returns the value associated to that check box (in this case, self.valAStatus).

Related

Tkinter: Getting Canvas Attribute and Options Values

I imagine this is a fairly basic Tkinter question - but I am a noob and I haven't seen this answer after some searching.
I would like to be able to check what the attribute of my canvas is in Tkinter.
So,
canvas = tk.Canvas(root, 200,200, bg="blue")
canvas2 = tk.Canvas(root, 200,200, bg="red")
canvases = [canvas, canvas2]
What I am looking for is something to check what the attribute is of the canvas. For example -
for canvas in canvases:
if canvas.get_color() == "red": # IS THERE SOMETHING LIKE get_color... or get_attr(bg)?
print("HECK YA")
else:
print("I'm feeling blue")
Thanks for the help!
you can call canvas.config('attribute') to obtain the value of a given attribute.
For instance canvas.config('bg') returns the value of the background.
Calling canvas.config() without arguments will return a dictionary of the current configuration
Universal Widget methods that relate to configuration of options:
The methods are defined on all widgets. In the descriptions, w can be any widget of any type.
w.cget(option): Returns the current value of option as a string. You can also get the value of an option for widget w as w[option].
w.config(option=value, ...)
Same as .configure().
w.configure(option=value, ...)
Set the values of one or more options. For the options whose names are Python reserved words (class, from, in), use a trailing underbar: 'class_', 'from_', 'in_'.
You can also set the value of an option for widget w with the statement w[option] = value
If you call the .config() method on a widget with no arguments, you'll get a dictionary of all the widget's current options. The keys are the option names (including aliases like bd for borderwidth). The value for each key is:
for most entries, a five-tuple: (option name, option database key, option database class, default value, current value); or,
for alias names (like 'fg'), a two-tuple: (alias name, equivalent standard name).

python checkbutton appearance does not update after setting to 1

I have a class with a member self.checkbutton (using the TkInter CheckButton), created in the init function with:
self.checkbutton = Checkbutton(self.frame, variable=self.value, command=self.get_entry_and_execute, onvalue="1", offvalue="0")
Now, instead of clicking on the checkbutton in my frame, I want to set it in my code. So, from somewhere in my code, I call setvalue("1") calling this function:
def setvalue(self, value):
if (value == "1"):
print "SELECTING CHECKBUTTON"
self.checkbutton.select()
# self.checkbutton.set(value=1)
Now, when I do this, actually, I can see that the associated "self.get_entry_and_execute" function is called and it even changes some background color. But, the checkbutton remains unchecked (i.e. an empty field without the "V" symbol).
Weirly, when I add the command
self.checkbutton.set(value=1)
, the code complains: AttributeError: Checkbutton instance has no attribute 'set'
but now the checkbutton does get checked!
I am assuming that because of this error, python puts the checkbutton in the correct state (=1) even though the "set" function does not exist. My question is: how can I correctly make python put the "V" inside the checkbutton box? (I.e, something like a "redraw" function).
According to your code, self.value is an instance of a variable class, so all what you need to do is to replace self.checkbutton.set(value=1) by self.value.set(value=1)

Sending a Class' attribute to an outside function in the function call

I'm trying to generalise a function in my script by sending in the Class' attribute through the function call to an outside function, but since I have to call the attribute self.attribute_name inside the class and object_name.attribute.name outside it, I either get an error that no self.attribute_nameexists outside the code or that no object_name.attribute.nameexists inside. The part of my code concerned is as follows(this is just a fragment of the full code with many parts omitted):
class My_Window:
self.get_info_box = Entry(root)
self.entry_button = Button(root, text="Choose", command =lambda: self.retrieve_input(self.get_info_box, solitaire.cards))
def retrieve_input(self, box, entity):
self.user_input = box.get()
entity = input_check(box)
def input_check(which_box): # Function outside class
my_window.which_box.delete(0, "end") # This is want I would like to do if it worked
return 0
my_window = My_Window()
Something in the back of my head tells me it might be possible to use lambda again to accomplish this but I'm still not sure how to use them properly and I couldn't find any active questions covering this specific case.
Anyone have any ideas how to work this out?
I think what you want is
def input_check(which_box):
getattr(my_window,which_box).delete(0, "end")
return 0
input_check("get_info_box")
but its hard to tell for sure
Try it without the my_window.
def input_check(which_box):
which_box.delete(0, "end")
return 0
Incidentally, entity = input_check(box) won't cause solitaire.cards to retain the value returned by input_check, because assignment doesn't propagate upwards like that. If you want to change solitaire.cards, you'll need to do solitaire.cards = input_check(box) instead. If solitaire isn't visible inside retrieve_input, then you'll need to make it an attribute of self.

How to see if a widget exists in Tkinter?

Now, I know that you can check to see if a window exists by:
x.winfo_exists()
which returns a Boolean. More exactly, I need to check the existence of my buttons, labels, list boxes, sliders etc. Then what?
winfo_exists returns 1 unless you have destroyed the widget, in which case it returns 0. This method can be called on any widget class, not only the Tk root or Toplevels. Alternatively, you can get all the children of a widget with winfo_children:
>>> import Tkinter as tk
>>> root = tk.Tk()
>>> label = tk.Label(root, text="Hello, world")
>>> label.winfo_exists()
1
>>> root.winfo_children()
[<Tkinter.Label instance at 0x0000000002ADC1C8>]
>>> label.destroy()
>>> label.winfo_exists()
0
>>> root.winfo_children()
[]
You can also print the type i.e.. type(label). This can be helpful to provide not only existence, but also find if anything is coming up 'NoneType' without an error. The type() will tell you if you have an instance, or other type that can provide valuable clues as to how close the program is performing or returning items to what you think you are asking! The object.winfo_exists() and object.winfo_children is specific, and will throw an error if the object is not a type 'instance'.

Python: Dynamic attribute name generation without exec() or eval()

I'm trying to dynamically create buttons at runtime with PyQT4.7
However, this being my first python program I'm not sure how to get the functionality I want.
I would like to be able to substitute a text string for an attribute name:
i.e.
for each in xrange(4):
myname = "tab1_button%s" % each #tab1_button0, tab1_button1, tab1_button2
#self.ui.tab1_button0 = QtGui.QPushButton(self.ui.tab) <--normal code to create a named button
setattr(self.ui,myname,QtGui.QPushButton(self.ui.tab)) #rewrite of line above to dynamicly generate a button
#here's where I get stuck. this code isn't valid, but it shows what i want to do
self.ui.gridLayout.addWidget(self.ui.%s) % myname
#I need to have %s be tab1_button1, tab1_button2, etc. I know the % is for string substituion but how can I substitute the dynamically generated attribute name into that statement?
I assume there's a basica language construct I'm missing that allows this. Since it's my first program, please take it easy on me ;)
If I interpreted this correctly, I think what you want is this:
self.ui.gridLayout.addWidget(getattr(self.ui,myname))
Give that a go. In Python the following two statements are functionally equivalent (from the link below):
value = obj.attribute
value = getattr(obj, "attribute-name")
For extra context:
http://effbot.org/zone/python-getattr.htm
Just assign the button to a variable so you can both set the attribute and add the widget.
for i in range(4):
name = 'button%d' % i
button = QtGui.QPushButton(...)
setattr(self, name, button)
self.ui.gridLayout.addWidget(button)
Personally I would add the buttons to a list instead of giving them different names.
I think you might benefit from knowledge of lists (commonly called arrays in other languages)
self.buttons = [None, None, None, None]
for each in xrange(4):
self.buttons[each] = QtGui.QPushButton(self.ui.tab)
self.ui.gridLayout.addWidget(self.buttons[each])
For a tutorial on Python lists:
http://effbot.org/zone/python-list.htm

Categories

Resources