Add 2 numbers from separate buttons (tkinter) - python

I have 3 buttons I want to make it so when you press a button it sets the variable to a value.
press 1st button sets x to 1 2nd set y to 2 press 3rd add x and y together should return with 3 but it returns with 0.
I tried to make a 4th value where when it is set to 1 it would add both together. me and a friend tried making x and y at the beginning and integer int(x)= x
here is the code
import tkinter
window_main = tkinter.Tk(className='Tkinter - TutorialKart', )
window_main.geometry("400x200")
i=0
x=0
y=0
o = 0
p = 0
x = int(x)
y = int(y)
o = int(o)
p = int(p)
i=int(i)
def submitFunction() :
x = 1
print(x)
if o == 1:
x = 1
def a2():
y = 2
print(y)
if p == 1:
y = 2
def equ():
i = int(x + y)
return(i)
print(i)
button_submit = tkinter.Button(window_main, text ="set x to 1", command=submitFunction).grid(column = 1, row = 1)
button = tkinter.Button(window_main, text ="set y to 2", command=a2).grid(column = 2, row = 1)
button = tkinter.Button(window_main, text = "solve", command = equ). grid(column = 3, row = 1)
window_main.mainloop()

Given your code if you look carefully there are two Variables by the name 'x' and 'y' and whenever you press the button it does execute the button however the variables in inside those function are treated as local variables although you have defined them outside the function which should make them global variables.
But in the case of python global variables can be accessed inside the function but cannot be modified.
So in this case in order to treat the 'x' and 'y' with global scope so they can be modified or changed inside the function which reflects it variables outside, we use global Keyword inside function in order to make their scope global.
I have modified your code a bit.
from tkinter import *
import tkinter
window_main = Tk(className='Tkinter - TutorialKart', )
window_main.geometry("400x200")
i=0
x=0
y=0
o = 0
p = 0
def submitFunction() :
global x
x = 1
print(x)
if o == 1:
x = 1
def a2():
global y
y = 2
print(y)
if p == 1:
y = 2
def equ():
i = x + y
print(i)
return (i)
button_submit = tkinter.Button(window_main, text ="set x to 1", command=submitFunction).grid(column = 1, row = 1)
button = tkinter.Button(window_main, text ="set y to 2", command=a2).grid(column = 2, row = 1)
button = tkinter.Button(window_main, text = "solve", command = equ). grid(column = 3, row = 1)
window_main.mainloop()
If you want to read more about calling functions in tkinter without parenthesis click this link the person has explained it perfectly.
Also check variable scoping in Python link
You might get more clarity on understanding your problem after reading.

Related

Search in list of tkinter widgets

