Issue with getting value of checkboxes tkinter - python

I'm trying to get the value of checkboxes in tkinter so I can have the data from those checkboxes exported into a excel spreadsheet
I've tried having the checkboxes generate iteratively (as they are presently) and making them manually, but no matter what I do, can't get them to give me their values (whether they are checked or not) and it's really stressing me out.
def check():
for movie in movies():
print(button.get())
Button(moviewindow,text="Check",command=check).pack(anchor=S)
for movie in movies():
var1 = IntVar()
button = Checkbutton(moviewindow,
bg=moviewindow_bg,
font=("Times",23),
onvalue=1,
offvalue=0,
text=movie.replace("<strong>","").replace("</strong>",""),
variable=var1).pack(anchor=W)
I expect the code to print either 1 or 0, but I cant get the checkboxes to return their values.

You need to store your variables (and possibly, buttons) somewhere. What's happening currently is this:
You create a Button that runs the function check. Inside check, you iterate over movies, and try to get the value from button. You should be getting the value from var1, but that's not the chief issue here. The main problem is that var1 only contains the very last IntVar created, so the loop will only repeat the value of the last checkbox you created.
Without knowing what kind of an object movie is, it's hard to say the best way to proceed here. If movie is a class object, you could perhaps change its properties. If it's a hashable object, here's what you can do.
Somewhere above your code: Create a dict for association between movies and vars
checkbox_vars = {}
Fix check to use this dict
def check():
for movie in movies():
print(checkbox_vars[movie].get())
Within your loop, store the variable in the dict
var1 = IntVar()
# Store the variable in checkbox_vars, for this specific movie
checkbox_vars[movie] = var1
This is still a somewhat inelegant way to do it, but it should illustrate how you need to actually create an association between button/var1 and movie yourself instead of it being implicit.

Use var1.get() to get the current value of the checkbox.
To print the value as soon as the check button is updated, use it inside the button's invoke method.

Related

asigning ids in kivy on the python side

im using kivy. the what im trying to do is have and 'idea',a slider and a label containing the slider's current value in a row in a grid layout
now getting the layout is fine but getting the label to have a text value the same as the slider's current value is tricky. I'm trying to use string concation to refer to the label with the same number suffix as the slider that it is paired with.
I think the problem im having is that im trying to assign ids on the python side when they normally have to be done on the kv side. It's either that or the fact the ids i'm assigning are strings when kv would normally expect plain text. any help would be appreciated
class ScatterTextWidget(FloatLayout):
def run_me(self):
r=1
main_list=self.ids.main_list
main_list.clear_widgets()
main_list.height=0
for idea in imported_ideas:
main_list.add_widget(Label(text=idea,color=(0,0,0,1),id='idea_label_'+str(r)))
main_list.add_widget(Slider(id='Slider_'+str(r),min=0,max=10,value=5, step=1,on_value_pos=self.slider_slid(self)))
main_list.add_widget(Label(color=(0,0,0,1),id='value_label_'+str(r)))
value_label=self.ids['value_label_'+str(r)] # get this working and then apply the method into slider slid
value_label.text='xxx'
main_list.height+=35
r +=1
button_1=self.ids.button_1
button_1.text='Begin'
button_1.bind(on_press=self.begin)
def slider_slid(self,sender):
s=str(sender.id)
value_label=self.ids['value_label_'+str(s[12:])]
value_label.text=str(sender.value)
value_label=self.ids['value_label_'+str(s[12:])]
KeyError: 'value_label_'
self.ids only collects ids from children in the kv language rule of the widget. It doesn't know about widgets you added via python.
You don't need to use the id though. In this case you could keep e.g. a dictionary of id -> widget keys.
self.keys_dict = {}
for idea in imported_ideas:
new_widget = Label(color=(0,0,0,1),id='value_label_'+str(r)))
main_list.add_widget(new_widget)
self.keys_dict['value_label_' + str(r)] = new_widget
Then later you can access it with self.keys_dict['value_label_' + str(s[12:])] or whatever you like.
I suppose in practice you could also modify the actual ids dictionary in the same way, though I subjectively feel it is preferable to maintain your own dictionary with a name that represents its more specific contents.

Kivy dynamic widget issue

