Reverting text and entry boxes on a tkinter canvas - python

In this code, entering an integer and clicking the process button shows a number of entry boxes. I want the back button to act as a reverting button which makes the entry boxes disappear and bring the GUI to its original state. How can I do this?
import tkinter as tk
import tkinter.ttk as ttk
hht=[]
tks = []
window = tk.Tk()
def open_window(pll):
numh = int(pll)
l0 = tk.Label(canvas, text="H T", font="Calibri 12", bg="white")
canvas.create_window(390,125, window=l0, anchor=tk.NW)
for i in range(numh):
hht.append(tk.StringVar())
tks.append(tk.StringVar())
en = ttk.Entry(canvas, textvariable = hht[i])
en.config({"background": "gainsboro"})
canvas.create_window(350, 150+i*25, window=en, anchor=tk.NW)
aen = ttk.Entry(canvas, textvariable = tks[i])
aen.config({"background": "gainsboro"})
canvas.create_window(500, 150+i*25, window=aen, anchor=tk.NW)
ws = window.winfo_screenwidth()
hs = window.winfo_screenheight()
w = 700 # width for the Tk root
h = 410 # height for the Tk root
x = (ws / 2) - (w / 2)
y = (hs / 2) - (h / 2)
window.geometry('%dx%d+%d+%d' % (w, h, x, y))
canvas = tk.Canvas(window,bg="white",width=700, height=410, highlightthickness=0)
canvas.pack()
l13= tk.Label(canvas, text="Enter Numbers", font="Calibri 16", bg="white")
canvas.create_window(300,8, window=l13, anchor=tk.NW)
l0 = tk.Label(canvas, text="Entry", font="Calibri 12", bg="white")
canvas.create_window(15,58, window=l0, anchor=tk.NW)
PLz = tk.DoubleVar()
entry_PLz = ttk.Entry(canvas, textvariable=PLz)
entry_PLz.config({"background": "gainsboro"})
canvas.create_window(270,70, window=entry_PLz)
submit_button = ttk.Button(canvas, text="Process >>", command=lambda: open_window(PLz.get()))
canvas.create_window(300, 100, window=submit_button, anchor=tk.NW)
back_button = ttk.Button(canvas, text="Back")
canvas.create_window(450, 100, window=back_button, anchor=tk.NW)
window.resizable(False, False)
window.mainloop()

Related

Multiple frames within Tkinter

I am experimenting with Tkinter to build a simple UI. This will contain a similar structure to the below:
Menu
Settings
Action1
Etc...
I want Menu to be my main frame, and there to be some general stuff on there and then buttons to the other frames.
I have been using some code I found here as a baseline but my amendments failed to work as expected. For example, why do the Label's and Entry's I place not show?
Code is as follows:
import tkinter as tk
def raise_frame(frame):
frame.tkraise()
root = tk.Tk()
root.title("Name")
width=400
height=500
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
root.geometry(alignstr)
root.resizable(width=False, height=False)
f1 = tk.Frame(root)
f2 = tk.Frame(root)
f3 = tk.Frame(root)
f4 = tk.Frame(root)
title = tk.Label(f1, text = "Title", background = '#3b5997', foreground ="white", font = ("Times New Roman", 25))
title.place(x=100,y=20,width=200,height=50)
eg1 = tk.Label(f1, text="Text :")
eg1.place(x=10,y=195,width=70,height=25)
eg2 = tk.Label(f1, text="Text")
eg2.place(x=290,y=195,width=70,height=25)
eg3 = tk.Entry(f1, width=20)
eg3.place(x=100,y=195,width=200,height=25)
raise_frame(f1)
root.mainloop()
I have used .grid() and pack() but never used place however I found the issue.
you need to use .place() for frame f1 as well, after the content that you want in that frame.
import tkinter as tk
def raise_frame(frame):
frame.tkraise()
root = tk.Tk()
root.title("Name")
width=400
height=500
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
root.geometry(alignstr)
root.resizable(width=False, height=False)
f1 = tk.Frame(root)
f2 = tk.Frame(root)
f3 = tk.Frame(root)
f4 = tk.Frame(root)
title = tk.Label(f1, text = "Title", background = '#3b5997', foreground ="white", font = ("Times New Roman", 25))
title.place(x=100,y=20,width=200,height=50)
eg1 = tk.Label(f1, text="Text :")
eg1.place(x=10,y=195,width=70,height=25)
eg2 = tk.Label(f1, text="Text")
eg2.place(x=290,y=195,width=70,height=25)
eg3 = tk.Entry(f1, width=20)
eg3.place(x=100,y=195,width=200,height=25)
f1.place(x=100,y=20,width=1000,height=900) # <-------------like this
raise_frame(f1)
root.mainloop()

can't invoke "wm" command: application has been destroyed

import tkinter as tk
from tkinter import *
import pyautogui
root = tk.Tk()
#label = tk.Label(root, text='you coomand hacking', font= ('Times New Roman','80'), fg='black', bg='white')
#label.pack()
root.title("Wallpaper")
wall = PhotoImage(file = "20170227180026_3.gif")
wall_label = Label(image = wall)
root.geometry(f"{wall.width()}x{wall.height()}")
root.overrideredirect(True)
currentMouseX,currentMouseY = pyautogui.position()
print(f'{currentMouseX} {currentMouseY}')
root.geometry("+0+0")
root.wm_attributes("-topmost", True)
root.wm_attributes("-disabled", True)
root.wm_attributes("-transparentcolor", "white")
wall_label.place(x = -2,y = -2)
root.after(1000 , root.destroy)
#root.geometry("+{}+{}".format(currentMouseX,currentMouseY))
root.geometry("+{}+{}".format(currentMouseX,currentMouseY))
root.mainloop()
root.after(1000 , root.destroy)
root.geometry("+{}+{}".format(currentMouseX,currentMouseY))
Please understand even if the source code is dirty.
What I want is for the image to follow the mouse
I tried to follow the mouse by repeating the image disappearing and appearing, but it is not easy.
Here. I made the image follow the mouse, without pyautogui.
Code:
import tkinter as tk
from tkinter import *
#import pyautogui
root = tk.Tk()
#label = tk.Label(root, text='you coomand hacking', font= ('Times New Roman','80'), fg='black', bg='white')
#label.pack()
root.title("Wallpaper")
wall = PhotoImage(file = "20170227180026_3.gif")
c = Canvas(root, height = 1200, width = 1200)
c.pack()
pic = c.create_image(600, 600, image = wall)
def movepic(event):
x,y = event.x, event.y
c.coords(pic, x, y)
c.bind_all("<Motion>", movepic)
root.mainloop()

Tkinter Text widget returns ".!frame3.!frame3.!frame.!text" instead of appropriate values

I'm currently working on a project where you scan bar codes and it implements the result into an excel file. I am using tkinter to make my GUI, however, when I try to get the values from a text widget it returns the value ".!frame3.!frame3.!frame.!text". how can I fix this to get the appropriate values?
here is my code so far
import tkinter as tk
from tkinter import *
root = tk.Tk(className = "Tool Manager")
root.configure(bg='#C4C4C4')
root.title('Main Screen')
root.geometry("800x600")
main = Frame(root, bg='#C4C4C4', width = 800, height = 600)
#This is the contents of the Main Frame (screen 1)
frame_pad1 = Frame(main, bg='#C4C4C4')
frame_1 = Frame(main,bg='#C4C4C4')
frame_2 = Frame(main, bg='#C4C4C4')
frame_3 = Frame(main, bg='#C4C4C4')
min = Frame(root, bg = 'GREEN')
#mout stuffs
mout = Frame(root, bg = '#C4C4C4')
outframe_pad1 = Frame(mout, bg='#C4C4C4')
outframe_1 = Frame(mout, bg='#C4C4C4')
outframe_2 = Frame(mout, bg='#C4C4C4')
outframe_3 = Frame(mout, bg='#C4C4C4')
#code for changing screens
def raise_frame(frame):
frame.tkraise()
for frame in (main, min, mout):
frame.grid(row=1, column=1, sticky='news')
#sets frame weight for 3 rows (centers frames)
rows = 0
while rows < 3:
root.rowconfigure(rows, weight=1)
root.columnconfigure(rows,weight=1)
rows += 1
def commit_to_file():
ID = name.get()
out_list.get('1.0', 'end-1c')
print(out_list) #<----- THIS IS WHERE I'M RETURNING VALUES TO THE TERMINAL
def on_every_keyboard_input(event):
update_char_length(out_list)
#updating Line Length Information
def update_char_length(out_list):
string_in_text = out_list.get('1.0', '1.0 lineend')
string_length = len(string_in_text)
print(string_length)
if (string_length == 4):
out_list.insert(0.0, '\n')
out_list.mark_set("insert", "%d.%d" % (0,0))
#main screen formatting
area = PhotoImage(file="test.png")
areaLabel = Label(frame_1, image=area, bg='#C4C4C4')
areaLabel.pack(side=RIGHT)
mwLabel = Label(frame_2,text="this is only a test", font=("Airel", 20), bg='#C4C4C4')
mwLabel.pack(side=RIGHT)
out_button = Button(frame_3, text="Check Out", command=lambda:raise_frame(mout) , height=5, width=20, font=("Airel", 15))
out_button.pack(side=RIGHT, padx=20, pady = 4)
in_button = Button(frame_3, text="Check In", command=lambda:raise_frame(min), height=5, width=20, font=("Airel", 15))
in_button.pack(side=LEFT, padx=20, pady = 4)
#out screen formatting
name = Entry(outframe_1, font=("Airel", 15))
name.pack(side=RIGHT)
name_lbl = Label(outframe_1, text="ID Number", bg='#C4C4C4', font=("Airel", 15))
name_lbl.pack(side=LEFT)
outlist = Frame(outframe_2, bd=1, relief=SUNKEN)
outlist.pack(side=LEFT)
out_list = Text(outlist, height=30, width=40)
out_list.pack(side=RIGHT)
done_btn = Button(outframe_3, text="Done", command=commit_to_file, font=("Ariel", 15))
done_btn.pack(side=RIGHT, padx=20, pady=4)
#init to main screen
raise_frame(main)
#drawing objects for main screen
frame_pad1.pack(padx=1, pady=25)
frame_1.pack(padx=1,pady=1)
frame_2.pack(padx=10,pady=1)
frame_3.pack(padx=1, pady=80)
#drawing out screen
outframe_1.pack(padx=1, pady=1)
outframe_2.pack(padx=1,pady=1)
outframe_3.pack(padx=1, pady=1)
#calls line info update out screen
out_list.bind('<KeyRelease>', on_every_keyboard_input)
root.mainloop()
You are printing the command and not the value of it. Put the command in a variable and then print the variable.
Example: myVar = out_list.get("1.0", "end-1c") and then print(myVar)

