Division with a 0. value and force digits in result - python

I'm in need off assistance with some ZeroDivision.
In my example I got an optionMenu, that returns a value to a label, whitch is divided with an entry, then the result is shown in a new label in column 3.
I allways want to type an entry, that starts with an zero, like 0.250 etc. then this float is divided with the labels value from the optionMenu and then the result should be shown in a new label with digits.
It works fine with int, but thats not how it should work :) and now I'm a bit lost.
My following code looks like this and I would really appreciate a bit off help :) Thx in advance.
from tkinter import *
class App(Frame):
def __init__(self, root=None):
Frame.__init__(self, root)
self.materialPrice = {'Brick': 70, 'Rockwool': 50, 'Concrete': 20}
materialvariable1 = StringVar(self, root)
materialvariable1.set("Choose material")
materialvariable2 = StringVar(self, root)
materialvariable2.set("Choose materiale")
self.w1 = OptionMenu(root, materialvariable1, *self.materialPrice, command=self.displayPrice)
self.w1.grid(row=2, column=0, columnspan=1, sticky='WE')
self.w2 = OptionMenu(root, materialvariable2, *self.materialPrice, command=self.displayPrice2)
self.w2.grid(row=3, column=0, columnspan=1, sticky='WE')
self.var = IntVar()
self.var.set(float(0.00))
self.var2 = IntVar()
self.var2.set(float(0.00))
self.entry1 = Entry(root, textvariable=self.var)
self.entry1.grid(row=2, column=1)
self.entry2 = Entry(root, textvariable=self.var2)
self.entry2.grid(row=3, column=1)
self.priceVarLabel1 = IntVar()
self.priceVarLabel1.set(float(0.00))
self.priceVarLabel2 = IntVar()
self.priceVarLabel2.set(float(0.00))
self.priceVarValue1 = Label(root, textvariable=self.priceVarLabel1, relief='sunken')
self.priceVarValue1.grid(row=2, column=2, columnspan=1, sticky='WE')
self.priceVarValue2 = Label(root, textvariable=self.priceVarLabel2, relief='sunken')
self.priceVarValue2.grid(row=3, column=2, columnspan=1, sticky='WE')
self.resultlabel1 = IntVar()
self.resultlabel1.set(float(0.00))
self.resultlabel2 = IntVar()
self.resultlabel2.set(float(0.00))
self.label1 = Label(root, textvariable=self.resultlabel1)
self.label1.grid(row=2, column=3, columnspan=1, sticky='WE')
self.label2 = Label(root, textvariable=self.resultlabel2)
self.label2.grid(row=3, column=3, columnspan=1, sticky='WE')
def displayPrice(self, value):
self.resultlabel1.set(self.var.get() / self.materialPrice[value])
self.priceVarLabel1.set(self.materialPrice[value])
def displayPrice2(self, value):
self.resultlabel2.set(self.var2.get() / self.materialPrice[value])
self.priceVarLabel2.set(self.materialPrice[value])
root = Tk()
app = App(root)
root.title("help")
root.mainloop()

It works when I change it to a DoubleVar, like my example.
But is there any way, that I can manage the digit length on the result?
self.priceVarLabel1 = DoubleVar()
self.priceVarLabel1.set(float(0.00))

Related

ttk.Entry not setting default based on textvariable

I have created following window with tkinter and ttk, however I simply can't force the ttk.Entry fields to follow textvariable for its default value, they just keep appearing as blank. Strangely sometimes when I actually cause an exception to occur elsewhere in the window they suddenly work.
class PopUpEdit:
def __init__(self, idx):
self.idx = idx
self.data = get_single(self.idx)
self.have = tk.StringVar(root)
self.site = tk.StringVar(root)
self.title = tk.StringVar(root)
self.tags = tk.StringVar(root)
self._setup_vars()
self._setup_window()
def _setup_window(self):
window = tk.Toplevel(root)
window.geometry('400x600')
pprint.pprint(self.data)
ttk.Label(window, text='Site').grid(row=2, column=1, pady=10, padx=10)
ttk.Entry(window, textvariable=self.site, width=40).grid(row=2, column=2, sticky='e', pady=10, padx=10)
ttk.Label(window, text='Title').grid(row=3, column=1, pady=10, padx=10)
ttk.Entry(window, textvariable=self.title, width=40).grid(row=3, column=2, sticky='e', pady=10, padx=10)
ttk.Label(window, text=self.data['id']).grid(row=4, column=1, pady=10, padx=10)
def _setup_vars(self):
self.title.set(self.data['title'])
self.site.set(self.data['site'])
self.tags.set(self.data['tags'])