Well, i'm a beginner using kivy framework, so i thought that someone here could help me.
My question is:
On my app, the user input a number n, then the app return n TextInput widgets. But how can i use the values inserted on each TextInput? The first part is easy to do, i did it by a list. (If someone know how to do it directly on kv file i would appreciate it). My issue is on second part, i need to use and manipulate these values (in TextInputs) later but i can't reach to them. I mean, i set up for each widget in the list an id, but i can't reach to .text attribute of them. Here is a piece of my code:
class FirstLayout(BoxLayout):
def next_layout(self):
self.clear_widgets()
secondLayout = Factory.SecondLayout()
number = NumericProperty()
# This 'number' variable came from another widget on kv file
textinput_list = []
# That list will receive as many TextInputs field as my variable 'number' said (by the loop for)
for i in range(int(self.number.text)):
textinput_list.append(TextInput())
textinput_list[i].id = "input" + str(i + 1)
# So for each textinput, i added a id named 'inputx' (where x is the number of the current
# iteration) my question resides here. How could i use those values (inside of each textinput
# on this list
# later? Because i'm not creating these widgets (TextInputs) on kv language so i don't know how to
# bind the ids for a new variable directly in .py file
secondLayout.container.add_widget(textinput_list[i])
self.add_widget(secondLayout)
If I understand your question right, you just have to make textinput_list a class variable. So this.
textinput_list = []
becomes
self.textinput_list = []
Lets say you have an object of FirstLayout called first. With first.textinput_list[0] you can access the first textinput and so on.
If you want to easily access the textinputs via id I would suggest using a dictionary, with the keys being the id's and the values being the inputs.

dynamically asigning instances in Python/PyQt4

Ok, this might be a duplicate, but as I couldn't really get anything out of (possibly) similar questions, here is mine: I'm working on a small PyQt4 program where I can enter the name of a song in a QLineEdit and then add a QLabel of it beneath it. I want a button beside each one of these labels that deletes the label when clicked. Relevant code:
def Add(self):
self.rf= QtGui.QLabel(self.le1.text(),self)
self.rf.move(45,30)
self.rf.resize(450,30)
self.rf.show()
self.x = QtGui.QPushButton("X",self)
self.x.move(10,30)
self.x.resize(30,30)
self.x.show()
self.x.clicked.connect(self.Del)
def Del(self):
self.rf.close()
self.x.close()
Now, what I'm not understanding is how I can assign a different instance to each of these dynamically added Qlabels, in order to delete the specific one when the button is clicked.
The best idea I had was creating a variable containing a number that would change with each added QLabel, something like var = rf+str(num) and num = 0, then adding 1 to num for each QLabel and then using getattr for the instances, so getattr(self, var) = Qtgui.QLabel(...), which unfortunately gives me an error that I can't assign that value to the function. And I can't create a dictionary since I have to have different instances for that.
Any ideas would be highly appreciated, thanks a lot.
You could keep them all in a dict and then key that off of the label text. It also provides a quick way to check for duplicates.

storing instances in variables in python

In my Pyqt4 program I want to change the shortcut for some buttons. As I have quite a lot I thought of accessing a button through user input. I copied the relevant code snippets.
self.btn3 = QtGui.QPushButton(self)
b, ok = QtGui.QInputDialog.getText(self, 'Keyboard Mapping',
"Enter button number: ")
so the user would, say, input "btn3", and then in another input dialog he'd specify the new shortcut. Finally, I want to change the button shortcut like this:
self.b.setShortcut(newkey)
I get an error that my QMainWindow Class has no attribute "b".
Is there no way of storing an instance in a variable? Or maybe reading the variable or something? I'd be glad if you can help me...
The issue here is that python doesn't take the value from b for the lookup when you do self.b.setShortcut(newkey), rather, it just looks for the name b.
You can do what you want using getattr():
getattr(self, b).setShortcut(newkey)
However, this is bad style and will generally be unsafe and cause problems. Instead, make a data structure that suits your need - here it would make sense to create a dictionary, for example:
self.widgets = {"btn3": QtGui.QPushButton(self)}
...
self.widgets[b].setShortcut(newkey)

Getting multiple wx widget values with Event Handling

CODE: http://pastebin.com/W4uXmazw
I would like to memorize how to get values from any wx widget with event handling after clicking a wx.Button.
In my program i have two fields, the new filename and the contents.
What are the steps i have to take in order to get the values from each field?
From there, i can use pythons f.open and f.write methods to complete my application.
Thanks!
If you want to get value of a widget, then you need to make that widget accessible throughout the entire class. To do that, you need to make the variable for the widget into an instance variable. So instead of adding the text control directly to the sizer, you'll want to do something like this:
self.newfilename = wx.TextCtrl(panel,-1), 0, wx.TOP, 5)
self.contents = wx.TextCtrl(panel,-1,size=(390,150),style = wx.TE_MULTILINE|wx.TE_PROCESS_TAB)
Then in your button's event handler, you can just do something like this:
valueOne = self.newfilename.GetValue()
contents = self.contents.GetValue()
The other way to do it would be to use your panel. If you use "self.panel", then you could grab all its children via its GetChildren method and then iterate over the list and use Python's "isinstance" builtin to check what kind of widget you're accessing. If you have set the widget's name, you can check that too.

Categories