Python: Tkinter :Dynamically Create Label - python

I am trying to create Label Dynamically , I am getting invalid Syntax. Can you please help me what i am missing or any alternative
crsr = cnxn.execute(query)
row_num=2
column_num=0
Variable_Number=1
for row in crsr.fetchall():
test='Column_Label'+str(Variable_Number)+' = tk.Label(frame,text="'+row[0]+'")'
#proper Indentation availabe in code test1='Column_Label'+str(Variable_Number)+'.grid(row='+str(row_num)+',column='+str(column_num)+')'
eval(test+';'+test1)
# eval(test1)
row_num+=1
column_num+=1
root.update_idletasks()

You should not be using exec. If you want to associate a computed name with a widget in a loop, use a dictionary:
labels = {}
varnum = 0
for row in crsr.fetchall():
name=f"label#{varnum}"
labels[name] = tk.Label(frame, text=str(row[0]))
labels[name].grid(row=row_num, column=column_num
varnum += 1
row_num+=1
column_num+=1
If you don't really care what the name is, you can store the widgets in a list rather than a dictionary, and then reference them using an integer index (eg: labels[0], labels[1], etc).

Use exec() instead eval()
eval will evaluate a expression, not run it like you want.
Think of eval like the argument of a if statement.

Related

how to create variable names dynamically and assigning values in python?

I would like to assign variable (matrices names) dynamically and assigning some values.
Below is the sample code I am trying. The expected output is mat1 and mat2 containing values 1 and 1 respectively.
stri = "mat"
for i in range(1,2):
"_".join([stri, i])=1
I would suggest you don't assign actual variables this way.
Instead just create a dictionary and put the values in there:
stri = "mat"
data = {}
for i in range(1,2):
data["_".join([stri, i])] = 1
If you really want to do that (which I again do absolutely not recommend, because no IDE/person will understand what you are doing and mark every subsequent access as an error and you should generally be very careful with eval):
stri = "mat"
for i in range(1,2):
eval(f'{"_".join([stri, i])}=1')
As noted in RunOrVeith's answer, a Dict is probably the right way to do this in Python. In addition to eval, other (non-recommended) ways to do this including using exec or setting local variables as noted here
stri = "mat"
for i in range(1,3):
exec("_".join([stri, str(i)])+'=1')
or locals,
stri = "mat"
for i in range(1,3):
locals()["_".join([stri, str(i)])] = 1
This define mat_1 = 1 and mat_2 = 1 as required. Note a few changes to your example (str(i) and range(1,3) needed, for python3 at least).

how to assign the variable for python tkinter entry?

I am trying to create a simple 'SOS' puzzle game from Tkinter. I am creating an entry widgets grid using the grid method. Now I want an assigned variables for each entry. I try to do it using for loops but I can't use that variable the proper way. Can you help me? My question idea explain given below digram,
Code
for i in range(5):
for j in range(5):
self.entry=Entry(root,textvariable=f'{i}{j}')
self.entry.grid(row=i,column=j)
self.position.update({f"{i}-{j}":f"{i}{j}"})
enter code here
Instead of creating variables on the go, you should store the widgets made into a list or a dictionary. The list seems more reasonable as you can index it more easily.
Below is a simple, but full example that shows how you can make a 2-D list as well as search this list for the entry object:
from tkinter import * # You might want to use import tkinter as tk
root = Tk()
def searcher():
row = int(search.get().split(',')[0]) # Parse the row out of the input given
col = int(search.get().split(',')[1]) # Similarly, parse the column
obj = lst[row][col] # Index the list with the given values
print(obj.get()) # Use the get() to access its value.
lst = []
for i in range(5):
tmp = [] # Sub list for the main list
for j in range(5):
ent = Entry(root)
ent.grid(row=i,column=j)
tmp.append(ent)
lst.append(tmp)
search = Entry(root)
search.grid(row=99,column=0,pady=10) # Place this at the end
Button(root,text='Search',command=searcher).grid(row=100,column=0)
root.mainloop()
You have to enter some row and column like 0,0 which refers to 1st row, 1st column and press the button. Make sure there are no spaces in the entry. You should not worry much about the searching part, as you might require some other logic. But instead of making variables on the go, you should use this approach and store it in a container.
Also a note, you do not have to use textvariable as here the need of those are totally none. You can do whatever you want with the original object of Entry itself. Just make sure you have the list indexing start from 0 rather than 1(or subtract 1 from the given normal values).

How to use a variable as dictionary key using f-string in python?

I'm trying to print dictionary item value of a dictionary but my item is also an another user input variable. How can I print the selected value with f-string?
option = ''
languages = {'1':'Learn Python', '2':'Learn Java', '3':'Learn C++', '4':'Learn PHP', '5':'Quit'}
option = input('Please choose an option between 1 and 5')
# Following part is not working!!!
print(f'Youve selected {languages["{option}"]}')
# Following part is working!!!
print(f'Youve selected {languages[option]}')
You need use next string: print(f'Youve selected {languages[option]}')
f-string don't not allow nested interpolation. However, to get the correct option from the dictionary you don't need quotes, languages[option] will do.
So the line you are looking to use will be
print(f"You've selected {languages[option]}")
option is a variable, but you made option to a string. That means the key you gave the dictionary language is in your case {option} and this key doesnt exist
languages = {'1':'Learn Python', '2':'Learn Java', '3':'Learn C++', '4':'Learn PHP', '5':'Quit'}
option = str(input('Please choose an option between 1 and 5'))
# Following part is working!!!
print(f'Youve selected {languages[option]}')
You didnt use the variable option, you used {option} as a string and tried to print the value of the key {option}. Just remove the brackets and the "".
You could also use a f string in a f string, but thats not necessary.
print(f'Youve selected {languages[f"{option}"]}')
The reason, why your code didnt work is in that case, because you made a string in a f string and not a f string in a f string

Importing dictionary values into an OptionMenu in Python

I'm stuck right now and could really use some help, i've exhausted every resource google could find for me and I still can't figure out how to do what I am attempting. (If its even possible)
In my python program I am using Tkinter in Python 3.5.1 to make a little calculator applet. For the calculator in question I created a CSV file and imported it using csv.DictReader.
import csv
exptable = csv.DictReader(open('C:/Users/SampleInfo.csv'))
result = {}
for column in exptable:
key = column.pop('Current Level')
if key in result:
pass
result[key] = column
Now the part that I simply can't figure out is how to use the information contained WITHIN this imported dictionary. Here is what I am trying so far...
DropDownLevelVar = StringVar()
DropDownLevel = ttk.OptionMenu(root, {column})
DropDownLevel.grid(column=3, row=1)
This is leaving me with...
Error on line 49, in module DropDownLevel = ttk.OptionMenu(root, {column})
TypeError: unhashable type: 'dict'
The CSV Dictionary I am trying to use contains 2 columns of data, "Current Level and Total EXP" See This for what the Data looks like.
What I would like is for the OptionMenu Dropdown list to be populated with the values listed under Current Level within the dictionary.
My goal is to create a super simple calculator that calculates how many of a certain monster I would need to kill to reach my desired level. (If Current level = 55, then 100 Kills at 500xp ea until 56.) I imported the dictionary so that I could reference the values over and over if I needed to.
I'm REALLY new to programming so i'm sorry if I look like a complete idiot!
Why not use this method to populate your dict?
Anyway, to correctly populate the result dict:
import csv
exptable = csv.DictReader(open('C:/Users/SampleInfo.csv'))
result = {}
for column in exptable: # should actually be called `row`
key = column['Current Level']
if key not in result:
result[key] = column['Total EXP']
The for and if block can be better written as:
for column in exptable: # should actually be called `row`
if column['Current Level'] not in result:
result[column['Current Level']] = column['Total EXP']
If ttk.OptionMenu wants a dict, then the line DropDownLevel = ttk.OptionMenu(root, {column}) should probably be:
DropDownLevel = ttk.OptionMenu(root, result)
Edit: And the pythonic way to do this, as per the method linked above:
import csv
result = {}
with open('C:/Users/SampleInfo.csv') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
if row['Current Level'] not in result: # is this check necessary?
result[row['Current Level']] = row['Total EXP']

Python: Convert String to Object Name

This may be a very simple question, but how can I use a string for the name of a class/object declaration? I'm working with PySide, and I have code that will make a text input for every entry in an array.
i=0
d = {}
for name in mtlName:
i = i+1
curOldLabel = d["self.oldLabel" + str(i)]
So now I have to just decalre QtGui.QLineEdit() as what curOldLabel equals (self.oldLabel1 = QtGui.QLineEdit(), self.oldLabel2 = QtGui.QLineEdit(), etc). How do I tell it not to overwrite curOldLabel, but instead use the string as the name for this object?
Your best bet is to use another dictionary to store those objects. It's safe, it's easy to use and it has fast lookup. You don't want to be creating normal variables with dynamic names in most scenarios.

Categories