Slicing a string and sets it to a label and now the label is not showing

I'm trying to slice a string and now my label wont show..
First I got a DoubleVar with a default float value. Then I'm trying to convert the updated value to a string and then slice it and set the value to the label, whitch result come from an entry and OptionsMenu.
The thing I'm tryng to achieve is to always get a value in the resultlabel1 with 3 decimals, that updates when the entry and OptionsMenu changes.
The code I'm speaking about:
self.resultlabel1 = DoubleVar()
self.resultlabel1.set(float(0.000))
self.label1 = Label(root, textvariable=str(self.resultlabel1)[:5])
self.label1.grid(row=2, column=3, columnspan=1, sticky='WE')
My total code is here:
from tkinter import *
from decimal import *
class App(Frame):
def __init__(self, root=None):
Frame.__init__(self, root)
self.materialPrice = {'Brick': 70, 'Rockwool': 50, 'Concrete': 20}
materialvariable1 = StringVar(self, root)
materialvariable1.set("Choose material")
materialvariable2 = StringVar(self, root)
materialvariable2.set("Choose materiale")
self.w1 = OptionMenu(root, materialvariable1, *self.materialPrice, command=self.displayPrice)
self.w1.grid(row=2, column=0, columnspan=1, sticky='WE')
self.w2 = OptionMenu(root, materialvariable2, *self.materialPrice, command=self.displayPrice2)
self.w2.grid(row=3, column=0, columnspan=1, sticky='WE')
# --------------------------------------------------------------------------------------------------------------------
self.var = DoubleVar()
self.var.set(Decimal("0.100"))
self.var2 = DoubleVar()
self.var2.set(Decimal("0.200"))
self.entry1 = Entry(root, textvariable=self.var)
self.entry1.grid(row=2, column=1)
self.entry2 = Entry(root, textvariable=self.var2)
self.entry2.grid(row=3, column=1)
# --------------------------------------------------------------------------------------------------------------------
self.priceVarLabel1 = DoubleVar()
self.priceVarLabel1.set(float(0.00))
self.priceVarLabel2 = DoubleVar()
self.priceVarLabel2.set(float(0.00))
self.priceVarValue1 = Label(root, textvariable=self.priceVarLabel1, relief='sunken')
self.priceVarValue1.grid(row=2, column=2, columnspan=1, sticky='WE')
self.priceVarValue2 = Label(root, textvariable=self.priceVarLabel2, relief='sunken')
self.priceVarValue2.grid(row=3, column=2, columnspan=1, sticky='WE')
self.resultlabel1 = DoubleVar()
self.resultlabel1.set(float(0.000))
self.resultlabel2 = DoubleVar()
self.resultlabel2.set(float(0.00))
# This is what I got so far!
self.label1 = Label(root, textvariable=str(self.resultlabel1)[:5])
self.label1.grid(row=2, column=3, columnspan=1, sticky='WE')
self.label2 = Label(root, textvariable=self.resultlabel2)
self.label2.grid(row=3, column=3, columnspan=1, sticky='WE')
# --------------------------------------------------------------------------------------------------------------------
self.resultSumNew = DoubleVar()
#self.resultSumNew.set(float(0.00))
self.resultSumNew.set(Decimal("0.000"))
self.labelSum = Label(root, textvariable=self.resultSumNew)
self.labelSum.grid(row=4, column=1, columnspan=1, sticky='WE')
def set_label(name, index, mode):
self.resultSumNew.set(self.var.get() + self.var2.get())
self.var.trace('w', set_label)
self.var2.trace('w', set_label)
# --------------------------------------------------------------------------------------------------------------------
def displayPrice(self, value):
self.resultlabel1.set(self.var.get() / self.materialPrice[value])
self.priceVarLabel1.set(self.materialPrice[value])
def displayPrice2(self, value):
self.resultlabel2.set(self.var2.get() / self.materialPrice[value])
self.priceVarLabel2.set(self.materialPrice[value])
root = Tk()
app = App(root)
root.title("help")
root.mainloop()
I was able to do it this way. Used StringVar for Label text and then sliced it accordingly
self.resultlabel1 = DoubleVar()
self.resultlabel1.set(float(0.000))
self.resultlabel2 = DoubleVar()
self.resultlabel2.set(float(0.00))
self.resultlabel1_str = StringVar()
self.resultlabel1_str.set(str(self.resultlabel1.get()))
self.label1 = Label(root, textvariable=self.resultlabel1_str)
self.label1.grid(row=2, column=3, columnspan=1, sticky='WE')
self.label2 = Label(root, textvariable=self.resultlabel2)
self.label2.grid(row=3, column=3, columnspan=1, sticky='WE')
And in your functions,
def displayPrice(self, value):
self.resultlabel1.set(self.var.get() / self.materialPrice[value])
self.priceVarLabel1.set(self.materialPrice[value])
self.resultlabel1_str.set(str(self.resultlabel1.get())[:5])
def displayPrice2(self, value):
self.resultlabel2.set(self.var2.get() / self.materialPrice[value])
self.priceVarLabel2.set(self.materialPrice[value])
Hope this helps.

