Canvas Text update - Python3 Tkinter - python

I have a tkinter Canvas with a C.create_text, determined by a variable.
var = "Hello"
C = tk.Canvas(top, width = 1000, height = 500)
p = C.create_text(500, 80, text = var, font = "monaco")
and when I press a button it changes the variable, but I have no idea how to update the text in the canvas
def add():
var = "Hello World"
b = tk.Button(text = "world", command = add)

Use
C.itemconfigure(p, text=var)

Related

Python tkinter how to get value from an entry box

I am trying to make a little thing in python like JOpenframe is java and I'm trying to make an entry box. That works fine but when I try to get the value and assign it to variable "t" nothing works. This is what I have:
def ButtonBox(text):
root = Tk()
root.geometry("300x150")
t = Label(root, text = text, font = ("Times New Roman", 14))
t.pack()
e = Entry(root, borderwidth = 5, width = 50)
e.pack()
def Stop():
root.destroy()
g = e.get()
ok = Button(root, text = "OK", command = Stop)
ok.pack()
root.mainloop()
t = ButtonBox("f")
I've tried to make "g" a global variable but that doesn't work. I have no idea how to get the value from this, and I'm hoping someone who does can help me out. Thanks!
If you want to return the value of the entry box after ButtonBox() exits, you need to:
initialize g inside ButtonBox()
declare g as nonlocal variable inside inner function Stop()
call g = e.get() before destroying the window
Below is the modified code:
from tkinter import *
def ButtonBox(text):
g = "" # initialize g
root = Tk()
root.geometry("300x150")
t = Label(root, text = text, font = ("Times New Roman", 14))
t.pack()
e = Entry(root, borderwidth = 5, width = 50)
e.pack()
def Stop():
# declare g as nonlocal variable
nonlocal g
# get the value of the entry box before destroying window
g = e.get()
root.destroy()
ok = Button(root, text = "OK", command = Stop)
ok.pack()
root.mainloop()
# return the value of the entry box
return g
t = ButtonBox("f")
print(t)

How to save a data after closing a window?

I'm trying to make some GUI on Python3 with tkinter. So far I have Main Window and 'Test' button on it, which opens second window. Second window has entry, label, save and close buttons. When you type something in entry and press save button, label shows the text you typed in entry. But after closing this window and opening it again, label shows nothing. How do I make this label to show the text that were typed last time before closing? For example, I type 'Hi' in entry, press 'Save', then I press 'Close', then I open this window again and label shows 'Hi'
import tkinter as tk
def save_data(entry, t):
t.config(text = entry.get())
def close_action(current_window):
current_window.destroy()
def insertMainInfo():
new_window = tk.Tk()
new_window.geometry("307x131")
new_window.title("TestWindow")
test_entry = tk.Entry(new_window)
test_entry.place(relx = 0.283, rely = 0.1, height = 24, width = 127)
text = tk.Label(new_window)
text.place(relx = 0.283, rely = 0.25, height = 24, width = 127)
save_button = tk.Button(new_window, command = lambda: save_data(test_entry, text))
save_button.place(relx=0.283, rely=0.45, height=24, width=127)
save_button.configure(text = "Save")
close = tk.Button(new_window, command = lambda: close_action(new_window))
close.place(relx=0.283, rely=0.687, height=24, width=127)
close.configure(text = "Close")
new_window.mainloop()
if __name__ == '__main__':
top = tk.Tk()
top.geometry("307x131+557+330")
top.resizable(width=False, height=False)
top.title("MainWindow")
new_window_button = tk.Button(top, command = insertMainInfo)
new_window_button.place(relx=0.283, rely=0.687, height=24, width=127)
new_window_button.configure(text = "Test")
main_label = tk.Label(top)
main_label.place(relx=0.033, rely=0.153, height=41, width=284)
main_label.configure(text = "TestLabel")
top.mainloop()
I have to confess that your question heading is a bit ambiguity.
If you just want to update a label of last entry, here a simple way of modifying your code.
As advised, as a good practice we only have one Tk() in a program, other new windows or pop-up windows should use Toplevel() of tkinter class; So I use this in your insertMainInfo() function.
The point here is to define a variable, I called last_entry and initially is empty or ‘’. Use this as parameter in new_window button in main program (after if __name__ == '__main__': ) to this variable (I also add lambda function here).
Then we define it as global in save_data function, so as it can be known later by other functions or main program as the last entry before new_window is closed.
Here I modify your code as said above, and I have tested it, and it works as expected.
import tkinter as tk
def save_data(entry, t):
global last_entry
last_entry = entry.get()
t.config(text = last_entry)
def close_action(current_window):
current_window.destroy()
def insertMainInfo(last_entry):
new_window = tk.Toplevel()
new_window.geometry("307x131")
new_window.title("TestWindow")
test_entry = tk.Entry(new_window)
test_entry.place(relx = 0.283, rely = 0.1, height = 24, width = 127)
text = tk.Label(new_window, text=last_entry)
text.place(relx = 0.283, rely = 0.25, height = 24, width = 127)
save_button = tk.Button(new_window, command = lambda: save_data(test_entry, text))
save_button.place(relx=0.283, rely=0.45, height=24, width=127)
save_button.configure(text = "Save")
close = tk.Button(new_window, command = lambda: close_action(new_window))
close.place(relx=0.283, rely=0.687, height=24, width=127)
close.configure(text = "Close")
new_window.mainloop()
# --- A Simple Data Structure ---
last_entry = ''
if __name__ == '__main__':
top = tk.Tk()
top.geometry("307x131+557+330")
top.resizable(width=False, height=False)
top.title("MainWindow")
new_window_button = tk.Button(top, command = lambda: insertMainInfo(last_entry))
new_window_button.place(relx=0.283, rely=0.687, height=24, width=127)
new_window_button.configure(text = "Test")
main_label = tk.Label(top)
main_label.place(relx=0.033, rely=0.153, height=41, width=284)
main_label.configure(text = "TestLabel")
top.mainloop()

