0

Below is how I have coded. A box will pop up with 2 options A, and B. User chooses the radio button and then click confirm to proceed.

def main_function():
    # Generate Tk class
    source_url = tk.Tk()

    # Screen size
    source_url.geometry ('270x100')

    # Screen title
    source_url.title ('Choose a source')

    # List radio button labels
    rdo_txt = ['A','B']

    # Radio button status
    rdo_var = tk.IntVar ()

    # Create and place radio buttons dynamically
    for i in range(len(rdo_txt)):  
        rdo = tkinter.Radiobutton (source_url, value = i, variable = rdo_var, text = rdo_txt [i])
        rdo.place (x = 40, y = 15 + (i * 20))
        
    # Button click event
    def btn_click ():
        url_domain = rdo_var.get()
        source_url.destroy()
        return url_domain

    # Create button
    confirm_button = tk.Button (source_url, text = 'Confirm', command = btn_click())
    confirm_button.place (x = 130, y = 30)
    source_url.mainloop()

if __name__ == "__main__": 
    main_function()

The error is ;

DevTools listening on ws://127.0.0.1:56974/devtools/browser/b4944cc1-632c-4830-a196-e98d2ad590d8
[45520:24484:0820/100600.304:ERROR:device_event_log_impl.cc(214)] [10:06:00.304] USB: usb_device_handle_win.cc:1048 Failed to read descriptor from node connection: A device attached to the system is not functioning. (0x1F)
Traceback (most recent call last):
  File "Web_scapper_1.0.py", line 363, in <module>
    main_function()
  File "Web_scapper_1.0.py", line 90, in main_function
    confirm_button = tk.Button (source_url, text = 'Confirm', command = btn_click())
  File "C:\Users\abc\anaconda3\lib\tkinter\__init__.py", line 2369, in __init__
    Widget.__init__(self, master, 'button', cnf, kw)
  File "C:\Users\abc\anaconda3\lib\tkinter\__init__.py", line 2299, in __init__
    (widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: can't invoke "button" command: application has been destroyed

It seems that when the confirm_button was run, it executed source_url.destroy() before the user actually clicks the button.

I have tried to move the source_url.destroy() above source_url.mainloop(), the error message is the same as above. If I move to below source_url.mainloop(), the source_url application did not close after button click.

How make the btn_click actually waits for an actual button-click by the user before source_url.destroy()?

user3782604
  • 330
  • 1
  • 19

1 Answers1

1

it is because you have a parenthesis: command = btn_click() When you put the parenthesis, it indicates calling the function. So when you put command = btn_click(), as the statement is executed, the function is executed and the returned value is kept as the command.

Since the function contains the statement: source_url.destroy(), the main window or the instance of Tk() is destroyed before the button is even properly initialised.

You should only put a reference to the function:

confirm_button = tk.Button (source_url, text = 'Confirm', command = btn_click)
confirm_button.place (x = 130, y = 30)