PySimpleGUI button event not working in Python code – why?

Question:

Why the button event is not avalible with pysimplegui?

This is my Code.

import os
import threading
import PySimpleGUI as gui
from rsa_controller import decryptwithPrivatekey, loadPublicKey, loadPrivateKey

id = 0
target_id = 0
prikey = None


def popout(title):
    gui.popup(title)


def read_keys():
    print("Opening key files: " + os.getcwd() + "\keys\")
    pubkey = loadPublicKey(os.getcwd() + "\keys\public.pem")
    prikey = loadPrivateKey(os.getcwd() + "\keys\private.pem")


def recv_msg():
    global target_id
    from main import s
    while True:
        data = s.recv(1024)
        if not data:
            break
        decoded_data = data.decode('utf-8')
        if decoded_data == 'target_connected_Success':
            print("Received message:", decoded_data)
        elif decoded_data.startswith("!+@"):
            target_id = decoded_data[3:]
            window2()
        elif decoded_data == 'target_connect_denied':
            gui.popup('Connection request denied')
        else:
            msg_to_recv = decryptwithPrivatekey(decoded_data, prikey)
            print("Received message:", msg_to_recv)


def window2():
    from main import s
    global target_id
    layout2 = [
        [gui.Text('Connecting with'), gui.Text(str(target_id), key='target_id'), gui.Text("Establishing contact")],
        [gui.Button('Accept and share my public key', key='accept', enable_events=True),
         gui.Button('Deny connection invitation', key='denied', enable_events=True)]
    ]
    window = gui.Window("Connection Request", layout2, finalize=True)
    while True:
        event2, values2 = window.read()
        if event2 == gui.WINDOW_CLOSED:
            break
        if event2 == 'Deny connection invitation':
            print("Connection denied")
            s.send('!x!{}'.format(target_id).encode('utf-8'))
            window.close()
        if event2 == 'Accept and share my public key':
            print("Accepting and sharing public key")
            # Handle the logic for accepting the connection
    window.close()


def start_GUI_progress(id):
    from main import s
    read_keys()
    layout = [
        [gui.Text('Your identification code'), gui.Text(id)],
        [gui.Text('Hint: Please enter the identification code of the person you want to connect to in the input box below and click the Connect button')],
        [gui.Input(key='target_id'), gui.Button('Connect', key='connect')]
    ]
    window = gui.Window("RSA Encrypted Chat Software", layout)
    host = "localhost"
    port = 23333
    s.connect((host, port))
    print(s.recv(1024))
    t_recv = threading.Thread(target=recv_msg)
    t_recv.start()
    s.send(b"__!" + str(id).encode('utf-8'))
    while True:
        event, values = window.read()
        if event is None:
            break
        if event == 'connect':
            print("Client is attempting to connect to: {}".format(values['target_id']))
            message = "_!?{}".format(values['target_id'])
            s.send(message.encode('utf-8'))
    window.close()


I found that the first window is intractivable,but after the window2 successfully displayed,i press buttons on it and nothing happend,what’s more,when the window2 displaying, there is an error:

Exception in thread Thread-1 (recv_msg):
Traceback (most recent call last):
File "C:UsersbaoAppDataLocalProgramsPythonPython310libthreading.py", line 1009, in _bootstrap_inner
self.run()
File "C:UsersbaoAppDataLocalProgramsPythonPython310libthreading.py", line 946, in run
self._target(*self._args, **self._kwargs)
File "C:UsersbaoPycharmProjectsRSAEncryptedChatSoftwareGUIDisplay.py", line 32, in recv_msg
window2()
File "C:UsersbaoPycharmProjectsRSAEncryptedChatSoftwareGUIDisplay.py", line 46, in window2
window = gui.Window("Connecting with", layout2, finalize=True)
File "C:UsersbaoPycharmProjectsRSAEncryptedChatSoftwarevenvlibsite-packagesPySimpleGUIPySimpleGUI.py", line 9614, in init
self.Finalize()
File "C:UsersbaoPycharmProjectsRSAEncryptedChatSoftwarevenvlibsite-packagesPySimpleGUIPySimpleGUI.py", line 10300, in finalize
self.Read(timeout=1)
File "C:UsersbaoPycharmProjectsRSAEncryptedChatSoftwarevenvlibsite-packagesPySimpleGUIPySimpleGUI.py", line 10075, in read
results = self._read(timeout=timeout, timeout_key=timeout_key)
File "C:UsersbaoPycharmProjectsRSAEncryptedChatSoftwarevenvlibsite-packagesPySimpleGUIPySimpleGUI.py", line 10146, in _read
self._Show()
File "C:UsersbaoPycharmProjectsRSAEncryptedChatSoftwarevenvlibsite-packagesPySimpleGUIPySimpleGUI.py", line 9886, in Show
StartupTK(self)
File "C:UsersbaoPycharmProjectsRSAEncryptedChatSoftwarevenvlibsite-packagesPySimpleGUIPySimpleGUI.py", line 16935, in StartupTK
window.TKroot.mainloop()
File "C:UsersbaoAppDataLocalProgramsPythonPython310libtkinter_init
.py", line 1458, in mainloop
self.tk.mainloop(n)
RuntimeError: Calling Tcl from different apartment

Process finished with exit code 0

Asked By: ddhello

||

Answers:

    layout2 = [
        [gui.Text('Connecting with'), gui.Text(str(target_id), key='target_id'), gui.Text("Establishing contact")],
        [gui.Button('Accept and share my public key', key='accept', enable_events=True),
         gui.Button('Deny connection invitation', key='denied', enable_events=True)]
    ]
        if event2 == 'Deny connection invitation':
            print("Connection denied")
            s.send('!x!{}'.format(target_id).encode('utf-8'))
            window.close()
        if event2 == 'Accept and share my public key':
            print("Accepting and sharing public key")
            # Handle the logic for accepting the connection

The keys defined for buttons are different from the events used in the event loop.

  • keys defined for buttons:'accept' and 'denied'.
  • The events: 'Accept and share my public key' and 'Deny connection invitation'.

t_recv = threading.Thread(target=recv_msg)

def recv_msg():
    # ... wrong, try to call `window.write_event_value` to generate an event to call `window2` in main thread.
            window2()
    # ... wrong, try to call `window.write_event_value` to generate an event to call `gui.popup` in main thread.
            gui.popup('Connection request denied')
    # ...

GUI should be run under main thread !

Answered By: Jason Yang
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.