Changing the show of an entry box numerous times

I would like the contents of this my entry box to be uncovered from the * when the button is clicked, but then recovered when it is clicked again, and so on. Any ideas?
The code i have currently:
password_entry = Entry(root, width = 45, textvariable=user_password, show = "*")
def Show():
password_entry.config(show="")
show_password = Button(canvas, width = 31, height = 17, image = eye_img, bg = "gray33", relief = "flat", command = Show)
This only uncovers the password, and does not recover it when the button is reclicked.
Its seems that you are trying to make a toggle button. Edit your function. Get the value of current show. If it is * then change it to , if it is then change it to *. Your function can be:
def Show():
password_entry["show"] = "*" if password_entry["show"] == "" else ""
Here is a sample code that works like expected:
from tkinter import *
root = Tk()
password_entry = Entry(root, width = 45, show = "*")
password_entry.grid(row=0,column=0)
def Show():
password_entry["show"] = "*" if password_entry["show"] == "" else ""
show_password = Button(root,text="Show Password",bg = "gray33", relief = "flat", command = Show)
show_password.grid(row=0,column=1)
root.mainloop()

TypeError: 'float' object has no attribute '__getitem__'. (Python)

import Tkinter
import tkMessageBox
from Tkinter import *
CanvasHeight = 500
CanvasWidth = 600
Canvas width and height set to 10x the maximum of the variables.
IsGraphHidden = 0
MainWindow = Tkinter.Tk()
This is the window for all the sliders, and is defined as "MainWindow" for later use.
Strength = DoubleVar()
Multiple = DoubleVar()
Time = DoubleVar()
All of the variables set to DoubleVar, because of the Tkinter plugin.
It needs it's own special floats, integers and strings to work.
They can be accessed as normal variables by using VARIABLE.get()
coords = []
lastcoords = [0,0]
This is what we'll use to continue the line instead of just having a bunch of lines drawing themselves from the corner of the screen.
Plot = DoubleVar()
StrengthScale = Scale( MainWindow, variable = Strength, orient = HORIZONTAL,label="Strength")
MultipleScale = Scale( MainWindow, variable = Multiple, from_ = float(0), to = float(1), resolution = float(0.01), orient = HORIZONTAL, label="Multiple")
TimeScale = Scale( MainWindow, variable = Time, orient = HORIZONTAL, from_ = int(0), to = int(120), label="Time")
These are the procedures for the buttons, as well as the rest of the code.
def Calculate():
answer = float(Strength.get())*float(Multiple.get())
tkMessageBox.showinfo("Answer:", answer)
def PrepPlot():
global IsGraphHidden
global coords
global lastcoords
lastcoords0 = lastcoords[0]
lastcoords1 = lastcoords[1]
coords.append(lastcoords0)
coords.append(lastcoords1)
coords.append(Time.get()*5)
coords.append(Strength.get()*Multiple.get()*5)
lastcoords = Time.get()*5
lastcoords = Strength.get()*Multiple.get()*5
if IsGraphHidden == 0:
Graph = Canvas(MainWindow, width = CanvasWidth, height = CanvasHeight, bg = "white")
Graph.create_line(coords, fill = "black")
Graph.grid(row=5, column=1)
else:
Graph.destroy()
Graph.delete("all")
Graph.create_line(coords, fill = "black")
Graph.grid(row=5,column=1)
IsGraphHidden = 1
def DisplayPoints():
PointWindow = Tkinter.Tk()
Text = Label(PointWindow, textvariable = "Hi there", relief=RAISED)
Text.pack()
PointWindow.mainloop() #Work in progress, nothin' to see here.
Button = Tkinter.Button(MainWindow, text= "Calculate",command = Calculate)
PrepButton = Tkinter.Button(MainWindow, text = "Plot", command = PrepPlot) #The text is the text on the button.
DisplayButton = Tkinter.Button(MainWindow, text = "Display Plots", command = DisplayPoints)
MultipleScale.grid(row=0,column=0)
StrengthScale.grid(row=1,column=0)
TimeScale.grid(row=1,column=2)
PrepButton.grid(row=2,column=1)
Button.grid(row=4,column=1)
DisplayButton.grid(row=3,column=1)
MainWindow.mainloop()
I need some help with the float object getitem error, I'm doing this code for work experience at Manchester university...
You replaced the lastcoords list with a floating point value:
lastcoords = Time.get()*5
lastcoords = Strength.get()*Multiple.get()*5
so that next time around the line:
lastcoords0 = lastcoords[0]
raises your exception as you cannot use subscription on a floating point value.
I think you wanted to set a new list instead:
lastcoords = [Time.get() * 5, Strength.get() * Multiple.get() * 5]