I have some tkinter widgets stored in a list. I'd like to search for an object in that list, by I don't know the syntax.
import tkinter as tk
main = tk.Tk()
base = tk.Frame(main).pack()
l = []
for i in range(3):
et = tk.Label(base, text='label '+str(i))
et.pack()
l.append(et)
print(base.Label.!label in l)
main.mainloop()
Note.
Certainly this is a minimal example to understand where my mistake is.
The gui actually consists of an n x m matrix of tkinker entries, whose cells, rows, and columns should be dynamically added, deleted, modified, and even inserted or switched.
To do this, I have a dictionary that associates index tuples (i,j) with tkinter entries. When an entry is chosen with the mouse, that object is known, but what I really need to know is its index (i,j) to manage all the rest of the information (maths operations over arrays, etc).
To solve your problem you could use the index of separate list and use widget.grid_info() to retrieve the indices.
top_bar = []
sidebar = []
The rendering and the content have separated masters to achieve that the indexes of the lists, which starts with 0, match with the column and row of your inner grid.
The outer master could be populated like this, important to note is that Label on grid position 0,0 is not append to any of the lists but is gridded to fill the space. The grid_configure is just a optical improvement.
def outer_matrix():
for x in range(COLUMNS+1):
for y in range(ROWS+1):
ref = tk.Label(root,)#justify='center')
txt = None
if x == 0 and y != 0:
txt = y
top_bar.append(ref)
elif y == 0 and x != 0:
txt = x
sidebar.append(ref)
if txt != None or x == 0 and y == 0:
ref.config(text = txt, width=10)
ref.grid(row = y, column = x, sticky='nswe')
root.grid_columnconfigure(x,weight=1)
root.grid_rowconfigure(y,weight=1)
Full Example:
import tkinter as tk
ROWS = 6
COLUMNS = 6
top_bar = []
sidebar = []
def outer_matrix():
for x in range(COLUMNS+1):
for y in range(ROWS+1):
ref = tk.Label(root,)#justify='center')
txt = None
if x == 0 and y != 0:
txt = y
top_bar.append(ref)
elif y == 0 and x != 0:
txt = x
sidebar.append(ref)
if txt != None or x == 0 and y == 0:
ref.config(text = txt, width=10)
ref.grid(row = y, column = x, sticky='nswe')
root.grid_columnconfigure(x,weight=1)
root.grid_rowconfigure(y,weight=1)
else:
ref.destroy()
def inner_matrix():
for x in range(COLUMNS):
for y in range(ROWS):
ref = tk.Entry(inner_frame, width=10)
ref.grid(column=x,row=y, sticky='nswe')
inner_frame.grid_columnconfigure(x,weight=1)
inner_frame.grid_rowconfigure(y,weight=1)
ref.bind('<FocusIn>', lambda e:highlight(e))
ref.bind('<FocusOut>', lambda e:highlight(e))
def highlight(event):
info = event.widget.grid_info()
x_info = info['row']
y_info = info['column']
if 'FocusIn' in str(event):
top_bar[x_info].configure(bg='yellow')
sidebar[y_info].configure(bg='yellow')
if 'FocusOut' in str(event):
top_bar[x_info].configure(bg='SystemButtonFace')
sidebar[y_info].configure(bg='SystemButtonFace')
root = tk.Tk()
root.update()
inner_frame = tk.Frame(root,bg='red')
inner_frame.grid(row=1,column=1,
columnspan=COLUMNS,
rowspan = ROWS,
sticky = 'nswe')
outer_matrix()
inner_matrix()
root.mainloop()

List append MemoryError

