Label and value display - python

I'm using a simple code that displays the square root of a number in a label, but for some reason the values get overlaped in a way that I couldn't avoid it, which means that, if I use it for a number that has a exact square root, then the answer goes messed up with the previous answer of many digits.
I've been use the next code so far:
from Tkinter import *
def square_calc():
x = x_val.get()
sqx = x ** 0.5
print x, "** 0.5 =", sqx
sqx_txt = Label(root, text = "x ** 0.5 =").grid(row=3, column=0)
sqx_lab = Label(root, text = sqx).grid(row=3, column=1)
root = Tk()
root.title("Calculating square root")
x_val = DoubleVar()
x_lab = Label(root, text = "x").grid(row=0, column=0)
nmb = Entry(root, textvariable = x_val).grid(row=0, column=1)
calc = Button(root, text = "Calculate", command=square_calc).grid(columnspan=2)
y_lab = Label(root, text = " ").grid(row=3, column=0)
root.mainloop()

The problem is that, every time you call square_calc(), you are simply creating and placing another Label. The right way to do this is to create a Label outside the function, then have the function update the Label's text with mylabel.config(text='new text').

The display is getting messed-up because every time your square_calc() function is called it creates new pair of Labels, but this may leave some parts of any previous ones visible. Since the one on the left is the same every time, so it's not noticeable with it, but the text in one on the right in column 1 is potentially different every time.
A simple way to fix that is to make the Label a global variable and create it outside the function, and then just change its contents in the function. As with all Tkinter widgets, this is can be done after it's created by calling the existing obj's config() method.
Here's a minimally-modified version of your code that illustrates doing that. Note, it also adds a sticky keyword arugment to the grid() method call for the label to left-justify it within the grid cell so it's closer to the text label immediately to its left (otherwise it would be center-justified within the cell).
from Tkinter import *
def square_calc():
x = x_val.get()
sqx = x ** 0.5
# print x, "** 0.5 =", sqx
sqx_txt = Label(root, text = "x ** 0.5 =").grid(row=3, column=0)
sqx_lab.config(text=sqx)
sqx_lab.grid(row=3, column=1, sticky=W)
root = Tk()
root.title("Calculating square root")
x_val = DoubleVar()
x_lab = Label(root, text = "x").grid(row=0, column=0)
nmb = Entry(root, textvariable = x_val).grid(row=0, column=1)
calc = Button(root, text = "Calculate", command=square_calc).grid(columnspan=2)
y_lab = Label(root, text = " ").grid(row=3, column=0)
sqx_lab = Label(root, text = " ")
root.mainloop()
There's another potentially serious flaw in your code. All those assignments of the form
variable = Widget(...).grid(...)
result in assigning the value None to the variable because that's what the grid() method returns. I didn't fix them because they do no harm in this cause since none of those variables are ever referenced again, but it would have been a problem if the new globally variable sqx_lab had been done that way since it is referenced elsewhere.

Related

One of my variables is being printed but the other is not in tkinter Entry boxes

I'm trying to create a function in tkinter where I can print out what the user writes in a Entry box. I'm able to print out ask_an_entry_get, but when I try to print what_is_answer_entry_get
, I get nothing my empty spaces.
Please find out the problem here. Also I'm using the Entry widget, along with the get() function, to get input from the user.
def answer_quizmaker_score():
print(ask_an_entry_get)
print(what_is_answer_entry_get)
I made a lot of global variables so I could use them all around my code.
global what_is_answer_entry
what_is_answer_entry = Entry(root4)
what_is_answer_entry.pack()
I then used the get() function to retrieve what the user typed.
global what_is_answer_entry_get
what_is_answer_entry_get = what_is_answer_entry.get()
This is the exact process I did for both ask_an_entry_get and what_is_answer_entry_get. However for some reason only ask_an_entry_get is printed, while what_is_answer_entry_get is printing nothing in the console.
from tkinter import *
root = Tk()
root.geometry("500x500")
txt1 = StringVar()
txt2 = StringVar()
def txt_printer():
print(txt1.get())
print(txt2.get())
x = Entry(root, textvariable=txt1, width=20)
x.place(x=0, y=0)
y = Entry(root, textvariable=txt2, width=20)
y.place(x=0, y=50)
btn_print = Button(root, text="print", command=txt_printer)
btn_print.place(x=0, y=100)
# Or if you want to show the txt on window then:
def txt_on_window():
lb1 = Label(root, text=txt1.get())
lb1.place(x=0, y=200)
lb2 = Label(root, text=txt2.get())
lb2.place(x=0, y=235)
btn_print_on_window = Button(root, text="print on screen", command=txt_on_window)
btn_print_on_window.place(x=0, y=150)
root.mainloop()

