简体   繁体   中英

Unresponsive tkinter SimpleDialog box

Below is an outline of a tkinter GUI in which I want the same dialog box to be opened in various ways. The response selected by the user from choices in the dialog then needs to be returned to the mainloop.
The SimpleDialog class looks to be ideal for this and here I have just used the example provided in the dialog code. It is accessed by both the button and popup menu in the View class, along with their bindings in the Controller class. It works just fine when called from the button, but when called from the popup menu (from a right click) the dialog appears and then freezes the entire app.

from tkinter import simpledialog as s
import tkinter as tk

class View(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self)       
        self.grid(row=0, column=0, sticky='nsew')
        self.configure(bg = 'blue')
        self.popup = tk.Menu(self, tearoff=0)
        self.bind("<Button-2>", self.make_popup) #right-click to show popup 
        self.button = tk.Button(self, text='Test')
        self.button.grid()             
    def make_popup(self, event):
        try:
            self.popup.tk_popup(event.x_root + 15, event.y_root, 0)
        finally:
            self.popup.grab_release()            
        
class Controller():
    def __init__(self, view):
        view.popup.add_command(label ='do test', command = lambda : self.do_test(None, view))  
        view.popup.add_command(label ='dummy test', command = print('This one works OK')) 
        view.button.bind("<Button-1>",  lambda e, : self.do_test(e, view))        
    def do_test(self, event, view):
        d = s.SimpleDialog(view,
                     text="This is a test dialog.  "
                          "Would this have been an actual dialog, "
                          "the buttons below would have been glowing "
                          "in soft pink light.\n"
                          "Do you believe this?",
                     buttons=["Yes", "No", "Cancel"],
                     default=0,
                     cancel=2,
                     title="Test Dialog")      
        print(d.go())
        
class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.geometry('200x100')  
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)    
        view = View(self)
        controller = Controller(view)

if __name__ == "__main__":  
    app = App()         
    app.mainloop()   

It seems to me that the dialog should either work or not work, and not care how it is called. So I would be very grateful for an explanation as to why it responds in one case but not the other, and of course equally grateful for a fix.

The problem appears to lie in the print statement in the do_test callback, as splitting this into two lines fixes it

    #print(d.go())       
    answer = d.go()
    print(answer)

As reported in a comment this may be only an issue for MacOS (I am using MacOS 11.1 and Python 3.10.8 ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM