im trying to show a dropdown input based on the selected item in a "main" dropdown.
dropdown main is numberer from 0 to 5
i need that on selection of for example 3 it opens bellow 3 dropdown inputs
this can easily be done with jquery but im making a small app 100% python
this is what i got so far
labdrop = Label(frmConf,width="18", text="Test:", anchor='w')
labdrop.pack(side=LEFT)
options = ['1', '2', '3', '4', '5',]
clicked = StringVar()
clicked.set(options[0])
drop = OptionMenu(frmConf, clicked, *options, command=slotstypes)
drop.pack(anchor=W)
def slotstypes():
i=int(1)
a = int(clicked.get(options))
print(a)
while i < a:
labdrop = Label(frmConf, width="18", text="got it", anchor='w').pack(side=LEFT)
i += 1
got this error
a = int(clicked.get(options))
AttributeError: 'str' object has no attribute 'get'
thanks in advance
done it
labdrop = Label(frmConf,width="18", text="Test:", anchor='w')
labdrop.pack(side=LEFT)
options = ['1', '2', '3', '4', '5',]
clicked = StringVar()
clicked.set(options[0])
drop = OptionMenu(frmConf, clicked, *options, command=slotstypes)
drop.pack(anchor=W)
def slotstypes():
i=int(1)
a = int(clicked)
print(a)
while i < a:
labdrop = Label(frmConf, width="18", text="got it", anchor='w').pack(side=LEFT)
i += 1
Related
I'd like to be able to add a new tuple on top of the ones already generated in col1, col2 and col3 for a and b datasets, respectively. I have been looking into various loop setups and list comprehensions, yet I do not seem to find what I am looking for. This is the code I am currently using to generate two tuples (you'll have to excuse the potentially clumsy beginner approach):
kv = '''
<Launch>:
BoxLayout:
Button:
size:(80,80)
size_hint:(None,None)
text:"......"
on_press: root.build()
'''
class MyDf(App):
def __init__(self):
super().__init__()
self.a_num = []
a = pd.DataFrame(columns=['col1', 'col2', 'col3'])
a['col1'] = pd.DataFrame(np.random.randint(0, 50, size=1))
a['col2'] = pd.DataFrame(np.random.randint(0, 50, size=1))
a['col3'] = pd.DataFrame(np.random.rand(1))
self.a_num = pd.DataFrame(a)
self.a_limit = a[(a.col3) < 1 & (a.col3 > 0.8)]
self.a_df = tuple(a.itertuples(index=False, name=None))
self.a_arrayed = np.array(self.a_num)
b = pd.DataFrame(columns=['col1', 'col2', 'col3'])
b['col1'] = pd.DataFrame(np.random.randint(0, 50, size=1))
b['col2'] = pd.DataFrame(np.random.randint(0, 50, size=1))
b['col3'] = pd.DataFrame(np.random.rand(1))
self.b_num = pd.DataFrame(b)
self.b_limit = b[(a.col3) < 1 & (b.col3 > 0.8)]
self.b_df = tuple(a.itertuples(index=False, name=None))
self.b_arrayed = np.array(self.b_num)
self.a_arrayed = self.a_num.append(b)
def press(self,instance):
from pprint import pprint
pprint(self.a_arrayed) # self.df, self.limit,
def build(self):
butt=Button(text="...")
butt.bind(on_press=self.press) #dont use brackets while calling function
return butt
MyDf().run()
The code subsequently laumches a kivy window showing a big button. Pressing that button code delivers randomly defined values displayed in above listed col's, e.g.
col1 col2 col3
0 46 20 0.501363
0 41 10 0.515129
col1 col2 col3
0 46 20 0.501363
0 41 10 0.515129
My problem is that it repeats the same values every time I press the kivy button, and I want it to add a new randomly defined set of values for every time I click the kivy button. I assume kv code is not relevant here, since solution to my issue is solely nested in some kind of 'for i in ....range' setup.
Any support out there is appreciated...;o)
I'm trying to create a dictionary object like below using the input file data structure as below, During conversion inner object is being replicated. Any advise what fix is needed for desire output
input file data:/home/file1.txt
[student1]
fname : Harry
lname : Hoit
age : 22
[Student2]
fname : Adam
lname : Re
age : 25
expected output :
{'Student1' : {'fname' : 'Harry', 'lname' : 'Hoit', 'Age' : 22},
'Student2' : {'fname' : 'Adam', 'lname' : 'Re', 'Age' : 25}}
def dict_val():
out = {}
inn = {}
path= '/home/file1.txt'
with open(path, 'r') as f:
for row in f:
row = row.strip()
if row.startswith("["):
i = row[1:-1]
# inn.clear() ## tried to clean the inner loop during second but its not correct
else:
if len(row) < 2:
pass
else:
key, value = row.split('=')
inn[key.strip()] = value.strip()
out[i] = inn
return out
print(dict_val())
current output: getting duplicate during second iteration
{'student1': {'fname': 'Adam', 'lname': 'Re', 'age': '25'},
'Student2': {'fname': 'Adam', 'lname': 'Re', 'age': '25'}}
With just a little change, you will get it. You were pretty close.
The modification includes checking for empty line. When the line is empty, write inn data to out and then clear out inn.
def dict_val():
out = {}
inn = {}
path= 'file.txt'
with open(path, 'r') as f:
for row in f:
row = row.strip()
if row.startswith("["):
i = row[1:-1]
continue
# when the line is empty, write it to OUT dictionary
# reset INN dictionary
if len(row.strip()) == 0:
if len(inn) > 0:
out[i] = inn
inn = {}
continue
key, value = row.split(':')
inn[key.strip()] = value.strip()
# if last line of the file is not an empty line and
# the file reading is done, you can check if INN still
# has data. If it does, write it out to OUT
if len(inn) > 0:
out[i] = inn
return out
print(dict_val())
When you do out[i] = inn you copy the reference/pointer to the inn dict. This means that when the inn dict is updated in the later part of the loop, your out[1] and out[2] point to the same thing.
to solve this, you can create deepcopy of the inn object.
ref : Nested dictionaries copy() or deepcopy()?
I would work the nested dictionary all at once since you're not going that deep.
def dict_val(file):
inn = {}
for row in open(file, 'r'):
row = row.strip()
if row.startswith("["):
i = row[1:-1]
elif len(row) > 2:
key, value = row.split(':')
inn[i][key.strip()] = value.strip()
return inn
print(dict_val('/home/file1.txt'))
Python drop down menu changes order each time it is ran and removes one choice each time. How do you fix this.
from tkinter import *
from tkinter.ttk import *
root = Tk()
root.title("Menu")
menu = Frame(root)
menu.pack(pady = 5, padx = 50)
var = StringVar(root)
list = {
'1',
'2',
'3',
'4',
}
option = OptionMenu(menu, var, * list)
var.set('Select')
option.grid(row = 1, column = 1)
root.mainloop()
Do not use a set (an unordered structure) to define your options, use a list, e.g.:
options = [ # notice the square bracket
'1',
'2',
'3',
'4'
]
option = OptionMenu(menu, var, options[0], *options) # make sure you define a proper default
# etc.
As for the removal of the first element - it was happening because you didn't define the third argument to OptionMenu which sets the default value so your first options element was expanded into it.
P.S. It's a very, very bad idea to name your variables/functions the same name as built-in types (e.g. list in your case).
I created a working sign-out script using Python3 / tkinter. To finish it, I am trying to transfer the name of a button to a new window, then to a txt file.
In my sign-out program, when the person clicks on a category button, it opens a corresponding items.txt file and then creates a new window with a button for each item in the file. When one of the item button is clicked, a sign-out window is created with an Entry box for their name and a ‘Submit’ button. When the submit button is pressed, I want it to write the item name, person’s name, date, and time to a sign-out text file.
The answers I have found so far talk about a field of buttons that are created (like in Minesweeper).
Since these are no static buttons, I don’t know how to determine which button was pressed and what item name was assigned to that button. The names and the number of items in the file changes.
I tried to make the ‘name’ global in the button_click_pk section but it only returns the name of the last button created. I don’t know if it’s related, but it incorrectly puts the name on a different line.
Item Five
Jane Smith 2016-12-19 10:30:53
I want it to show on one line:
Item Five Jane Smith 2016-12-12 13:30:53
How do you tie a name to a button created in a for loop from a txt file?
class Writefiles:
def __init__(self):
global win3
win3 = Tk()
self.VarEnt = StringVar()
self.lab = Label(win3, text = "Signature")
self.lab.grid(padx = 10, pady = 10)
self.ent = Entry(win3, font = ('Lucida Handwriting', 10), textvariable = self.VarEnt, bd = 5, width = 45)
self.ent.focus()
self.ent.grid(padx = 10, pady = 10)
self.btn = Button(win3, text = 'Submit', width = 10, height = 2, background = 'gold', command = self.write_to_file)
self.btn.grid(padx = 10, pady = 10)
def write_to_file(self):
date = datetime.now().strftime(' %Y-%m-%d %H:%M:%S')
with open('sig.txt', 'a') as f:
f.write(name + self.ent.get() + date + '\n')
f.close()
win3.destroy()
def button_click_pk(): # creates the buttons from text file
global name
win2 = Tk()
file = open('item.txt', 'r')
rw = 0
cl = 0
for name in file:
b1 = Button(win2, text = name, wraplength = 100, width = 18, height = 5, background = 'gold', command = Writefiles)
b1.grid(row = rw, column = cl, padx = 11, pady = 13)
cl += 1
if cl == 4:
cl = 0
rw += 1
After 2 days and MANY errors, I finally figured out that I had to make 2 lambdas. You need one in the button_click_pk function to pass it to the Class, and a second in the Class to pass it to the write_to_file function. A hint that I would need to make 2 lambdas would have made it much easier, it’s not something that is explained in any of the lambda documentation I found.
I have an OptionMenu in tkinter. The options in the menu are keys from a dictionary. The value of each key is a list that contains 4 items.
How do I use the selected menu option to assign the 4 items to separate variables?
from tkinter import *
root = Tk()
options = {'option 1' : ['list item 1' , 'list item 2' , 'list item 3' , 'list item 4'] , 'option 2' : ['list item w' , 'list item x' , 'list item y' , 'list item z']}
options = sorted(options)
var = StringVar(root)
var.set('Choose an option')
option = OptionMenu(root, var, *options)
option.pack()
selection = StringVar()
def changeOption(*args):
newSelection = options[var.get()]
selection.set(newSelection)
var.trace('w', changeOption)
variable1 = # if option 1 was selected from the menu then this variable would contain list item 1
variable2 = # if option 1 was selected from the menu then this variable would contain list item 2
variable3 = # if option 1 was selected from the menu then this variable would contain list item 3
variable4 = # if option 1 was selected from the menu then this variable would contain list item 4
root.mainloop()
You have to do it in function change_option, not in main part.
Main part only create windows/GUI and starts mainloop(). And then mainloop() controls everything - it executes function change_option when you change option in OptionMenu.
You can use your var.get() or first argument send by command= to get key and then you can get data from dictionary.
But you can't assign sorted() to options because sorted() returns only list of sorted keys and you loose access to oryginal dictionary.
keys = sorted(options)
Full code:
from tkinter import *
# --- functions ---
def change_option(*args):
# selected element
print(' args:', args)
print('var.get():', var.get())
# get list from dictionary `options`
data = options[var.get()]
data = options[args[0]]
print(' data:', data[0], data[1], data[2], data[3])
# if you really need in separated varaibles
variable1 = data[0]
variable2 = data[1]
variable3 = data[2]
variable4 = data[3]
print('variables:', variable1, variable2, variable3, variable4)
print('---')
# --- main ---
root = Tk()
options = {
'option 1': ['list item 1', 'list item 2', 'list item 3', 'list item 4'],
'option 2': ['list item w', 'list item x', 'list item y', 'list item z']
}
keys = sorted(options) # don't overwrite `options` - sorted() returns only keys from dictionary.
var = StringVar(root)
var.set('Choose an option')
option = OptionMenu(root, var, *keys, command=change_option)
option.pack()
root.mainloop()
results:
args: ('option 1',)
var.get(): option 1
data: list item 1 list item 2 list item 3 list item 4
variables: list item 1 list item 2 list item 3 list item 4
---
args: ('option 2',)
var.get(): option 2
data: list item w list item x list item y list item z
variables: list item w list item x list item y list item z
---
You can use command option of OptionMenu. That command executes everytime you choose an option from dropdown.
from tkinter import *
root = Tk()
def change_vars(e):
for i in range(len(options[var.get()])):
vars[i].set(options[var.get()][i])
#these two prints added for debugging purposes
#to see if we are getting and setting right values
print(options[var.get()])
for item in vars:
print(item.get())
options = {'option 1':['list item 1','list item 2','list item 3','list item 4'] , 'option 2':['list item w','list item x','list item y','list item z']}
var = StringVar(root)
var.set('Choose an option')
option = OptionMenu(root, var, *options, command=change_vars)
option.pack()
vars = [StringVar() for _ in range(len(options[0]))] #creates a list of 4 stringvars
root.mainloop()
In here, instead of hardcoding all variables, I created them in a loop and stored them in a list.