I have been trying to get .place_forget() to work in my test application but I am having some difficulty.
I am trying to get the widgets in "def select_1:" to show when R1 "Yes" checkbox is checked and then have the widgets not show when the check is removed.
The widgets show when I check the box but will not forget(hide) when it is then unchecked.
Any assistance would be greatly appreciated.
import os, sys
import pywintypes
from tkinter import *
#================================= MAIN WINDOW =================================
root = Tk()
w = 750
h = 325
ws = root.winfo_screenwidth()
hs = root.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
root.geometry('%dx%d+%d+%d' % (w, h, x, y))
root.title('Test Application')
root.geometry('750x325')
root.config(bg='#000000')
pass_entry=StringVar()
pass_1=StringVar()
var1 = IntVar()
var2 = IntVar()
selection = StringVar()
#=================================== HEADER ====================================
header = Label(root, font = ('Times New Roman','25','bold'), text='Test Application',
bg = ('#000000'), fg = ('#B3CDE0'))
header.place(x=250,y=15)
#================================ RESULT WINDOW ================================
result_window = Text(root, width = 80, height = 10)
result_window.place(x=50, y=75)
#=========================== CHECK BUTTON SELECTION ============================
def select_1():
if var1.get()==1:
pass_entry = Entry(root, width = 20, textvariable = pass_1, bg='#000000', fg='#B3CDE0')
pass_entry.place(x=250,y=275)
pass_entry.focus_set()
selection = Label(root, text='Enter OS Password:', bg='#000000', fg='#B3CDE0')
selection.place(x=140,y=275)
elif var1.get()==0:
pass_entry.place_forget()
selection.place_forget()
else:
return
#========================= ACCESS CREDENTIAL MANAGER ===========================
def getpass():
if var1.get()==1:
os.system('explorer.exe')
else:
return
def close():
root.destroy()
#=============================== RADIO BUTTONS =================================
R1 = Checkbutton(root, text="Yes", variable = var1, onvalue = 1, offvalue = 0, height=1, width = 15, activebackground = '#000000', bg='#000000', fg='#B3CDE0', command=select_1)
R1.place(x=350,y=250)
R2 = Checkbutton(root, text="No ", variable = var2, onvalue = 1, offvalue = 0, height=1, width = 15, bg='#000000', fg='#B3CDE0', activebackground = '#000000')
R2.place(x=350,y=275)
#=========================== RADIO BUTTON SELECTION ============================
cancel_button = Button(root, text='Cancel', width = 12, bg=('#000000'), fg = ('#B3CDE0'), activebackground = '#000000', command = close)
cancel_button.place(x=590,y=270)
recover_button = Button(root, text='Open', width = 12, bg=('#000000'), fg = ('#B3CDE0'), activebackground = '#000000',command = getpass)
recover_button.place(x=480,y=270)
root.mainloop()
When you want to make a widget disappear and then appear again, you don't actually have to define it and all it's options again.
#=========================== CHECK BUTTON SELECTION ============================
pass_entry = Entry(root, width = 20, textvariable = pass_1, bg='#000000', fg='#B3CDE0')
selection = Label(root, text='Enter OS Password:', bg='#000000', fg='#B3CDE0')
def select_1():
if var1.get()==1:
pass_entry.place(x=250,y=275)
pass_entry.focus_set()
selection.place(x=140,y=275)
elif var1.get()==0:
pass_entry.place_forget()
selection.place_forget()
else:
return
Notice how pass_entry and selection are defined outside of the function and only placed inside the function.
What's a bit confusing though is why you're using two separate buttons for "yes" and "no" if checking them doesn't automatically uncheck the other one (i assume that's the purpose of the two buttons).
If that's what you want to do, you should use the Radiobutton widget instead. Notice how both of them affect the same variable and each of them have one value.
#=============================== RADIO BUTTONS =================================
R1 = Radiobutton(root, text="Yes", variable = var1, value = 1, height=1, width = 15, activebackground = '#000000', bg='#000000', fg='#B3CDE0', command=select_1)
R1.place(x=350,y=250)
R2 = Radiobutton(root, text="No", variable = var1, value = 0, height=1, width = 15, activebackground = '#000000', bg='#000000', fg='#B3CDE0', command=select_1)
R2.place(x=350,y=275)
I also tidied up the other options a bit too, you had some random spacing in there.
Related
I'm studying GUI, so please understand my poor codes below.
I was trying to make a program which gets game-character's information. So if you press the 'search' button, the list would be shown below. But... it only shows about 11 names due to the window size. So i wanted to put a scrollbar for that area, but I just don't know how to link the scroll bar to control the area. I meant, the scroll bar itself has created, and it does scroll itself, but it doesn't scroll the window I wanted. I must have linked it wrong but... not sure.
Below is the minimized example code, but it's still quite long and crude. Sorry for that again.
If anyone can enlighten me, it would be really great help for this and my future works as well.
import tkinter as tk
import requests
from bs4 import BeautifulSoup
import webbrowser
import time
global var_dict, input_id, output
var_dict = {}
def enter_call_back(event=None):
output.grid(column = 0, row = 2, columnspan = 5 , sticky='w')
output.insert(tk.END,"Text_Something")
output.update()
search_chr()
def open_browse(url_list):
for url in url_list:
time.sleep(0.3)
webbrowser.open(url)
def search_inven(ch_id):
if ch_id == "ch1" or ch_id == "ch13" or ch_id == "ch15" :
num = 5
url_list = ["something.url","something2.url"]
self_count = 1
else:
num = 0
url_list = []
self_count = 0
masterset = []
masterset.append(num)
masterset.append(url_list)
masterset.append(self_count)
return masterset
def search_chr():
global var_dict, output
for things in var_dict.keys():
var_dict[things].destroy()
chr_list = ["ch1","ch2","ch3","ch4","ch5","ch6","ch7","ch8","ch9","ch9","ch10","ch11","ch12","ch13","ch14","ch15"]
output.insert(tk.END," Done! \n\n")
var_dict = {}
num = -1
for ch in chr_list:
num += 1
var_dict["output%s" %num] = tk.Entry(frame_buttons, width = 125)
result = search_inven(ch)
if result[0] == 0:
var_dict["output"+str(num)].insert(0, "Clean "+ch+"\n")
var_dict["output"+str(num)].grid(column = 0, row = num, sticky='w', padx=5, pady=5)
else:
url_list = result[1]
var_dict["o-button%s" %num] = tk.Button(frame_buttons, command=lambda url_list = url_list : open_browse(url_list))
var_dict["o-button"+str(num)].grid(column = 1, row = num, sticky='e')
var_dict["o-button"+str(num)].config(text="URL")
var_dict["output"+str(num)].insert(0, "Not Clean "+str(result[0])+" Self : "+str(result[2])+" Ch_id : "+ch+")\n")
var_dict["output"+str(num)].grid(column = 0, row = num, sticky='w', padx=5, pady=5)
vsb = tk.Scrollbar(frame_canvas, orient="vertical")
vsb.grid(row=0, column=1, sticky='ns')
vsb.config(command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set)
frame_canvas.config(height = 300)
canvas.config(scrollregion=canvas.bbox("all"))
root = tk.Tk()
root.geometry("760x710")
root.resizable(width=False, height=False)
root.title("Minimum v.1.2")
root.grid_rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
frame_main = tk.Frame(root, bg="gray")
frame_main.grid(sticky='news')
intro = tk.Text(frame_main, height = 17, bg="#E3D5F3")
intro.option_add("*Font", "명조 10")
intro.insert(tk.CURRENT,"Text_something")
intro.config(state='disabled')
intro.grid(row=0, column=0, pady=(5, 0), columnspan = 5, sticky='nw')
input_id = tk.Entry(frame_main, width = 35)
input_id.option_add("*Font","명조 10")
input_id.insert(0,"Ch_name")
input_id.grid(row=1, column=0, pady=(5, 0), sticky='w')
search_btn = tk.Button(frame_main)
search_btn.config(text="Search")
search_btn.option_add("*Font","명조 10")
search_btn.config(width=5,height=1)
search_btn.grid(row = 1, column = 0, pady=(5, 0), sticky='e')
output = tk.Text(frame_main, height = 10)
output.option_add("*Font","명조 10")
output.grid(row = 2, column = 0,pady=(5,0),sticky='nw')
frame_canvas = tk.Frame(frame_main, width = 565)
frame_canvas.grid(row=3, column=0, pady=(5, 0), columnspan = 3 ,sticky='nw')
frame_canvas.grid_rowconfigure(0, weight=1)
frame_canvas.grid_columnconfigure(0, weight=1)
frame_canvas.grid_propagate(False)
canvas = tk.Canvas(frame_canvas, bg="gray", height=500,scrollregion=(0,0,500,1800))
canvas.grid(row=0, column=0, sticky="news")
frame_buttons = tk.Frame(canvas, bg="gray")
frame_buttons.grid(row = 0, column = 0,sticky='e')
root.bind('<Return>',enter_call_back)
search_btn.config(command = enter_call_back)
root.mainloop()
First, using grid() to put frame_buttons into the canvas will not affect the scrollregion of the canvas. Use canvas.create_window() instead.
Second, it is better to bind <Configure> event on frame_buttons and update canvas' scrollregion inside the bind callback. Then adding widgets to frame_buttons will automatically update the scrollregion.
Also note that you have created new scrollbar and put it at same position whenever search_chr() is executed. Better create the scrollbar only once outside the function.
I'm trying to bind arrow keys to buttons or at least the functions of the buttons (button_forward and button_back). The function of the buttons works, however, when I bind a key to the button the image just disappears.
It would also be awesome if someone could help me figure out how to create a loop to define the images and put them into a list. I'm just so lost when it comes to that.
The main purpose of the code is to be an image viewer that flashes an LED strip when an image changes.
I want to be able to control it using arrow keys to move forward and back between the images.
from tkinter import Tk, Button,Label, DISABLED
from PIL import ImageTk,Image
import board
import time
import neopixel
pixels = neopixel.NeoPixel(board.D18, 30)
root= Tk()
root.configure(bg='black')
root.title("please work")
# define, load, show
my_img1 = ImageTk.PhotoImage(Image.open("1.bmp"))
my_img2 = ImageTk.PhotoImage(Image.open("2.bmp"))
my_img3 = ImageTk.PhotoImage(Image.open("3.bmp"))
my_img4 = ImageTk.PhotoImage(Image.open("4.bmp"))
my_img5 = ImageTk.PhotoImage(Image.open("5.bmp"))
my_img6 = ImageTk.PhotoImage(Image.open("6.bmp"))
my_img7 = ImageTk.PhotoImage(Image.open("7.bmp"))
my_img8 = ImageTk.PhotoImage(Image.open("8.bmp"))
image_list = [my_img1, my_img2, my_img3, my_img4, my_img5, my_img6, my_img7, my_img8]
my_label = Label(image=my_img1)
my_label.grid(row = 0, column = 0, columnspan= 3, rowspan = 25, padx=440, pady= 5)
def forward(image_number, event = None):
global my_label
global button_forward
global button_back
my_label.grid_forget()
my_label = Label(image = image_list[image_number-1])
button_forward = Button(root, text = "next", command=lambda: forward(image_number+1))
button_back = Button(root, text = "previous", command = lambda: back(image_number-1))
if image_number == 7:
button_forward = Button(root, text = "next", state = DISABLED)
my_label.grid(row = 0, column = 0, columnspan = 3, rowspan = 25, padx=440, pady= 5)
button_back.grid(row = 23, column = 0)
button_forward.grid(row = 23, column = 2)
pixels.fill((255,0,0))
time.sleep(0.1)
pixels.fill((0,0,0))
time.sleep(0.5)
def back(image_number,):
global my_label
global button_forward
global button_back
my_label.grid_forget()
my_label = Label(image = image_list[image_number-1])
button_forward = Button(root, text = "next", command=lambda: forward(image_number+1))
button_back = Button(root, text = "previous", command = lambda: back(image_number-1))
my_label.grid(row = 0, column = 0, columnspan = 3, rowspan = 25, padx=440, pady= 5)
if image_number == 1:
button_back = Button(root, text = "previous", state = DISABLED)
button_back.grid(row=23, column = 0 )
button_exit.grid(row=23, column = 1 )
button_forward.grid(row=23, column = 2)
pixels.fill((255,0,0))
time.sleep(0.1)
pixels.fill((0,0,0))
time.sleep(0.5)
button_back = Button(root, text = "previous", command = back)
button_exit = Button(root, text = "Exit", command = root.quit)
button_forward = Button(root, text = "next", command =lambda:forward(2))
root.bind('<Left>', back)
root.bind('<Right>', forward)
button_back.grid(row=23, column = 0 )
button_exit.grid(row=23, column = 1 )
button_forward.grid(row=23, column = 2)
root.mainloop()
Your bindings cannot work because the event corresponding to the keypress will be passed instead of the image_number argument in back() and forward().
Also, you are recreating the widgets every time while you should only reconfigure them. So to change the label's image, you can do: my_label.configure(image=<new image>). Also instead of passing image_number as an argument, I would rather use a global variable, so that it will be easier to use the functions in the key bindings:
from tkinter import Tk, Button, Label, DISABLED, NORMAL
from PIL import ImageTk, Image
import board
import time
import neopixel
pixels = neopixel.NeoPixel(board.D18, 30)
root = Tk()
root.configure(bg='black')
root.title("please work")
# define, load, show
my_img1 = ImageTk.PhotoImage(Image.open("1.bmp"))
my_img2 = ImageTk.PhotoImage(Image.open("2.bmp"))
my_img3 = ImageTk.PhotoImage(Image.open("3.bmp"))
my_img4 = ImageTk.PhotoImage(Image.open("4.bmp"))
my_img5 = ImageTk.PhotoImage(Image.open("5.bmp"))
my_img6 = ImageTk.PhotoImage(Image.open("6.bmp"))
my_img7 = ImageTk.PhotoImage(Image.open("7.bmp"))
my_img8 = ImageTk.PhotoImage(Image.open("8.bmp"))
image_list = [my_img1, my_img2, my_img3, my_img4, my_img5, my_img6, my_img7, my_img8]
image_number = 1
# create the label only once
my_label = Label(root, image=image_list[image_number - 1])
my_label.grid(row=0, column=0, columnspan= 3, rowspan=25, padx=440, pady= 5)
def forward(event=None):
global image_number # global variable to keep track of the displayed image
image_number += 1
# change image in label
my_label.configure(image=image_list[image_number - 1])
if image_number == 8:
# last image, disable forward button
button_forward.configure(state=DISABLED)
elif image_number == 2:
# no longer first image, re-enable back button
button_back.configure(state=NORMAL)
pixels.fill((255,0,0))
time.sleep(0.1)
pixels.fill((0,0,0))
time.sleep(0.5)
def back(event=None):
global image_number
image_number -= 1
my_label.configure(image=image_list[image_number - 1])
if image_number == 1:
# first image, disable back button
button_back.configure(state=DISABLED)
elif image_number == 7:
# no longer last image, re-enable forward button
button_forward.configure(state=NORMAL)
pixels.fill((255,0,0))
time.sleep(0.1)
pixels.fill((0,0,0))
time.sleep(0.5)
button_back = Button(root, text="previous", command=back, state=DISABLED)
button_exit = Button(root, text="Exit", command=root.quit)
button_forward = Button(root, text="next", command=forward)
root.bind('<Left>', back)
root.bind('<Right>', forward)
button_back.grid(row=23, column=0)
button_exit.grid(row=23, column=1)
button_forward.grid(row=23, column=2)
root.mainloop()
Iam new to Tkinter and am trying do an interface a small randomising application. i have several windows and i need to open one at a time, however the problem is when a user enters wrong crentials and they have to go back to the login page which was destroyed previous. When i run my code so far, i get the error below:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\SANDRA\AppData\Local\Programs\Python\Python37\lib\tkinter__init__.py", line 1705, in call
return self.func(*args)
File "C:\Users\SANDRA\Desktop\python work\GUI\stem page 1.py", line 31, in validation
open_login()
File "C:\Users\SANDRA\Desktop\python work\GUI\stem page 1.py", line 35, in open_login
root.destroy()
File "C:\Users\SANDRA\AppData\Local\Programs\Python\Python37\lib\tkinter__init__.py", line 2062, in destroy
self.tk.call('destroy', self._w)
_tkinter.TclError: can't invoke "destroy" command: application has been destroyed
below is my code so far:
from tkinter import *
#creating the admin's logged in page
def admin_logged_in():
#global adn_logged_in
adn_logged_in = Tk()
adn_logged_in.title("Administrative page")
adn_logged_in.config(bg = "#ffe6ff")
adn_logged_in.geometry("700x400")
adn_logged_in.resizable(width=FALSE, height=FALSE)
adn_lbl = Label(adn_logged_in, text ="please select what you wish to do.", font = "Arial 16",fg = "black", bg = "#ffe6ff", pady = 50)
adn_lbl.pack()
list = Listbox(adn_logged_in,selectmode = SINGLE, height = 2,bg = "#ffe6ff", width = 30, font = "Arial 16" ,fg = "blue")
list.insert(1, "Add students")
list.insert(2, "Delete students")
list.pack()
adn_logged_in.mainloop()
#creating a function to validate the username and password
def validation():
username_text = username.get()
password_text = password.get()
if username_text == "admin" and password_text == "123":
admin.destroy()
admin_logged_in()
else:
open_login()
#creating a function to open the administrator window
def open_login():
root.destroy()
global password
global username
global admin
admin = Tk()#creates a new window
admin.title("Administrative login page")
admin.config(bg = "#ffe6ff")
admin.geometry("700x400")
admin.resizable(width=FALSE, height=FALSE)
label1 = Label(admin,text = " please login", font = "Arial 40",fg = "blue", bg = "#ffe6ff", pady = 40)
label1.pack()
open_frame = Frame(admin, bg = "#ffe6ff")
open_frame.pack()
#crating label and entry for user name .
name_lbl = Label(open_frame, text = "Username: ",font = "Arial 16", fg = "black",bg = "#ffe6ff",)
name_lbl.grid(row = 0, column = 0, sticky = "e")
username = StringVar()
name_entry = Entry(open_frame, textvariable = username, width = 50)
name_entry.grid(row = 0, column = 1, sticky = "w", pady =8)
#creating label and entry for password
pw_lbl = Label(open_frame, text = "Password: ",font = "Arial 16", fg = "black", bg = "#ffe6ff",)
pw_lbl.grid(row = 1, column = 0, sticky = "e")
password = StringVar()
pw_entry = Entry(open_frame, textvariable = password,width = 50, show = "*")
pw_entry.grid(row = 1, column = 1, sticky = "w",pady = 8)
#creating a submit button
sub_btn = Button(open_frame, text = "Submit",font = "Arial 16", fg = "black", bg = "#ffe6ff", width = 20,command= validation)
sub_btn.grid(row = 3, column = 1, sticky = "s")
admin.mainloop()
#creating the main window
root = Tk()
root.title("Student Randomiser v 1.0")
root.config(bg = "#ffe6ff")
root.geometry("700x400")
root.resizable(width=FALSE, height=FALSE)
#creating the frame1 for the first window
frame1 = Frame(relief = FLAT, borderwidth = 3, bg ="#ffe6ff")
frame1.pack()
#creating the heading
main_lbl = Label(frame1, text = "STUDENT RANDOMISER",bg = "#ffe6ff",fg = "blue", font = "Helvetica 40 bold")
main_lbl.pack(side = TOP, pady= 40)
#creating the welcome note
welcome_lbl = Label(frame1,font = "Arial 18", text = "Welcome to our student randomising sytem ",bg = "#ffe6ff",fg = "black")
welcome_lbl.pack()
#creatinf empty frame for spacing
empty_frame = Frame(height = 40)
empty_frame.pack()
#creating a frame for the buttons
frame2 = Frame(relief = FLAT,borderwidth = 3, bg ="#ffe6ff")
frame2.pack()
#creating a adminstrator button
adm_button = Button(frame2, font = "Arial 16",text = "Adminstrator", fg = "black", width = 20, command =open_login)
adm_button.pack(side = LEFT, padx = 15, pady = 5)
#creating user button
user_button = Button(frame2, font = "Arial 16", text = "User", fg = "black", width = 20)
user_button.pack(side = RIGHT, padx = 15, pady = 5)
root.mainloop()
I have come across an issue with using the tkinter message box, when a user of my application presses the English flag and then goes to Log-out in the top right hand corner a message box appears but also another box appears with the window title 'tk', I have not made or called any such window so my theory is that the window is coming from some place with the message box or maybe its something I have mistakenly done in my code which I cant see.
here is my code below;
import tkinter
from tkinter import *
from tkinter import messagebox as box
Title_Text = 25
Title_Font = "Courier"
Font = 'Ariel'
Rest_Text = 16
Background_Colour = 'Light blue'
def EngFlag():
print('Hello world')
def LogOut1():
response = box.askquestion ('?', 'Are You Sure?')
if response == 'yes':
try:
window.destroy()
except:
Eng_window.destroy()
def back1():
Home_Screen()
def Home_Screen():
global window
window = Tk()
window.geometry('1366x768')
window.configure(background = Background_Colour)
window.title('Local Languages Learning System')
window.resizable(width=False, height=False)
try:
Eng_window.destroy()
except:
pass
Title1 = Label(window, text = 'Local Languages Home Screen', bg = Background_Colour)
Title1.config(font=("Courier", Title_Text))
Title1.pack()
Title1.place(y = 1, x = 450)
Question_Label = Label(window, text = 'Please Pick The Language You Wish To Learn', bg = Background_Colour)
Question_Label.config(font=(Font, Rest_Text))
Question_Label.pack()
Question_Label.place(y = 200, x = 495)
Log_Out = Button(window, text = 'Log-Out', height = 1, width = 8, command = LogOut1)
Log_Out.pack()
Log_Out.place(y = 5, x = 1290)
help_btn = Button(window, text = 'Help', height = 1, width = 8, command = None)
help_btn.pack()
help_btn.place(y = 45, x = 1290)
English_Flag = PhotoImage(file = 'EnglishFlag.gif')
English_Flag_btn = Button(window, image = English_Flag, command = English_Home_Screen)
English_Flag_btn.pack(side = LEFT, padx = 10)
English_Flag_btn.place(y = 350, x = 300)
Polish_Flag = PhotoImage(file = 'PolishFlag.gif')
Polish_Flag_btn = Button(window, image = Polish_Flag, command = EngFlag)
Polish_Flag_btn.pack(side = LEFT, padx = 10)
Polish_Flag_btn.place(y = 350, x = 600)
Italian_Flag = PhotoImage(file = 'ItalianFlag.gif')
Italian_Flag_btn = Button(window, image = Italian_Flag, command = None)
Italian_Flag_btn.pack(side = LEFT, padx = 10)
Italian_Flag_btn.place(y = 350, x = 900)
window.mainloop()
def English_Home_Screen():
global Eng_window
Eng_window = Tk()
Eng_window.geometry('1366x768')
Eng_window.configure(background = Background_Colour)
Eng_window.title('Local Languages Learning System')
Eng_window.resizable(width=False, height=False)
window.destroy()
Title1 = Label(Eng_window, text = 'Local Languages\nEnglish Home Screen', bg = Background_Colour)
Title1.config(font=("Courier", Title_Text))
Title1.pack()
Title1.place(y = 1, x = 450)
Log_Out = Button(Eng_window, text = 'Log-Out', height = 1, width = 8, command = LogOut1)
Log_Out.pack()
Log_Out.place(y = 5, x = 1290)
Back = Button(Eng_window, text = 'Back', height = 1, width = 8, command = back1)
Back.pack()
Back.place(y = 5, x = 1210)
help_btn = Button(Eng_window, text = 'Help', height = 1, width = 8, command = None)
help_btn.pack()
help_btn.place(y = 45, x = 1290)
Play_all = Button(Eng_window, text = 'Play All Games', height = 2, width = 20, command = None)
Play_all.pack()
Play_all.place(y = 100, x = 320)
Multiple_Choice = Button(Eng_window, text = 'Play Multiple Choice Game', height = 2, width = 20, command = None)
Multiple_Choice.pack()
Multiple_Choice.place(y = 100, x = 510)
Picture = Button(Eng_window, text = 'Play Picture Game', height = 2, width = 20, command = None)
Picture.pack()
Picture.place(y = 100, x = 700)
Memory = Button(Eng_window, text = 'Play Memory Game', height = 2, width = 20, command = None)
Memory.pack()
Memory.place(y = 100, x = 890)
LeaderBoard = Button(Eng_window, text = 'LeaderBoard', height = 2, width = 20, command = None)
LeaderBoard.pack()
LeaderBoard.place(y = 160, x = 600)
Home_Screen()
Apologies for it being so long but to actually see the problem you have to have all the code. Any help or fixies would be great.
Now there are several issues with your code and some I will address.
First off what you are trying to do is very complicated when using a Non-OOP method. I have re-written your code as OOP to provide some ease of use and readability.
For the most part you should avoid using global the easiest way to do this is to use class attributes instead. This allows for you to have a variable that can be seen by any method within the class.
Some helpful tips:
Do not import tkinter twice.
Instead of doing:
import tkinter
from tkinter import *
from tkinter import messagebox as box
Do this instead:
import tkinter as tk
from tkinter import messagebox
Your Try/Except function will not work as you expect as Eng_window.destroy() will not return an error regardless of if the window is there or not. So it will always attempt to destroy Eng_window and never window
Instead do this:
# This will check if the instance of Eng_self_window exist first.
if tk.Toplevel.winfo_exists(self.Eng_self_window):
self.Eng_self_window.destroy()
else:
self.window.destroy()
Let me know if you have any questions on the class set up.
It can be done using global's but its not as clean and harder to deal with.
Here I have moved your code into a class and rearranged some stuff.
import tkinter as tk
from tkinter import messagebox
class Home_Screen(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.Title_Text = 25
self.Title_Font = "Courier"
self.Font = 'Ariel'
self.Rest_Text = 16
self.Background_Colour = 'Light blue'
self.window = parent
self.window.geometry('1366x768')
self.window.configure(background = self.Background_Colour)
self.window.title('Local Languages Learning System')
#self.window.resizable(width=False, height=False)
Title1 = tk.Label(self.window, text = 'Local Languages Home Screen', bg = self.Background_Colour)
Title1.config(font=("Courier", self.Title_Text))
Title1.pack()
Title1.place(y = 1, x = 450)
Question_Label = tk.Label(self.window, text = 'Please Pick The Language You Wish To Learn', bg = self.Background_Colour)
Question_Label.config(font=(self.Font, self.Rest_Text))
Question_Label.pack()
Question_Label.place(y = 200, x = 495)
Log_Out = tk.Button(self.window, text = 'Log-Out', height = 1, width = 8, command = self.LogOut1)
Log_Out.pack()
Log_Out.place(y = 5, x = 1290)
help_btn = tk.Button(self.window, text = 'Help', height = 1, width = 8, command = None)
help_btn.pack()
help_btn.place(y = 45, x = 1290)
self.English_Flag = tk.PhotoImage(file = 'EnglishFlag.gif')
self.English_Flag_btn = tk.Button(self.window, image = self.English_Flag, command = self.English_Home_Screen)
self.English_Flag_btn.pack(side = tk.LEFT, padx = 10)
self.English_Flag_btn.place(y = 350, x = 300)
self.Polish_Flag = tk.PhotoImage(file = 'PolishFlag.gif')
self.Polish_Flag_btn = tk.Button(self.window, image = self.Polish_Flag, command = self.EngFlag)
self.Polish_Flag_btn.pack(side = tk.LEFT, padx = 10)
self.Polish_Flag_btn.place(y = 350, x = 600)
self.Italian_Flag = tk.PhotoImage(file = 'ItalianFlag.gif')
self.Italian_Flag_btn = tk.Button(self.window, image = self.Italian_Flag, command = None)
self.Italian_Flag_btn.pack(side = tk.LEFT, padx = 10)
self.Italian_Flag_btn.place(y = 350, x = 900)
def English_Home_Screen(self):
self.Eng_self_window = tk.Toplevel(self.window)
self.Eng_self_window.geometry('1366x768')
self.Eng_self_window.configure(background = self.Background_Colour)
self.Eng_self_window.title('Local Languages Learning System')
#Eng_self.window.resizable(width=False, height=False)
Title1 = tk.Label(self.Eng_self_window, text = 'Local Languages\nEnglish Home Screen', bg = self.Background_Colour)
Title1.config(font=("Courier", self.Title_Text))
Title1.pack()
Title1.place(y = 1, x = 450)
Log_Out = tk.Button(self.Eng_self_window, text = 'Log-Out', height = 1, width = 8, command = self.LogOut1)
Log_Out.pack()
Log_Out.place(y = 5, x = 1290)
Back = tk.Button(self.Eng_self_window, text = 'Back', height = 1, width = 8, command = self.back1)
Back.pack()
Back.place(y = 5, x = 1210)
help_btn = tk.Button(self.Eng_self_window, text = 'Help', height = 1, width = 8, command = None)
help_btn.pack()
help_btn.place(y = 45, x = 1290)
Play_all = tk.Button(self.Eng_self_window, text = 'Play All Games', height = 2, width = 20, command = None)
Play_all.pack()
Play_all.place(y = 100, x = 320)
Multiple_Choice = tk.Button(self.Eng_self_window, text = 'Play Multiple Choice Game', height = 2, width = 20, command = None)
Multiple_Choice.pack()
Multiple_Choice.place(y = 100, x = 510)
Picture = tk.Button(self.Eng_self_window, text = 'Play Picture Game', height = 2, width = 20, command = None)
Picture.pack()
Picture.place(y = 100, x = 700)
Memory = tk.Button(self.Eng_self_window, text = 'Play Memory Game', height = 2, width = 20, command = None)
Memory.pack()
Memory.place(y = 100, x = 890)
LeaderBoard = tk.Button(self.Eng_self_window, text = 'LeaderBoard', height = 2, width = 20, command = None)
LeaderBoard.pack()
LeaderBoard.place(y = 160, x = 600)
def EngFlag(self):
print('Hello world')
def LogOut1(self):
response = messagebox.askquestion ('?', 'Are You Sure?')
if response == 'yes':
if tk.Toplevel.winfo_exists(self.Eng_self_window):
self.Eng_self_window.destroy()
else:
self.window.destroy()
def back1(self):
print("Go back")
self.Eng_self_window.destroy()
root = tk.Tk()
Home_Screen(root)
root.mainloop()
Quick fix; Don't use multiple instances of Tk. Instead, use Toplevel and hide & show the root window. Add:
...
Background_Colour = 'Light blue'
root = Tk()
root.withdraw()
...
and replace:
...
if response == 'yes':
try:
window.destroy()
except:
Eng_window.destroy()
...
global window
window = Tk()
...
global Eng_window
Eng_window = Tk()
with:
...
if response == 'yes':
root.destroy()
...
global window
window = Toplevel()
...
global Eng_window
Eng_window = Toplevel()
def mouse_click(event):
#'reports' to both terminal and results text box
parent_name = Frame.winfo_parent(root)
parent = Frame._nametowidget(parent_name)
result = ("{0}: {1},{2}\n ".format('Clicked at', event.x, event.y))
print('clicked at',parent, event.x, event.y)
from tkinter import *
root = Tk()
root.title("Change Text")
root.geometry('700x500')
top=root.winfo_toplevel()
for rn in range(0,9): # rn = row number
top.rowconfigure(rn, weight=1)
top.rowconfigure(rn, weight=0)
for cn in range(0,5): # cn = column number
top.columnconfigure(cn, weight=1)
# FRAME 1
frame1 = Frame(root, borderwidth = 2, background = '#EFE0CD', relief = RIDGE,width = 25, height = 20)
frame1.bind("<Button-1>", mouse_click)
frame1.grid(column = 0, row = 0, columnspan = 2, rowspan = 3, sticky = N+S+E+W)
frame1_lbl = Label(frame1, text='Frame 1', font='comic-sans-MS 10 ', fg ='red', bg = '#EFE0CD')
frame1_lbl.grid(row=0, column =0)
# FRAME 2
frame2 = Frame(root, borderwidth = 2, background = '#CCC6B0', relief = RIDGE,width = 25, height = 20)
frame2.bind("<Button-1>", mouse_click)
frame2.grid(column = 0, row = 3, columnspan = 2, rowspan = 3, sticky = N+S+E+W)
frame2_lbl = Label(frame2, text='Frame 2', font='comic-sans-MS 10', fg ='red', bg = '#CCC6B0')
frame2_lbl.grid(row=0, column =0,)
root.mainloop()
I know that this is a really dumb question. How do I identify the Frame in which the mouse is clicked so that report prints clicked frame1 or frame2 at x y coordinates?. I found a bit about using winfo_parent but have obviously not used it properly.
Thank you
The event object that is passed in to the callback has a widget attribute which is a reference to the widget that got the event. So, event.widget is what you want to print.