How do I make a tkinter entry widget?

This is my code:
import random
from tkinter import *
root=Tk()
a=Canvas(root, width=1000, height=1000)
a.pack()
e = Entry(root)
paralist = []
x=random.randint(1,10)
file = open("groupproject.txt")
line = file.readline()
for line in file:
paralist.append(line.replace("\n", ""));
a.create_text(500,50, text = "Typing Fun", width = 700, font = "Verdana", fill = "purple")
a.create_text(500,300, text = paralist[x], width = 700, font = "Times", fill = "purple")
#master = Tk()
#a = Entry(master)
#a.pack()
#a.focus_set()
#def callback():
# print (a.get())
root.mainloop()
The commented section is supposed to print an entry widget underneath a paragraph but instead it gives an error IndexError: list index out of range for line a.create_text(500,300, text = paralist[x], width = 700, font = "Times", fill = "purple"). If I use e instead of a it works but opens the entry widget in a separate window.
I'm trying to make the tkinter entry widget appear in the same window as the text. Can someone please tell me how to do this?
First off,
paralist = []
The list is empty so a random word between 1 and 10 will be wrong since theres nothing in the list.
master = Tk() # since Tk() is already assigned to root this will make a new window
a = Entry(master) # a is already assigned to canvas
a.pack() # this is already declare under a=canvas
a.focus_set()
def callback():
print (a.get())
Edit:
I suspect that your file might be the problem. This code:
import random
from tkinter import *
root = Tk()
a = Canvas(root, width = 400, height = 400)
a.pack()
e = Entry(root)
e.pack()
paralist = []
x = random.randint(1,10)
file = open("teste.txt")
line = file.readline()
for line in file:
paralist.append(line.replace("\n", ""));
a.create_text(200,50, text = "Typing Fun", width = 700, font = "Verdana", fill = "purple")
a.create_text(200,300, text = paralist[x], width = 700, font = "Times", fill = "purple")
b = Entry(root)
b.pack()
b.focus_set()
def callback():
print (a.get())
root.mainloop()
With this as "teste.txt":
test0
test1
test2
test3
test4
test5
test6
test7
test8
test9
test10
Works fine for me.
import tkinter
window = tkinter. Tk()
window.geometry('200x200')
ent= tkinter.Entry(window)
ent.pack()
This is the easiest way to do it in tkinter. If you need something else Just ask me:)

Categories