Python/Tkinter - clear the graphical interface screen

i am developing an application to calculate some taxes and show the result in the graphical interface. The code itself works perfectly, but if i use numbers with bigger squares, the result overlaps over the previous one. My question is, is it possible to clear the previous result and calculate the new one?
Follow the complete code below:
from tkinter import *
root = Tk()
l_vlrRec = Label(root, text='Receita')
l_vlrRec.place(x=10, y=10)
e_vlrRec = Entry(root)
e_vlrRec.place(x=75, y=10, width=75)
def calcular():
receita = float(e_vlrRec.get())
l_result = Label(root, text='{:.2f}'.format(receita))
l_result.place(x=10, y=150)
e_vlrRec.delete(0, END)
bt = Button(root, text='Calcular', command=calcular)
bt.place(x=10, y=50)
root.mainloop()
You can use the label's textvariable and also you don't have to instantiate a new Label every time the button is pressed:
v_result = DoubleVar()
l_result = Label(root, textvariable=v_result)
l_result.place(x=10, y=150)
def calcular():
v_result.set(round(float(e_vlrRec.get()),2))
You can do the same for your Entry object e_vlrRec so you don't have to cast the string you get by calling e_vlrRec.get() but use the variable's get() instead
Without using textvariable you can also reconfigure the label's text parameter:
l_result.configure(text='{:.2f}'.format(receita))
or
l_result['text'] = '{:.2f}'.format(receita)

How to alter attributes in Tkinter

Is there any way to alter options of a widget after creating/drawing it? I can't seem to find any way to do so. What I'm currently aiming for is altering the fg of a Label once its temp0 textvariable is >= 50.
This code is part of a bigger program, so I didn't want to put all of that here, since the essential part is that I am not sure how to change the fg (i.e. font color) for that Label once I get the b[0] value and find out that it is above 50. Is the self.t0.config(fg="red") the proper syntax for that?
class App:
def __init__(self, master):
#live updating TkInter variables
self.temp0 = DoubleVar()
frame = Frame(master)
self.t0 = Label(frame, fg="blue", textvariable=self.temp0,font=(20)).grid(row=2, column=0)
frame.pack(padx=10, pady=10)
def start(self):
# calculates temperature
self.temp0.set(b[0])
# changes color of text to red if temp >= 50
if b[0] >= 50:
self.t0.config(fg="red")
Yes that works. You can use either:
self.t0.config(fg="red")
or:
self.t0["fg"] = "red"
Both methods do the same thing, so you can choose what you want.
Also, to get everything working, you will want to make this line of code:
self.t0 = Label(frame, fg="blue", textvariable=self.temp0,font=(20)).grid(row=2, column=0)
into two lines:
self.t0 = Label(frame, fg="blue", textvariable=self.temp0,font=(20))
self.t0.grid(row=2, column=0)
Now, self.t0 will point to the label like it should and not the return value of .grid, which is None.

Tkinter Program for making a calculator

