I have created a custom message box that returns True if the yes button is pressed and False if the no button is pressed. Now I want to do logic based on that in the init method of the class MainApp. How can I do this? How can I get the instance attribute value of answer from the class MessageboxYesNo? I am fairly new to OOP.
from sys import platform
import tkinter as tk
class MainApp(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent #save root window object here when instantiating from this class
self.set_app_size_and_position()
#Exit button
self.exitButton = tk.Button(self.parent, text="Exit", command=lambda: MessageboxYesNo(self, "QUIT", "Are you sure you want to quit?"), bg="red", fg="black")
self.exitButton.pack(side="top", anchor='ne', padx=15, pady=10)
#Want to do logic here based on the answer from the messagebox. How can I access the answer from the MessageboxYesNo class/instance?
# if answer:
# do something
def set_app_size_and_position(self):
# get screen width and height
self.screen_width = int(self.parent.winfo_screenwidth())
self.screen_height = int(self.parent.winfo_screenheight())
self.app_width_mac = int(self.screen_width/2)
self.app_height_mac = int(self.screen_height)
self.app_x_pos_mac = int(self.screen_width/2)
self.app_y_pos_mac = 0
#set the app window to half of the screens width and to the right side of the screen
if platform == "darwin":
self.parent.geometry(f"{self.app_width_mac}x{self.app_height_mac}+{self.app_x_pos_mac}+{self.app_y_pos_mac}")
class MessageboxYesNo(tk.Frame):
def __init__(self, parent, title, text):
tk.Frame.__init__(self, parent)
self.parent = parent #this will be root
self.title = title
self.text = text
self.answer = None
self.toplevel = tk.Toplevel(self.parent)
#get the messagebox on top of the app window
self.toplevel.focus_force() # Get focus
self.toplevel.title(self.title)
#set x- and y-coordinates for centering the messagebox
#self.parent.app_x_pos_mac will get the instance attribute value from the class MainApp
self.x_pos_messagebox = int(self.parent.app_x_pos_mac+(self.parent.app_x_pos_mac/2))
self.y_pos_messagebox = int(self.parent.app_height_mac/2)
#position the messagebox near the center of the app
self.toplevel.geometry(f"500x300+{self.x_pos_messagebox}+{self.y_pos_messagebox}")
#add labels and buttons to messagebox
self.l1=tk.Label(self.toplevel, image="::tk::icons::question")
self.l1.grid(row=0, column=0, pady=(7, 0), padx=(10, 30), sticky="e")
self.l2=tk.Label(self.toplevel,text=self.text)
self.l2.grid(row=0, column=1, columnspan=3, pady=(7, 10), sticky="w")
self.b1=tk.Button(self.toplevel,text="Yes",width = 10, command=lambda: self.answerMessagebox(True))
self.b1.grid(row=1, column=1, padx=(2, 35), sticky="e")
self.b2=tk.Button(self.toplevel,text="No", width = 10, command=lambda: self.answerMessagebox(False))
self.b2.grid(row=1, column=2, padx=(2, 35), sticky="e")
def answerMessagebox(self, answerOnQuestion):
if answerOnQuestion == True:
print("You pressed yes")
self.answer = True
if answerOnQuestion == False:
print("You pressed no")
self.answer = False
print(self.answer)
self.toplevel.destroy() #close messagebox
return self.answer
def main():
root = tk.Tk()
app = MainApp(root)
app.pack()
root.mainloop()
if __name__ == "__main__":
main()
MainApp.__init__()has necessarily exited before the messagebox is even presented to the user, so what you're asking is fundamentally impossible. You need to handle the messagebox results in the same code that actually presented the messagebox - which in this case is thecommand=option of your Button. This exceeds what you can reasonably do in alambda, so move it to a separate function.command=? Can you please explain a little bit further?