I can't seem to update my money counter(var money) when its labeled, I have a button that's supposed to add 0.1 to moneyNum but the money counter doesn't change. I'm new to stack overflow and would appreciate any help.(btw sry if its REALLY messy)
from tkinter import *
import random
from time import sleep
root = Tk()
root.geometry('320x320')
#spacing
spacingTitle = Label(root, text=" \n\n\n\n\n\n\n\n\n")
#title
title = Label(root, text=" \bGamblers Dream\b", font="Helvetica", fg="red")
titleWelcom = Label(root, text=" Welcom to...")
titleWelcom.grid()
title.grid()
#money counter
moneyNum = float(10.0)
money = Label(root, text="money:" + str(moneyNum), font="Helvetica")
money.grid(row=3, column=0)
#moneyClicker
def moneyButtonAdder():
global moneyNum
moneyNum = moneyNum + 0.1
moneyClicker = Button(root, text="click", fg="green", command=moneyButtonAdder)
moneyClicker.grid(row=14)
root.mainloop()
The problem is that once you create a label, you pass the string to it. Label displays the string, and:
changing a string object does not change the label text
changing the integer does not change the string - it lost the whole connection when the new string object was created
So everything is not as procedural as you would have hoped it is.
The solution - use StringVar objects and detect value changes - see this.
So, the solution is:
from tkinter import *
class Observed(object):
"""adapted copy from https://stackoverflow.com/a/6192298/10713244"""
def __init__(self):
self._observed = 10.0
self._observers = []
#property
def observed(self):
return self._observed
#observed.setter
def observed(self, value):
self._observed = value
for callback in self._observers:
print('announcing change')
callback(self._observed)
def bind_to(self, callback):
print('bound')
self._observers.append(callback)
class Observer(object):
def __init__(self, data):
self.text = ''
self.data = data
self.data.bind_to(self.update)
self.tkinter_init()
def update(self, observed):
self.text = 'float: '+str(data._observed)
self.tkinter_update()
def tkinter_init(self):
self.tk = Tk()
self.tvar = StringVar()
self.label = Label(textvariable=self.tvar)
self.label.pack()
def tkinter_update(self):
self.tvar.set(self.text)
if __name__ == '__main__':
data = Observed()
label = Observer(data)
print(label.text)
data.observed = 10.0
print(label.text)
def dec(): data.observed -= 0.1
Button(label.tk, text='decrease', command=dec).pack()
label.tk.mainloop()
Hope that's helpful!
Related
My code:
import tkinter
class latinwords:
def __init__(self):
self.main = tkinter.Tk()
self.top = tkinter.Frame(self.main)
self.mid = tkinter.Frame(self.main)
self.latinword1 = tkinter.Button(self.mid, text = 'sinister', command = self.cbfunction)
self.latinword2 = tkinter.Button(self.mid, text = 'dexter', command = self.cbfunction2)
self.latinword3 = tkinter.Button(self.mid, text = 'medium', command = self.cbfunction3)
self.toplabel = tkinter.Label(self.top, text= 'Latin')
self.toplabel2 = tkinter.Label(self.top, text= '\tEnglish')
self.value = tkinter.StringVar()
self.value1 = tkinter.StringVar()
self.value2 = tkinter.StringVar()
self.labels = tkinter.Label(self.bot, textvariable = self.value)
self.labels1 = tkinter.Label(self.bot, textvariable = self.value1)
self.labels2 = tkinter.Label(self.bot, textvariable = self.value2)
self.labels.pack()
self.labels1.pack()
self.labels2.pack()
self.top.pack()
self.mid.pack()
self.latinword1.pack()
self.latinword2.pack()
self.latinword3.pack()
self.toplabel.pack(side='left')
self.toplabel2.pack(side='left')
tkinter.mainloop()
def cbfunction(self):
value = 'left'
self.value1.set(value)
def cbfunction2(self):
value = 'right'
self.value.set(value)
def cbfunction3(self):
value = 'centre'
self.value2.set(value)
s = latinwords()
Unexpected output:
Expected output:
As you can see, I am trying to get my expected output with 3 buttons that can show the English word after its being pressed. But I got my output vertically with my own code. I am expecting my button and the matched word are on same horizontal level. Can anyone help me with this issue? Thanks.
It is better to put all the labels and buttons in same frame and use grid() instead of pack():
import tkinter
class latinwords:
def __init__(self):
self.main = tkinter.Tk()
self.mid = tkinter.Frame(self.main)
self.mid.pack()
self.latinword1 = tkinter.Button(self.mid, text='sinister', command=self.cbfunction)
self.latinword2 = tkinter.Button(self.mid, text='dexter', command=self.cbfunction2)
self.latinword3 = tkinter.Button(self.mid, text='medium', command=self.cbfunction3)
self.toplabel = tkinter.Label(self.mid, text='Latin')
self.toplabel2 = tkinter.Label(self.mid, text='English')
self.value = tkinter.StringVar()
self.value1 = tkinter.StringVar()
self.value2 = tkinter.StringVar()
self.labels = tkinter.Label(self.mid, textvariable=self.value)
self.labels1 = tkinter.Label(self.mid, textvariable=self.value1)
self.labels2 = tkinter.Label(self.mid, textvariable=self.value2)
self.labels.grid(row=1, column=1)
self.labels1.grid(row=2, column=1)
self.labels2.grid(row=3, column=1)
self.latinword1.grid(row=1, column=0)
self.latinword2.grid(row=2, column=0)
self.latinword3.grid(row=3, column=0)
self.toplabel.grid(row=0, column=0)
self.toplabel2.grid(row=0, column=1)
tkinter.mainloop()
def cbfunction(self):
value = 'left'
self.value.set(value)
def cbfunction2(self):
value = 'right'
self.value1.set(value)
def cbfunction3(self):
value = 'centre'
self.value2.set(value)
s = latinwords()
Solution:
The self.bot attribute is missing.
self.bot = tkinter.Frame(self.main)
You should set the position of packing of frames.
self.top.pack(side=tkinter.TOP)
self.mid.pack(side=tkinter.LEFT)
self.bot.pack(side=tkinter.RIGHT)
Test/Output:
>>> python3 test.py
NOTE:
The order of English words are not correct but it is not related to question.
I recommend to use the grid instead of pack. You can make more nice GUI with grid in your case. See more: https://tkdocs.com/tutorial/grid.html
I'm trying to avoid to multiply functions in code by using
def Return_Label(self,number)
with a parameter.
Any Idea how to use string in order to define variable name usable to .set value to StringVar()?
Example code below:
import tkinter as tk
from tkinter import *
class WINDOW():
def __init__(self):
self.Settings_Window()
def Settings_Window(self):
self.settings_window = tk.Tk()
self.settings_window.minsize(200,200)
self.entry = Entry(self.settings_window)
self.entry.pack()
self.entry2 = Entry(self.settings_window)
self.entry2.pack()
self.label1input = StringVar()
self.label = Label(self.settings_window,textvariable=self.label1input, bg='yellow')
self.label.pack(expand='yes',fill='x')
self.label2input = StringVar()
self.label2 = Label(self.settings_window, textvariable=self.label2input, bg='yellow')
self.label2.pack(expand='yes', fill='x')
self.button = Button(self.settings_window,text='SETUP1',command=self.Next)
self.button.pack()
self.button2 = Button(self.settings_window,text='SETUP2',command=self.Next2)
self.button2.pack()
self.settings_window.mainloop()
def Next(self):
self.number=1
self.Return_Label(self.number)
def Next2(self):
self.number=2
self.Return_Label(self.number)
def Return_Label(self,number):
self.entry_field_value = self.entry.get()
print(self.entry_field_value)
#self.label1input.set(self.entry_field_value)
setattr(self,'label'+str(number)+'input.set',self.entry_field_value)
window=WINDOW()
I prefer a list approach to managing multiple entry fields and updating values.
By using list you can use the index value to manage the labels as well :D.
See the below example of how you can use list to deal with all the values and updates.
import tkinter as tk
from tkinter import *
class Window(tk.Tk):
def __init__(self):
super().__init__()
self.minsize(200, 200)
self.entry_list = []
self.label_list = []
entry_count = 2
for i in range(entry_count):
self.entry_list.append(Entry(self))
self.entry_list[i].pack()
for i in range(entry_count):
self.label_list.append(Label(self,bg='yellow'))
self.label_list[i].pack(expand='yes', fill='x')
Button(self, text='SETUP', command=self.Return_Label).pack()
def Return_Label(self):
for ndex, lbl in enumerate(self.label_list):
lbl.config(text=self.entry_list[ndex].get())
if __name__ == '__main__':
Window().mainloop()
Create lists of objects rather than individual attributes for each object. For example,
import tkinter as tk
from tkinter import *
class Window:
def __init__(self):
self.settings_window()
def Settings_Window(self):
self.settings_window = tk.Tk()
self.settings_window.minsize(200,200)
self.entries = [
Entry(self.settings_window),
Entry(self.settings_window)
]
for e in self.entries:
e.pack()
self.labelinputs = [
StringVar(),
StringVar()
]
self.labels = [
Label(self.settings_window, textvariable=label, bg='yellow')
for label in self.labelinputs
]
for l in self.labels:
l.pack(expand='yes', fill='x')
self.buttons = [
Button(self.settings_window,text='SETUP1',command=lambda: self.return_label(0))
Button(self.settings_window,text='SETUP2',command=lambda: self.return_label(1))
]
for b in self.buttons:
b.pack()
self.settings_window.mainloop()
def return_label(self,number):
entry_field_value = self.entry.get()
self.labelsinput[number].set(entry_field_value)
window=WINDOW()
Dynamicly computing variable names should be avoided at all costs. They are difficult to do correctly, and it makes your code hard to understand, hard to maintain, and hard to debug.
Instead, store the widgets in a dictionary or list. For example:
def __init___(self):
...
self.vars = {}
...
self.vars[1] = StringVar()
self.vars[2] = StringVar()
...
def Return_Label(self,number):
self.entry_field_value = self.entry.get()
var = self.vars[number]
var.set(self.entry_field_value)
Though, you really don't need to use StringVar at all -- they usually just add extra overhead without providing any extra value. You can save the labels instead of the variables, and call configure on the labels
self.labels[1] = Label(...)
...
self.labels[number].configure(text=self.entry_field_value)
I am creating a simple bank account GUI , when i click the menu " interest" the variable changed from 1 to 2 , which should change the value of the current balance by 10 percent, however the value stays the same, give your insight.
from tkinter import *
from random import randint
class BankAccount(object):
def __init__(self, initial_balance=0):
self.balance = initial_balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
self.balance -= amount
def get_balance(self, initial_balance, rate):
return self.get_balance() * self._rate
class BankAccountWithInterest(BankAccount):
def __init__(self, initial_balance=0, rate=0.1):
BankAccount.__init__(self, initial_balance)
self._rate = rate
def interest(self):
return self.balance * self._rate
balance = (randint(100, 500))
my_account = BankAccount(balance)
my_interest = BankAccountWithInterest(balance)
interest = my_interest.balance + my_interest.interest()
typeOfAccount = "1"
class GUI:
def __init__(self, master):
frame = Frame(master)
frame.pack()
#Toolbar#
toolbar = Frame(root)
toolbar.pack(side=TOP, fill=X)
#Button#
button1 = Button(toolbar, text="Deposit", width = 13, command=self.depositBalance)
button2 = Button(toolbar, text="Withdraw",width = 13, command=self.depositWithdraw)
button1.pack(side=LEFT)
button2.pack(side=RIGHT)
#Menu#
subMenu = Menu(menu)
menu.add_cascade(label="Type of Account", menu=subMenu)
subMenu.add_command(label="Standard", command= self.standard)
subMenu.add_command(label="Interest", command= self.interest)
#Textbox#
self.text = Entry(root)
self.text.pack()
#Labels#
w = Label(root, text="Current Balance:")
w.pack()
w1 = tkinter.StringVar()
if typeOfAccount == "1":
w1 = Label(root, text=my_account.balance)
w1.pack()
elif typeOfAccount == "2":
w1.set(text=interest)
w1.pack()
def depositBalance(self):
a = int(self.text.get())
my_account.balance = a + my_account.balance
print(my_account.balance)
def depositWithdraw(self):
a = int(self.text.get())
my_account.balance = my_account.balance - a
print(my_account.balance)
def standard(self):
typeOfAccount = "1"
def interest(self):
typeOfAccount = "2"
root = Tk()
menu = Menu(root)
root.config(menu=menu)
root.title("Bank Account")
root.minsize(width=250, height=100)
root.maxsize(width=300, height=150)
GUI(root)
root.mainloop()
There are several problems with your code. The multiple class files do not appear to work as you think they should and some things are just wrong. I have reworked your program into what I think it is you are trying to do and I have moved everything into 1 big class as it made more sense in this situation. You were making things more complicated than it needed to be by creating variables outside of the classes and by making several classes. There is nothing really wrong with using several classes but the way you were going about it was making things way more difficult than it needed to be.
First thing I did was to create all the class variables/attributes that we are going to use.
To make things easier on us going forward I made every widget and variable a class attribute by placing self. as a prefix to all the variable/widget names. This will allow us to interact with and change each attribute in any of the class methods without an issue and if you add more options down the road the attributes will already be defined and ready to change.
Next I moved all your separate class methods into the main class to make things easier to work with.
I replaced your if/else statement on the account types into a methods. This will allow us to update label to show the balance or the interest any time the account type changes or an amount is added or removed from the balance.
I modified the depositBalance and depositWithdraw methodsto have a little error handling because your entry field is not restricted to only numbers and can cause errors if the user puts anything else in or leaves it blank.
I change the standard and interest methods to update the typeOfAccount attribute and to update the label by calling on the type_account method.
Last but not least some general clean up so the code did not have pointless spacing and to make sure we follow a DRY (don't repeat yourself) standard.
Below is the reworked code with all the changes I mentioned above. Let me know if this helps and if you are confused on anything.
from tkinter import *
from random import randint
class GUI:
def __init__(self, master):
self.master = master
self.typeOfAccount = "1"
self.balance = (randint(100, 500))
self.rate = 0.1
self.frame = Frame(master)
self.frame.pack()
self.toolbar = Frame(root)
self.toolbar.pack(side=TOP, fill=X)
self.button1 = Button(self.toolbar, text="Deposit", width = 13, command=self.depositBalance)
self.button2 = Button(self.toolbar, text="Withdraw",width = 13, command=self.depositWithdraw)
self.button1.pack(side=LEFT)
self.button2.pack(side=RIGHT)
self.menu = Menu(self.master)
self.master.config(menu = self.menu)
self.subMenu = Menu(self.menu)
self.menu.add_cascade(label="Type of Account", menu=self.subMenu)
self.subMenu.add_command(label="Standard", command=self.standard)
self.subMenu.add_command(label="Interest", command=self.interest)
self.text = Entry(self.master)
self.text.pack()
self.w = Label(root, text="Current Balance: {}".format(self.balance))
self.w.pack()
#removed "tkinter." not needed because of the type of import you used
self.w1 = StringVar()
def type_account(self):
if self.typeOfAccount == "1":
self.w.config(text="Current Balance: {}".format(self.balance))
elif self.typeOfAccount == "2":
interest = self.balance * self.rate
self.w.config(text="Current Balance: {}".format(interest))
def depositBalance(self):
try:
if int(self.text.get()) > 0:
a = int(self.text.get())
self.balance = a + self.balance
self.type_account()
except:
print("Blank or non numbers in entry field")
def depositWithdraw(self):
try:
if int(self.text.get()) > 0:
a = int(self.text.get())
self.balance = self.balance - a
self.type_account()
except:
print("Blank or non numbers in entry field")
def standard(self):
self.typeOfAccount = "1"
self.type_account()
def interest(self):
self.typeOfAccount = "2"
self.type_account()
if __name__ == "__main__":
root = Tk()
root.title("Bank Account")
root.minsize(width=250, height=100)
root.maxsize(width=300, height=150)
app = GUI(root)
root.mainloop()
You should set self.w1, (rather than just w1) for example, then you can update the text from any instance method in that class.
The problem I am having is that the function below works fine on the first pass with regards to displaying the chosen value at the top of the OptionMenu before the 'Enter' button is clicked:
First pass
However on a second pass and any future passes to the function the chosen value is not displayed at the top of the OptionMenu (although if selected it will be used) before the 'Enter' Button is pressed:
Second etc. passes
The code is:
def load_create_list(self):
self.app = Toplevel(self.parent)
self.parent.withdraw()
self.app.title("Rgs2")
self.student = []
self.student1=[]
self.gs1=0
self.ng1=0
options = ["2", "3", "4", "5", "6", "7"]
self.results=[]
self.ngg=StringVar() #for the option menu widget the variable must be a stringVar not a normal string, int etc.
self.ng = Label(self.app, text="Number of groups")
self.ng.grid(row=2, column=0)
self.ngg.set("3")
self.ng1 = OptionMenu(self.app, self.ngg, *options)
self.ng1.grid(row=2, column=1, ipadx=10)
for i in range(0,len(self.x3)):
self.L1 = Label(self.app,text="Student")
self.L1.grid(row=i+4, column=0)
self.en = Entry(self.app)
self.en.insert(END, self.x3[i])
self.en.grid(row=i+4, column=1)
self.student.append(self.en)
self.el = int(len(self.student)+1)
for h in range(self.el,self.el+5):
self.L2 = Label(self.app,text="Student")
self.L2.grid(row=h+4, column=0)
self.em = Entry(self.app)
self.em.grid(row=h+4, column=1)
self.student.append(self.em)
button=Button(self.app,text="enter",command=lambda : self.hallo2()).grid(row=h+7,column=0)
button=Button(self.app,text="Save List",command=lambda : self.save_list2()).grid(row=h+7,column=1)
I have tried everything but can't understand what might be causing this issues. Any help would be gladly appreciated. Seems like very odd behaviour could it be something outside of the function that is causing the issue?
Full code is:
from Tkinter import *
from tkFileDialog import askopenfile
class main_menu:
def __init__(self, parent):
self.myParent = parent
self.myContainer1 = Frame(parent)
parent.title("Random Group Sorter")
self.myContainer1.pack()
self.button1 = Button(self.myContainer1, command = lambda : self.hope())
self.button1.configure(text="Create List", height = 1, width = 20, font=("Arial", 16))
self.button1.pack(side=TOP)
self.button1.focus_force()
self.button3 = Button(self.myContainer1, command = lambda : self.hope1())
self.button3.configure(text="Load List", height = 1, width = 20, font=("Arial", 16))
self.button3.pack(side=TOP)
self.button2 = Button(self.myContainer1, command = lambda : exit(), )
self.button2.configure(text="Exit",height = 1, width = 20, font=("Arial", 16))
self.button2.pack(side=TOP)
def hope(self):
self.myParent.destroy()
create_list()
def hope1(self):
self.myParent.destroy()
load_list()
class create_list():
def __init__(self):
parent = Tk()
self.parent=parent
self.student = []
self.student1 =[]
self.student2 =[]
self.fake_student = []
self.results=[]
self.ngg = StringVar()# for the option menu widget the variable must be a stringVar not a normal string, int etc.
self.ng = Label(text="Number of groups")
self.ng.grid(row=2, column=0)
self.ng = OptionMenu(parent, self.ngg, "2", "3", "4", "5","6")
self.ng.grid(row=2, column=1)
for i in range(3,21):
self.L1 = Label(text="Student")
self.L1.grid(sticky=E)
self.en = Entry(parent)
self.en.grid(row=i, column=1)
self.student.append(self.en)
button=Button(parent,text="Enter",command=lambda : self.hallo()).grid(row=23,column=0)
button=Button(parent,text="Save List",command=lambda : self.save_list()).grid(row=23,column=1)
parent.mainloop()
def hallo(self):
self.gs1 = int(len(self.student))
self.ng1 = int(self.ngg.get())# still need to use .get even though a stringvar
for entry in self.student:
self.student1.append(entry.get())
self.student1 = filter(None, self.student1)
for i in self.student1:# this is added as there are duplicate entries in the student list if saved
if i not in self.student2:
self.student2.append(i)
self.parent.destroy()
lis_an(self.student2,self.ng1)
def save_list(self):
for entry in self.student:
self.student1.append(entry.get())
self.student1 = filter(None, self.student1)
import tkFileDialog
root = Tk()
root.withdraw()
file_name = tkFileDialog.asksaveasfile(parent=root)
root.destroy()
print >>file_name, "\n"
print >>file_name, "\n".join(self.student1)
file_name.close()
class load_list:
def __init__(self):
self.x = []
self.x3 = []
self.load_clean()
self.root = Tk()
def load_clean(self):#option to load an already created file, cleans unwanted info from the list
import tkFileDialog
root = Tk()
root.withdraw()
file_name = tkFileDialog.askopenfile(parent=root)
root.destroy()
self.x = file_name.readlines()
file_name.close()
x2 =self.x[:]
for z in self.x:
if z [0:6]== "Random" or z == '\n' or z[0:5] == "Group":
x2.remove(z)
for c in range (0,len(x2)):
v = x2[c].rstrip()# this strip spaces and \n from each list item and returns the cleaned up string
self.x3.append(v)
self.load_create_list()
def load_create_list(self):
parent = Tk()
self.parent=parent
self.student = []
self.student1=[]
self.gs1=0
self.ng1=0
self.results=[]
self.ngg = StringVar()# for the option menu widget the variable must be a stringVar not a normal string, int etc.
self.ng = Label(text="Number of groups")
self.ng.grid(row=2, column=0)
self.ng = OptionMenu(parent, self.ngg, "2", "3", "4", "5", "6")
self.ng.grid(row=2, column=1)
for i in range(0,len(self.x3)):
self.L1 = Label(text="Student")
self.L1.grid(row=i+3, column=0)
self.en = Entry(parent)
self.en.insert(END, self.x3[i])
self.en.grid(row=i+3, column=1)
self.student.append(self.en)
self.el = int(len(self.student)+1)
for h in range(self.el,self.el+5):
self.L2 = Label(text="Student")
self.L2.grid(row=h+3, column=0)
self.em = Entry(parent)
self.em.grid(row=h+3, column=1)
self.student.append(self.em)
button=Button(parent,text="enter",command=lambda : self.hallo2()).grid(row=h+6,column=0)
button=Button(parent,text="Save List",command=lambda : self.save_list2()).grid(row=h+6,column=1)
parent.mainloop()
def hallo2(self):
self.student2= []
self.gs1 = int(len(self.student))
self.ng1 = int(self.ngg.get())# still need to use .get even though a stringvar
for entry in self.student:
self.student1.append(entry.get())
self.student1 = filter(None, self.student1)
for i in self.student1:# this is added as there are duplicate entries in the student list if saved
if i not in self.student2:
self.student2.append(i)
self.parent.destroy()
lis_an(self.student2,self.ng1)
def save_list2(self):
for entry in self.student:
self.student1.append(entry.get())
self.student1 = filter(None, self.student1)
import tkFileDialog
root = Tk()
root.withdraw()
file_name = tkFileDialog.asksaveasfile(parent=root)
root.destroy()
print >>file_name, "\n"
print >>file_name, "\n".join(self.student1)
file_name.close()
class lis_an:
def __init__(self,student1,ng1):
self.student1 = student1
self.ng1=ng1
self.results = []
self.randomList()
def randomList(self): # this creates a random list of students on the course
import random
studentb = self.student1[:]# this is added as otherwise the student list is overwritten
studentc = []
for i in range(len(studentb)):
element = random.choice(studentb)
studentb.remove(element)
studentc.append(element)
self.student1 = studentc
self.partition()
def partition(self): # this creates sub list of the student list containing the groups of students
increment = len(self.student1) / float(self.ng1)
last = 0
i = 1
while last < len(self.student1):
idx = int(round(increment * i))
self.results.append(self.student1[last:idx])
last = idx
i += 1
output(self.results, self.ng1)
class output:
def __init__(self, student, ng1):
self.ng1 = ng1
self.student = student
self.parent = Tk()
for item1 in range (0,len(self.student)):
test1 = "Group " + str(item1+1)+ ":"
v = Label(self.parent, text=test1, font=("Arial", 13))
test = "\n".join(self.student[item1])
w = Label(self.parent, text=test, justify = LEFT, font=("Arial", 12))
v.pack(side="top", anchor="w")
w.pack(side="top", anchor="w")
button=Button(self.parent,text="Repeat",command=lambda : self.join_list()).pack(side="top", anchor="w")
button=Button(self.parent,text="Main Menu",command=lambda : self.menu_link()).pack(side="top", anchor="w")
mainloop()
def join_list(self):#this function creates a new undivided version of student to feed back to lis_an
self.parent.destroy()
self.student = [j for i in self.student for j in i]
lis_an(self.student,self.ng1)
def menu_link(self):#destroys the parent frame and returns back to main menu
self.parent.destroy()
main()
def main():
parent = Tk()
myapp = main_menu(parent)
parent.mainloop()
main()
Very Simple solution to this problem. I was not defining self.ngg as a StringVar in the parent widget so:
self.ngg = StringVar()
Would cause the error, and
self.ngg = StringVar(self.app)
Solves the problem. Not quite sure why this would occur on the second and subsequent uses of the function but not the first.
I'm trying to use a function which a placed inside the class of Tkinder but the function(aktodec) can't be found and a get an error. I don't wanna call the def as a command of a button but as a function that will give value to one of my variables
from Tkinter import *
class ADialog:
def __init__(self, parent):
top = self.top = Toplevel(parent)
Label(top, text="Number to convert").pack()
self.numb = Entry(top)
self.numb.pack(padx=15)
Label(top, text="Base of incered number").pack()
self.base = Entry(top)
self.base.pack(padx=15)
Label(top, text="Base you want to be converted").pack()
self.basemet=Entry(top)
self.basemet.pack(padx=15)
b = Button(top, text="OK", command=self.met)
b.pack(pady=5)
def aktodec(self,num,base): #####commands
dec=0
num=num[::-1]
for i in range(len(num)):
s=int(num1[i])*(int(base)**i)
dec=dec+s
def met(self):
num=self.numb=str(self.numb.get())
base=self.base =int(self.base.get())
basemet=self.basemet=int(self.basemet.get())
if base==basemet:
Label(root,text="The number "+self.numb+"is converted to"+self.numb) ##why can't be print??
if base==10:
new=num
else:
new1=self.aktodec(num,base) ####why aktodec doesn't give value to "new"??
Label(root,text="Number is"+str(new))
self.top.destroy()
root = Tk()
def open_dialog():
dial = ADialog(root)
root.wait_window(dial.top)
root.wm_geometry("400x300+20+40")
message=StringVar()
message.set("Complete the form")
Label(root, textvariable=message).pack(padx=30)
root.update()
message.set("Form completed")
Button(root, text="Done", command=root.destroy).pack()
Button(root, text="new", command=open_dialog).pack()
root.update()
root.mainloop()
And also I have a problem whith the label
Label(root,text="The number "+self.numb+"is converted to"+self.numb
which (i don't know why) won't appear to the root even the base=basemet. Help please(it's for a project in this week)!
In Python, a function can't modify some arguments(integers, strings) as perceived by the caller, they are immutable. However, some objects like lists are mutable.
def aktodec(self,num,base):
dec=0
num=num[::-1]
for i in range(len(num)):
s=int(num1[i])*(int(base)**i)
dec=dec+s
return dec
def met(self):
num=self.numb=str(self.numb.get())
base=self.base =int(self.base.get())
basemet=self.basemet=int(self.basemet.get())
new = num
if base==basemet:
Label(root,text="The number "+self.numb+"is converted to"+self.numb).pack()
if base==10:
new=num
else:
new=self.aktodec(num,base)
Label(root,text="Number is"+str(new)).pack()
self.top.destroy()