Mixing two layout managers inside the same window in Python (Tkinter)

I am pretty new to Python and Tkinter, so I hope this question will be easy for the seniors...
I have this checkerboard:
I am using a grid layout management, as can be noticed below:
from tkinter import *
def checkerboard(can):
w = can.winfo_width()
h = can.winfo_height()
cellwidth = w / 4
cellheight = h / 4
for row in range(4):
for col in range(4):
x1=col * cellwidth
y1=row * cellheight
x2=(col + 1) * cellwidth
y2=(row + 1) * cellheight
can.create_rectangle(col * cellwidth, row * cellheight, (col + 1) * cellwidth, (row + 1) * cellheight,
fill='white')
can.create_text(((x1+x2)/2,(y1+y2)/2),text='A')
window = Tk()
thecanvas = Canvas(window, width=500, height=500)
thecanvas.grid(row=0, column=0)
window.update_idletasks()
checkerboard(thecanvas)
window.mainloop()
The problem is that I want to add a previous line over the checkerboard, which does not belong to the grid layout. Something like this:
How can I achieve it?
Thanks in advance
You don't use grid to create checkoard, you use grid only to put canvas in window.
Canvas is in row=0 so you can put it in row=2 and then you can put Labels in row=0 and row=1
l1 = Label(window, text="I WANT TO CREATE THIS LABEL")
l1.grid(row=0, column=0)
l2 = Label(window, text="AND THIS TOO", fg='red')
l2.grid(row=1, column=0)
thecanvas = Canvas(window, width=500, height=500)
thecanvas.grid(row=2, column=0)
Full code
from tkinter import *
def checkerboard(can):
w = can.winfo_width()
h = can.winfo_height()
cellwidth = w / 4
cellheight = h / 4
for row in range(4):
for col in range(4):
x1=col * cellwidth
y1=row * cellheight
x2=(col + 1) * cellwidth
y2=(row + 1) * cellheight
can.create_rectangle(col * cellwidth, row * cellheight, (col + 1) * cellwidth, (row + 1) * cellheight,
fill='white')
can.create_text(((x1+x2)/2,(y1+y2)/2),text='A')
window = Tk()
l1 = Label(window, text="I WANT TO CREATE THIS LABEL")
l1.grid(row=0, column=0)
l2 = Label(window, text="AND THIS TOO", fg='red')
l2.grid(row=1, column=0)
thecanvas = Canvas(window, width=500, height=500)
thecanvas.grid(row=2, column=0)
window.update_idletasks()
checkerboard(thecanvas)
window.mainloop()
Instead of grid() you can even use pack() and you get the same result
l1 = Label(window, text="I WANT TO CREATE THIS LABEL")
l1.pack()
l2 = Label(window, text="AND THIS TOO", fg='red')
l2.pack()
thecanvas = Canvas(window, width=500, height=500)
thecanvas.pack()
If you really need to mix managers then you can also put Frame in row=0 and Canvas in row=1 and then you can use pack() inside Frame
frame = Frame(window)
frame.grid(row=0, column=0)
l1 = Label(frame, text="I WANT TO CREATE THIS LABEL")
l1.pack()
l2 = Label(frame, text="AND THIS TOO", fg='red')
l2.pack()
thecanvas = Canvas(window, width=500, height=500)
thecanvas.grid(row=1, column=0)
The best solution is to create a frame for the checkerboard, and then you can create the widgets in that frame. In the main window, you can use any geometry manager you want to add the checkerboard and any other widgets.
Though, in this specific case you can just move the canvas to row one and add anything else in row 0.