why is nothing returned when I invoke .get()

Having trouble setting the file path that is selected by the user and setting to variable. I am able to retrieve the path and set it to display in the entry box but I would like to capture that path and import it into another script. Maybe my logic is flawed here? What am I doing wrong?
import Tkinter
import tkFileDialog
from Tkinter import *
from tkFileDialog import *
class GUI:
def __init__(self, master):
self.master = master
master.title("XML Compare Tool")
master.geometry('700x300')
path1 = StringVar()
path2 = StringVar()
self.bb1 = Button(master, text="Browse", command=lambda: path1.set(askopenfilename()))
self.bb1.grid(row=0, column=0, padx=5, pady=5)
self.bb2 = Button(master, text="Browse", command=lambda: path2.set(askopenfilename()))
self.bb2.grid(row=1, column=0, padx=5, pady=5)
self.confirm = Button(master, text="Confirm", command='')
self.confirm.grid(row=3, column=1, padx=5, pady=5, sticky='')
self.entry1 = Entry(master, width=75, textvariable=path1)
self.entry1.grid(row=0, column=1, columnspan=2, sticky=W)
print path1.get()
self.entry2 = Entry(master, width=75, textvariable=path2)
self.entry2.grid(row=1, column=1, sticky=W)
self.t_label = Label(master, text="Script Output")
self.t_label.grid(row=4, column=1, columnspan=1, sticky='')
self.t_frame = Frame(master, bg="white", height=150, width=600)
self.t_frame.grid(row=5, column=1, columnspan=1, sticky='')
self.t_text = Text(self.t_frame)
root = Tk()
my_gui = GUI(root)
root.mainloop()
You do not need to use a textvariable, you can just use variable = entry1.get(). A Tkinter textvariable is not like a traditional python variable, it is just used for setting the text in an entry.

Tkinter Label Overwrite

