Reputation: 3
I'm trying to write my first GUI based python program using Tkinter. I have created a base window which holds the menu bar with a couple of options.
One of the options is for a standard 'About' box. When I call the about section with
helpMainMenu.add_command(label="About", command=self.aboutProgram)
It opens the message box, but in a fresh window so there are now two windows showing on the taskbar. Is there any way to stop it opening a new window and use the main one instead, or is there a better way to do it?
The full code is below
#! /usr/bin/python3
from tkinter import *
from tkinter import messagebox
import datetime
timeNow = datetime.datetime.now()
writeYear = 2020 # Enter the year you started writing the program
lineFeed = "\n"
programTitle = "Basic Menu"
programVersion = "Version 1.0.0"
programmerName = " Name ([email protected])"
if timeNow.year > writeYear:
programAuthor = "©" + str(writeYear) + "-" + str(timeNow.year) + programmerName
else:
programAuthor = "©" + str(writeYear) + programmerName
aboutMessage = programTitle + lineFeed + programVersion + lineFeed + programAuthor
class Window(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title("{} ({})".format(programTitle, programVersion))
self.pack(fill=BOTH, expand=1)
menu = Menu(self.master)
self.master.config(menu=menu)
fileMainMenu = Menu(menu, tearoff=0) #Create the File menu container
fileMainMenu.add_command(label="Exit", command=self.programExit) # File menu option
menu.add_cascade(label="File", menu=fileMainMenu)
helpMainMenu = Menu(menu, tearoff=0) #Create the Help menu container
helpMainMenu.add_command(label="About", command=self.aboutProgram)
menu.add_cascade(label="Help", menu=helpMainMenu)
def programExit(self):
exitMsgBox = messagebox.askquestion ("Exit Application","Are you sure you want to exit the application",icon = "warning")
if exitMsgBox == "yes":
root.destroy()
exit()
def aboutProgram(self):
messagebox.showinfo("About","About the application", icon = "info")
root = Tk() # root window created. Here, that would be the only window, but
windowHeight = int(root.winfo_screenheight()/100*75) # Set the main window height to 75% of the screen height
windowWidth = int(root.winfo_screenwidth()/100*75) # Set the main window width to 75% of the screen width
screenWidth = int(root.winfo_screenwidth())
screenHeight = int(root.winfo_screenheight())
positionRight = int(root.winfo_screenwidth()/2 - windowWidth/2) # Get the screen width and divide by 2, then minus the result of 'windowWidth' divided by 2
positionDown = int(root.winfo_screenheight()/2 - windowHeight/2) # Get the screen height and divide by 2, then minus the result of 'windowHeight' divided by 2
root.geometry("{}x{}+{}+{}".format(windowWidth, windowHeight, positionRight, positionDown)) # Positions the window in the center of the page.
app = Window(root)
root.mainloop()
Python Version 3.7.3
tkinter.TkVersion 8.6
Upvotes: 0
Views: 283
Reputation: 386342
The simplest way would be to create a new frame for the "about" page, and then overlay it on top of the main window with place
-- one of the few times when place
is superior to grid
and pack
.
You should also do a "grab" on the frame so that all events are funneled to the frame and its children. With a grab, while the popup is visible you can't interact with the widgets on the main window.
Here's a quick example:
def aboutProgram(self):
# create the frame with a message and a button
# which destroys the window
aboutFrame = Frame(self.master, bd=2, relief="groove")
label = Label(aboutFrame, text="About the application...")
button = Button(aboutFrame, text="Ok", command=aboutFrame.destroy)
label.pack(side="top", padx=20, pady=20)
button.pack(side="bottom", pady=20)
# overlay the "about" page on top of the root window
aboutFrame.place(relx=.5, rely=.5, anchor="c")
# force all events to go to the popup
aboutFrame.grab_set()
If you want to completely hide the contents of the main window, you can change the place
arguments to fill the window:
aboutFrame.place(x=0, y=0, anchor="nw", relwidth=1.0, relheight=1.0)
Upvotes: 1