0

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.

  • 1
    No, we haven't have to have the whole code, especially not the image parts. – Nae Feb 27 '18 at 21:36
  • 2
    Please provide [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). You do not need to provide all the code. Just enough that shows the problem. In doing so you often find the problem yourself. – Mike - SMT Feb 27 '18 at 21:37

2 Answers2

1

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()
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79
  • Thanyou for your help, the only reason i didnt use a class i because i struggle to understand them, like what does def __init__(self, parent, *args, **kwargs): tk.Frame.__init__(self,parent, *args, **kwargs) Mean? –  Feb 27 '18 at 22:37
  • The `__init__` portion is how the class is initialized. Technically you do not need the `*args, **kwargs` part as they are for extra variables to be submitted to the class if you add more functionality later. You can just use `__init__(self, parent)` here. – Mike - SMT Feb 27 '18 at 22:44
  • @tom the OOP method can be hard to learn at first but if you work with what I have provided and do a little research as you add to the program it will click eventually. Once it does it will make sense. You can write this in Non_OOP but it will be harder to maintain and require some rearranging of the methods/functions. – Mike - SMT Feb 27 '18 at 22:48
  • is there anything you would recommend so that I can get a better understanding of classes like books or websites –  Feb 27 '18 at 22:53
  • @Tom the way I learned was youtube. It was a massive help. And a lot of googling. – Mike - SMT Feb 27 '18 at 22:55
  • Ok thanks for the help and advise I'm gona get researching it now, any recomended youtube channels –  Feb 27 '18 at 23:00
  • @tom Socratica is a good place to start. It fun and accurate. It's a YouTube channel. – Mike - SMT Feb 27 '18 at 23:02
  • 2
    I have been learning classes for the last 5 hours and I'm getting the hang of it now, I can realy see the benefits as my code is much more organised and it is much easyer to identify problems in the code. Socratica was a good shout and stackoverflow.com/q/17466561/7032856 was very useful to in seeing the structure of classes. Thankyou –  Feb 28 '18 at 18:46
  • Glad it helped :) – Mike - SMT Feb 28 '18 at 19:05
  • yea sorry I solved it but forgot to remove my comment –  Mar 01 '18 at 19:03
0

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()
Nae
  • 14,209
  • 7
  • 52
  • 79