I'm using Tkinter to do a small project. Long story short, I want a label to generate some stuff on creation.
Later on, I want to print a label in the same spot but with different text.
I cannot for the life of me figure out how to remove the previous text.
What I wind up with in this example is the text "Does this even work" printed on top of "ALL I WANT IS A VERY LONG AND ANNOYING SENTENCE FOR TESTING"
Thanks!
from Tkinter import *
import pygal
class Application(Frame) :
def __init__(self, root) :
Frame.__init__(self, root)
self.root = root
self.grid()
self.create_widgets()
def create_widgets(self) :
queryLabel = Label(self, text = "Enter your query :")
queryLabel.grid(row=0, column=0, sticky=W)
self.userQuery = StringVar()
qEntry = Entry(self, textvariable=self.userQuery)
qEntry.grid(row=0, column=1, sticky=W)
queryTypeLabel = Label(self,text="Selecting query type: ")
queryTypeLabel.grid(row=2, column=0, sticky=W)
self.searchType = StringVar()
authorButton = Radiobutton( self, text="Author", variable=self.searchType, value="author")
authorButton.grid(row=3,column=0,sticky=W)
memberButton = Radiobutton( self, text="PC Member", variable=self.searchType, value="pcmember")
memberButton.grid(row=3,column=1,sticky=W)
affilButton = Radiobutton( self, text="Affiliation", variable=self.searchType, value="affiliation")
affilButton.grid(row=3,column=2,sticky=W)
self.conference = BooleanVar()
confCheck = Checkbutton(self, text="Select Conference?", variable = self.conference)
confCheck.grid(row=4,column=0,sticky=W)
self.conferenceName = StringVar()
self.conferenceName.set('No Preference')
confDropDown = OptionMenu(self, self.conferenceName, *conferenceOptions)
confDropDown.grid(row=4,column=1,sticky=W)
submit_button = Button( self, text="Submit", command = self.reveal)
submit_button.grid(row=5, column = 0, sticky = W)
#self.graphics_button = Button( self, text="I want Statistics!", command=self.graphics)
#self.graphics_button.grid(row=5, column = 1, sticky= W)
label1 = Label(root, text="ALL I WANT IS A VERY LONG AND ANNOYING SENTENCE FOR TESTING")
label1.grid(row=6, column=0, columnspan=5, sticky=W)
def reveal(self) :
#root.submit_button.grid_destroy()
self.label1 = Label(root, text="Does this even work?")
self.label1.grid(row=6, column=0, columnspan=5, sticky=W)
Bunch of MySQL stuff deleted
### Launch the UI
root = Tk()
root.geometry("800x800+300+300")
app = Application(root)
In reveal, you're creating a new Label which you grid in the same place as the previous label. What you want to do is use this:
# Make label1 an attribute of self to be able to reference it in reveal
self.label1 = Label(root, text="ALL I WANT IS A VERY LONG AND ANNOYING SENTENCE FOR TESTING")
self.label1.grid(row=6, column=0, columnspan=5, sticky=W)
def reveal(self) :
#root.submit_button.grid_destroy()
# Do not create a new Label, but change the existing one
self.label1.config(text="Does this even work?")
I had the exact same issue, and it was incredibly annoying--trying both grid_destroy() and grid_forget(). Neither worked. What worked for me was to call the label 2 times, the first time with many spaces, and the second with what I actually wanted to show. This way, the label content is overwriting spaces, not old content. I know this is not the best way to do this, but it gets me the result I want without a headache:
NumAssetsLabel = tk.Label(self, text="Num of Assets: ", font=('Helvetica', 10))
NumAssetsLabel.grid(row=9, column=3, pady=20, padx=10, sticky="w", columnspan=2)
NumAssetsLabel = tk.Label(self, text="Num of Assets: %s"%runCheck, font=('Helvetica', 10))
NumAssetsLabel.grid(row=9, column=3, pady=20, padx=10, sticky="w", columnspan=2)
Note that I have columnspan=2, to make sure that the number of spaces does not impact the grid.

How to use tkinter's widget.config() to modify separate widgets that were created by the same method?