So I have this piece of code I'm trying to make generate level layouts for a grid of rooms. The first time through the mainloop it runs perfectly it runs and does exactly what it should but the second time through it pauses just after the first print error and gives me the attached error and I cant figure out what's wrong with it.
(the y/n prompt is only to slow down the program so I can see what's happening)
userInput = ""
roomChance = 0.5
world = [[0,0,0], \
[0,1,0], \
[0,0,0]]
possibleWorld = []
newX = []
def check_neighbours(xy):
possibleWorld.clear()
yLoops = 0
for y in xy:
print(" y:", y)
xLoops = 0
for x in y:
print(" x:", x)
#Check left cell
if(xLoops-1 >= 0):
if(y[xLoops-1] == 1):
possibleWorld.append([xLoops, yLoops])
print("x-1:", y[xLoops-1])
#Check right cell
if(xLoops+1 < len(y)):
if(y[xLoops+1] == 1):
possibleWorld.append([xLoops, yLoops])
print("x+1:", y[xLoops+1])
#Check above cell
if(yLoops-1 >= 0):
if(xy[yLoops-1][xLoops] == 1):
possibleWorld.append([xLoops, yLoops])
print("y-1:", xy[yLoops-1][xLoops])
#Check above cell
if(yLoops+1 < len(xy)):
if(xy[yLoops+1][xLoops] == 1):
possibleWorld.append([xLoops, yLoops])
print("y+1:", xy[yLoops+1][xLoops])
print("\n")
xLoops += 1
yLoops += 1
def assign_neighbours(possible, world, chance):
for i in possible:
if(random.random() < chance):
world[i[1]][i[0]] = 1
possible.clear()
def border_expand(world):
for x in world[0]:
if(x == 1):
for i in world[0]:
newX.append(0)
world.insert(0, newX)
newX.clear
break
def print_world(world):
for y in world:
print(y)
# ==================== Mainloop ====================
while(True):
userInput = input(print("Generate Level? Y/N?"))
check_neighbours(world)
print(possibleWorld)
assign_neighbours(possibleWorld, world, roomChance)
print_world(world)
border_expand(world)
print("\n")
print_world(world)
File "C:\Users\Potato\Desktop\Level gen_query.py", line 96, in <module>
border_expand(world)
File "C:\Users\Potato\Desktop\Level gen_query.py", line 67, in border_expand
newX.append(0)
MemoryError```
You're not calling newX.clear, so it is continually growing. When you run world.insert(0, newX) you are inserting a reference to newX into world[0], even if you did call newX.clear() you would not get the behaviour you want as the first element in world would be empty.
You need to create a new list on every call to border_expand so that it is a new list every time
def border_expand(world):
newX = []
for x in world[0]:
if(x == 1):
for i in world[0]:
newX.append(0)
world.insert(0, newX)
break

trying to compare two lists or one list with the same

import random
b=[]
o=[]
v=0
g=2
y=0
V=0
q=0
compat=0
alex=[]
zach=[]
while v != 5:
name="name"
position="position"
answers=[]
for i in range(10):
answer=random.randint(1,4)
answers.append(answer)
b.append(name)
b.append(position)
b.append(answers)
v+=1
print(b)
for ii in range(0,5):
t=b[g]
o.append(t)
g+=3
l=len(o)
for iii in list(o):
C = o[y]
y = y + 1
alex = []
for iiii in range(5):
I = 0
compat=0
R=o[q]
V=0
Y = C[V]
for iiiii in range(10):
r=R[I]
if r == Y:
compat+=1
else:
compat=compat
I+=1
V += 1
print(compat)
alex.append(compat)
print(alex)
zach.append(alex)
q+=1
w=len(zach)
print(zach)
print(w)
this is my code and it works pretty well. but it should put every single value against every other one but it doesnt it just put the same Y value and does not change. i have put v+=1 in tons of different places and moved around the a couple variable but it doesnt change. there should be 25 different answers for 5 people but it doesnt it just prints the same number 5 times then restarts.
any help would be appreciared
Edit: this is what i will intergrat the code above into
global compatability
import sqlite3
with sqlite3.connect("Questionare.db") as db:
cursor = db.cursor()
class mentee: # these classes are made to create a place where atributes can be filled with variables
def __init__(self,mentee_name,mentee_position):
self._mentee_posisition=mentee_position
self._mentee_name=mentee_name
def menteereport(self):
return{"mentee name:":self._mentee_name,"mentee position":self._mentee_posisition}
class mentor:
def __init__(self,mentor_name,mentor_position):
self._mentor_position=mentor_position
self._mentor_name=mentor_name
def mentorreport(self): # these are methods and they use a function with the variables instanciated within the class to make this appen
return {"mentor name":self._mentor_name,"mentor position":self._mentor_position}
class calculation:
def __init__(self,number_of_questions,compatability,mentoranswers,menteeanwers):
self._question_number= 1
self._number_of_questions=number_of_questions
self._compatability=compatability
self._mentor_values=mentoranswers
self._mentee_values=menteeanwers
def calc(self):
compat=0
c=0
for i in range(0,self._number_of_questions):
if self._mentee_values[c] == self._mentor_answers[c]:
compat += 1
c+=1
else:
compat += 0
c+=0
compatability=compat/self._number_of_questions
self._compatability=compatability
compatability=compatability*100
print(self._mentee_answers)
print(self._mentor_answers)
print("\n{:0.2f}%.\n".format(compatability))
def mentoranswer(self):
self._number_of_questions = int(self._number_of_questions)
self._question_number=1
for i in range(0,self._number_of_questions):
answer=input("Q{}".format(self._question_number))
self._question_number+=1
self._mentor_answers.append(answer)
def menteeanswer(self):
self._number_of_questions = int(self._number_of_questions)
self._question_number=1
for i in range(0,self._number_of_questions):
answer=input("Q{}".format(self._question_number))
self._question_number+=1
self._mentee_answers.append(answer)
class timerequirements:
def __init__(self,mentor_time_allotment,mentee_time_allotment,ideal_length_of_mentoring,ideal_length_of_being_mentored):
self._mentor_time_allotment=mentor_time_allotment
self._mentee_time_allotment=mentee_time_allotment
self._ideal_length_of_mentoring=ideal_length_of_mentoring
self._ideal_length_of_being_mentored=ideal_length_of_being_mentored
def main(): # this function is created to put the variables into the artibutes so that everything will work.
v = True
mentoranswers = []
menteeanswers = []
no_of_q = int(input("numebr of questions"))
while v == True:
morm = input("are your a mentor or a mentee")
if morm.lower() == "mentor":
name = input("name")
position = input("position")
answers = []
for i in range(0, no_of_q):
answer = int(input("1 or 2"))
answers.append(answer)
mentoranswers.append(name)
mentoranswers.append(position)
mentoranswers.append(answers)
print(mentoranswers)
elif morm.lower() == "mentee":
name = input("name")
position = input("position")
answers = []
for i in range(0, no_of_q):
answer = int(input("1 or 2"))
answers.append(answer)
menteeanswers.append(name)
mentoranswers.append(position)
menteeanswers.append(answers)
print(menteeanswers)
elif morm.lower() == "q":
v = False
else:
print("try again")
print(mentoranswers.mentorreport())
print(menteeanswers.menteereport())
main()
you are adding way too much noise.
for iii in list(o):
C = o[y]
y = y + 1
why don't you simply use the variable you just created? it will be incremented automatically
for iii in list(o):
C = o[iii]
you should learn how to use a loop and a few other basics. there are good tutorials on the official python site. here the for-loop one. most of your variables exist just to repeat what you are already doing.
i've avoided some high-level constructs, but i left zip.
import random
mentees = []
names = ['zach', 'alex', 'fred', 'jane', 'sara']
for name in names:
mentee = dict()
mentee['name'] = name
mentee['compatibility'] = []
answers = []
for i in range(10):
answers.append(random.randint(1,4))
mentee['answers'] = answers
mentees.append(mentee)
for mentee1 in mentees:
m1_answers = mentee1['answers']
for mentee2 in mentees:
m2_answers = mentee2['answers']
compat = 0
# zip fuses both lists into one
for m1_answer, m2_answer in zip(m1_answers, m2_answers):
if m1_answer == m2_answer:
compat += 1
mentee1['compatibility'].append((mentee2['name'], compat))
print(mentees)

Trouble with global dictionary

import tkinter as tk
#messagebox is not imported automatically w/ tkinter
from tkinter import messagebox as tkMessageBox
from tkinter import ttk
from random import random as rand
class Square(object):
""" class to use for each square """
def __init__(self):
self.mine_yn = False
self.flag_yn = False
self.prox_num = 0 # number of nearby mines, parse_mines() will fill this in.
self.button = None # ttk.Button instance.
def parse_mines():
"""Look at how many mines are next to a given square,
store in each Square instance that is inside of sqr_dict. """
global sqr_dict
global mine_frame
print('in parse_mines, sqr_dict='+str(sqr_dict))
def try_a_square(sq): #sq = coordinate string(key)
try:
if sqr_dict[sq].mine_yn == True: return 1
if sqr_dict[sq].mine_yn == False: return 0
except KeyError:
print('KeyError for '+sq)
return 0
n = 0
for x in range(5):
for y in range(4):
#check the 8 adjacent squares.
n = n + try_a_square('x'+str(x+1)+'y'+str(y+1))
n = n + try_a_square('x'+str(x+1)+'y'+str(y ))
n = n + try_a_square('x'+str(x+1)+'y'+str(y-1))
n = n + try_a_square('x'+str(x )+'y'+str(y+1))
n = n + try_a_square('x'+str(x )+'y'+str(y-1))
n = n + try_a_square('x'+str(x-1)+'y'+str(y+1))
n = n + try_a_square('x'+str(x-1)+'y'+str(y ))
n = n + try_a_square('x'+str(x-1)+'y'+str(y-1))
if sqr_dict[('x'+str(x)+'y'+str(y))].mine_yn == False:
(sqr_dict[('x'+str(x)+'y'+str(y))]).prox_num = n
print('x'+str(x)+'y'+str(y)+': '+str(n)) #(debug) print n for each sq
#sqr_dict[('x'+str(x)+'y'+str(y))].button.text=(str(n)) #(debug) show n on each button.
n = 0
def create_mine_field():
global mine_frame
global sqr_dict
sqr_dict = {}
mine_frame = tk.Toplevel(root)
mine_frame.grid()
#what to do if user hit 'X' to close window.
mine_frame.protocol("WM_DELETE_WINDOW", mine_frame_close)
# create grid of squares (buttons)
for x in range(5):
for y in range(4):
coord = 'x'+str(x) + 'y'+str(y)
sqr_dict[coord] = Square()
#print('coord='+coord) #debug
#populate with mines
if ( rand()*100 < mines_pct ):
sqr_dict[coord].mine_yn = True
print(str(sqr_dict[coord].mine_yn))
else:
sqr_dict[coord].mine_yn = False
if sqr_dict[coord].mine_yn:
t = '*'
else: t = ' '
# draw boxes
sqr_dict[coord].button = ttk.Button(mine_frame, text=t, width=3 )
sqr_dict[coord].button.grid(column=x, row=y)
# done, next: parse!
print('in create_mines, sqr_dict='+str(sqr_dict))
#parse_mines()
def root_close():
root.destroy()
def mine_frame_close():
root.destroy()
root = tk.Tk()
root.title("MineSweeper")
mines_pct = 20
start_button = ttk.Button(root,text="Start",command=create_mine_field)
start_button.pack()
root.mainloop()
I'm trying to make a simple minesweeper game with tkinter. If I run the above code a simple mine field appears. However if I uncomment the call to parser() then nothing shows up and it seems like it never finds any mines in the sqr_dict dictionary. (parser() will fill in the numbers of adjacent mines for each square)
I don't understand why this function would cause trouble before it is even called. No mine field appears when it's called. Please kindly give me your suggestions. Thanks!
The reason nothing shows up is because you are using both pack and grid on widgets that are children of the root window. Within any given window you must only use one or the other.

Python tkinter get() has no attribute

I'd like to use each variable in the list in an Entry widget, and get the text after pressing a button.
self.input_text = ['l1', 'l2', 'l3']
self.activeRow = 3
for e in self.input_text:
e = StringVar()
t = Entry(textvariable=e)
t.grid(row=self.activeRow,column=4,columnspan=2,sticky=W)
self.activeRow += 1
Eventually, I'd like to write the value of each variable in the list to a file but for now, I can't seem to print self.input_text[0] after the button press.
button1 = Button(text='Write',command=self.__writeNewInfo, width = 15)
button1.grid(row=self.activeRow,column=5,sticky=W)
def __writeNewInfo(self):
x = self.input_text[0].get()
y = self.input_text[1].get()
z = self.input_text[2].get()
print x
print y
print z
You are doing the wrong thing when creating the instances of StringVar. You set e to be the item in the list, then overwrite it as an empty StringVar. Instead try:
for i, e in enumerate(self.input_text):
self.input_text[i] = StringVar() #Overwrite this item in the list
self.input_text[i].set(e) #Set the StringVar to take the value from the list
t = Entry(textvariable=self.input_text[i])
t.grid(row=self.activeRow,column=4,columnspan=2,sticky=W)
self.activeRow += 1
self.input_text is basically a list of strings. If you want to retrieve something from an entry you need to keep the variable of this entry and call get() on it.
for example:
self.input_text = ['l1', 'l2', 'l3']
self.entries = []
self.activeRow = 3
for e in self.input_text:
e = StringVar()
t = Entry(textvariable=e)
t.grid(row=self.activeRow,column=4,columnspan=2,sticky=W)
self.activeRow += 1
self.entries.append(t)
button1 = Button(text='Write',command=self.__writeNewInfo, width = 15)
button1.grid(row=self.activeRow,column=5,sticky=W)
def __writeNewInfo(self):
x = self.entries[0].get()
y = self.entries[1].get()
z = self.entries[2].get()
print x
print y
print z

Categories