I am trying to make a simple GUI calculator just for addition/subtraction in the beginning. I am able to print the result to the console but I want to print it to the Entry box like the First Name entry box for example but not able to do it. I would really appreciate if you could help.(*Please neglect the alignment right now of the buttons I am focusing on the functioning, trying to get it right)
from Tkinter import *
import tkMessageBox
import sys
class scanner:
list1 = []
def __init__(self,parent):
self.entrytext = StringVar()
self.entrytext1 = StringVar()
Label(root, text="first name", width=10).grid(row=0,column=0)
Entry(root, textvariable=self.entrytext, width=10).grid(row=0,column=1)
Label(root, text="last name", width=10).grid(row=1,column=0)
Entry(root, textvariable=self.entrytext1, width=10).grid(row=1,column=1)
Button(root, text="ADD", command=self.add).grid()
Button(root, text="SUBTRACT", command=self.subtract).grid()
def add(self):
global a
global b
self.a=int(self.entrytext.get())
self.b=int(self.entrytext1.get())
print "result is", self.a+self.b
def subtract(self):
global a
global b
self.a=int(self.entrytext.get())
self.b=int(self.entrytext1.get())
print "result is", self.a-self.b
root= Tk()
root.geometry("300x300")
calc = scanner(root)
root.mainloop()
If you want to show the result of the operation as a label's text, just create a new label and configure it with the text option and the string you are printing as its value. As a side note, you don't need the global statements, and the use of instance variables is not necessary either. However, it is very important to check that the content of the entries are actually valid numbers:
def __init__(self,parent):
# ...
self.result = Label(root, text='')
self.result.grid(row=4, column=0)
def add(self):
try:
a = int(self.entrytext.get())
b = int(self.entrytext1.get())
self.result.config(text=str(a+b))
except ValueError:
print("Incorrect values")
To add entry text to the widget, use the insert method. To replace the current text, you can call delete before you insert the new text.
e = Entry(master)
e.pack()
e.delete(0, END)
e.insert(0, "a default value")
The first parameter in the delete method is which number character to delete from and the second parameter is where to delete too. Notice how END is a tkinter variable.
The parameters for the insert function is where the text will be inserted too, and the second parameter is what will be inserted.
In the future, I recommend going to Effbot and reading about the widget that you are trying to use to find out all about it.

How to arrange numbers in Label into grid in Tkinter?

I create a sudoku solver and I want to show candidates for each cell. Sudoku grid is list of Label widgets and I have a problem with arranging these candidates into grid. My goal is something like this (without colors). I already have them in grid, but number "0" is still visible. And I´m asking you how to hide these zeros. I tried to substitute "0" with space (" "), but brackets are displayed instead.
My code:
from Tkinter import *
root = Tk()
text_good = [1,2,3,4,5,6,7,8,9]
text_wrong1 = [1,2,3,4,0,0,0,8,9]
text_wrong2 = [1,2,3,4," "," "," ",8,9]
L1 = Label(root,bg="red",text=text_good,wraplength=30)
L1.place(x=0,y=0,width=50,height=50)
L2 = Label(root,bg="red",text=text_wrong1,wraplength=30)
L2.place(x=50,y=0,width=50,height=50)
L3 = Label(root,bg="red",text=text_wrong2,wraplength=30)
L3.place(x=100,y=0,width=50,height=50)
root.mainloop()
I hope I described my problem well. I appreciate any answer.
Thank you
Use text_wrong2 = ' '.join(map(str,[1,2,3,4," "," "," ",8,9])) instead of passing directly the list as the text option. Remember that the default font is not monospaced, so the numbers won't be aligned as in the other two examples.
Apart from that, I recommend you to use grid instead of place, and represent each number using a Label, instead of using only one for each cell and relying on the new lines that are added because of the width. Thus, you don't have to worry about handling the offsets for each label.
from Tkinter import *
root = Tk()
text_good = [1,2,3,4,5,6,7,8,9]
text_wrong1 = [1,2,3,4,0,0,0,8,9]
text_wrong2 = [1,2,3,4," "," "," ",8,9]
def create_box(text_list, **grid_options):
frame = Frame(root, bg="red")
for i, text in enumerate(text_list):
Label(frame, text=text, bg="red").grid(row=i//3, column=i%3)
frame.grid(**grid_options)
create_box(text_good, row=0, column=0, padx=10)
create_box(text_wrong1, row=0, column=1, padx=10)
create_box(text_wrong2, row=0, column=2, padx=10)
root.mainloop()

Categories

Resources