I'm pretty new to Python. I can MAKE things work, but I'm never really sure if I'm actually using best practices, so forgive me if I'm not explaining things correctly, or if my code isn't written using best practices. I'm working on it!
I'm trying to figure out how to use tkinter's widget.config() to modify separate widgets that were created by the same method? For example, in the code below, how can I use widget.config() to modify the text in results section 2, r2??
from tkinter import *
from tkinter.ttk import *
class App():
def __init__(self, master):
self.master = master
self.master.title('Question')
self.create_main_frame()
def create_main_frame(self):
self.main_f = Frame(self.master)
nb = Notebook(padding=5)
nb.pack(anchor='w')
self.tab1(nb)
def tab1(self, nb):
tab1_frame = Frame(nb)
nb.add(tab1_frame, text='Tab 1', underline=0)
prod_lab = Label(tab1_frame, text='Entry:')
prod_lab.grid(row=1, column=0, padx=(10,0), pady=(10,5), sticky='e')
self.product_e = Entry(tab1_frame, width=40)
self.product_e.grid(row=1, column=1, padx=(0,10), pady=(10,5))
self.button1 = Button(tab1_frame,
text="Run",
command=self.run1
)
self.button1.grid(row=2, column=1, padx=(0,10), pady=(0,10), sticky='ne')
self.results1 = self.create_result(tab1_frame, 'Results Section 1')
self.results2 = self.create_result(tab1_frame, 'Results Section 2')
self.results3 = self.create_result(tab1_frame, 'Results Section 3')
def create_result(self, frame, name):
lab_frame = LabelFrame(master=frame, text=name)
lab_frame.grid(sticky='we', padx=10, pady=10, columnspan=10)
l1 = Label(master=lab_frame, text='Result 1:')
l1.grid(sticky='e', row=0, column=0, pady=2)
l2 = Label(master=lab_frame, text='Result 2:')
l2.grid(sticky='e', row=1, column=0, pady=2)
l3 = Label(master=lab_frame, text='Result 3:')
l3.grid(sticky='e', row=2, column=0, pady=2)
r1 = Label(master=lab_frame, text='')
r1.grid(sticky='w', row=0, column=1, pady=2)
r2 = Label(master=lab_frame, text='')
r2.grid(sticky='w', row=1, column=1, pady=2)
r3 = Label(master=lab_frame, text='')
r3.grid(sticky='w', row=2, column=1, pady=2)
def run1(self):
#This is the method that will be used to find the results I need
#For the sake of this question, let's pretend I want to put whatever text is in Entry 1, into results section 2 result 2
print (self.product_e.get())
print ('How do I use "widget.config()" to modify the 3 results sections separately???')
master = Tk()
app = App(master)
master.mainloop()
Thanks so much in advance for your help!
I'm not good in Tkinter so I would change create_result() to class Results.
from Tkinter import *
from ttk import *
class Results():
def __init__(self, frame, name):
self.lab_frame = LabelFrame(master=frame, text=name)
self.lab_frame.grid(sticky='we', padx=10, pady=10, columnspan=10)
self.l1 = Label(master=self.lab_frame, text='Result 1:')
self.l1.grid(sticky='e', row=0, column=0, pady=2)
self.l2 = Label(master=self.lab_frame, text='Result 2:')
self.l2.grid(sticky='e', row=1, column=0, pady=2)
self.l3 = Label(master=self.lab_frame, text='Result 3:')
self.l3.grid(sticky='e', row=2, column=0, pady=2)
self.r1 = Label(master=self.lab_frame, text='')
self.r1.grid(sticky='w', row=0, column=1, pady=2)
self.r2 = Label(master=self.lab_frame, text='')
self.r2.grid(sticky='w', row=1, column=1, pady=2)
self.r3 = Label(master=self.lab_frame, text='')
self.r3.grid(sticky='w', row=2, column=1, pady=2)
class App():
def __init__(self, master):
self.master = master
self.master.title('Question')
self.create_main_frame()
def create_main_frame(self):
self.main_f = Frame(self.master)
nb = Notebook(padding=5)
nb.pack(anchor='w')
self.tab1(nb)
def tab1(self, nb):
tab1_frame = Frame(nb)
nb.add(tab1_frame, text='Tab 1', underline=0)
prod_lab = Label(tab1_frame, text='Entry:')
prod_lab.grid(row=1, column=0, padx=(10,0), pady=(10,5), sticky='e')
self.product_e = Entry(tab1_frame, width=40)
self.product_e.grid(row=1, column=1, padx=(0,10), pady=(10,5))
self.button1 = Button(tab1_frame,
text="Run",
command=self.run1
)
self.button1.grid(row=2, column=1, padx=(0,10), pady=(0,10), sticky='ne')
self.results1 = Results(tab1_frame, 'Results Section 1')
self.results2 = Results(tab1_frame, 'Results Section 2')
self.results3 = Results(tab1_frame, 'Results Section 3')
def run1(self):
#This is the method that will be used to find the results I need
#For the sake of this question, let's pretend I want to put whatever text is in Entry 1, into results section 2 result 2
print (self.product_e.get())
print ('How do I use "widget.config()" to modify the 3 results sections separately???')
self.results1.r2.config(text='1111111111')
self.results2.r2.config(text='xxxxxxxxxx')
self.results3.r2.config(text='----------')
master = Tk()
app = App(master)
master.mainloop()

Categories

Resources