canvas command not working inside function

Help! I am using python 3.5.2 and the function self.new_game is not working. It is supposed to put text on the canvas but it does nothing! There are also no errors that appear in the shell.
from tkinter import *
import time
import os
WIDTH = 1920
HEIGHT = 1080
root = Tk()
root.state('zoomed')
planet_selected = 0
planet_name = "nothing"
planet_temp = -270
planet_size = 0.0
planet_life = 0.0
class Space(Frame):
def __init__(self):
Frame.__init__(self)
frame1 = Frame(self)
self.canvas = Canvas(frame1, width = WIDTH, height = HEIGHT, bg ="white")
self.canvas.focus_set()
self.canvas.create_text(1920,1000,text='Planetary Creator',font=('Arial',15))
self.master.title("Planetary Creator Alpha 0.1")
frame = Frame(root, bg='grey', width=1920, height=40)
frame.pack(fill='x')
button1 = Button(frame, text='New Game',command=lambda : self.new_game())
button1.pack(side='left', padx=10)
button2 = Button(frame, text='Quit Game',command=lambda : os._exit(0))
button2.pack(side='left')
#this function below does not work!!!
def new_game(self):
self.canvas.delete(ALL)
size = self.canvas.create_text(960,540,text=str(planet_size) + "moon",font=("Arial",10))
life = self.canvas.create_text(960,520,text="✣" + str(planet_life) + "%",font=("Arial",10))
temp = self.canvas.create_text(960,500,text=str(planet_temp) + "°C",font=("Arial",10))
name = self.canvas.create_text(960,480,text=planet_name,font=("Arial",15))
Space().mainloop()
I removed frame1 and put Canvas in root , and use canvas.pack() to see canvas in window.
(but I could use self instead of root and use self.pack() because Space inherits from Frame. it would ne more logical)
After that I had to only change text positions because windows was too big for my screen.
I used variables CENTER_X, CENTER_Y to put text in center regardless of the size of the screen.
from tkinter import *
import time
import os
class Space(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.master.title("Planetary Creator Alpha 0.1")
self.canvas = Canvas(root, width=WIDTH, height=HEIGHT, bg="white")
self.canvas.pack()
self.canvas.focus_set()
self.canvas.create_text(CENTER_X, CENTER_Y, text='Planetary Creator', font=('Arial',15))
frame = Frame(root, bg='grey', width=WIDTH, height=40)
frame.pack(fill='x')
button1 = Button(frame, text='New Game', command=self.new_game)
button1.pack(side='left', padx=10)
button2 = Button(frame, text='Quit Game', command=root.destroy)
button2.pack(side='left')
def new_game(self):
self.canvas.delete(ALL)
size = self.canvas.create_text(CENTER_X, CENTER_Y, text=str(planet_size) + "moon", font=("Arial",10))
life = self.canvas.create_text(CENTER_X, CENTER_Y-20, text="✣" + str(planet_life) + "%", font=("Arial",10))
temp = self.canvas.create_text(CENTER_X, CENTER_Y-40, text=str(planet_temp) + "°C", font=("Arial",10))
name = self.canvas.create_text(CENTER_X, CENTER_Y-60, text=planet_name, font=("Arial",15))
# --- main ---
WIDTH = 800 #1920
HEIGHT = 500 #1080
CENTER_X = WIDTH//2
CENTER_Y = HEIGHT//2
planet_selected = 0
planet_name = "nothing"
planet_temp = -270
planet_size = 0.0
planet_life = 0.0
root = Tk()
#root.state('zoomed')
Space(root)
root.mainloop()

Categories

Resources