Как соединить два разных потока?

Работаю с логированием и разрабатывают интерфейс на модуле PySimpleGUI. Есть два кода, основной (PySimpleGUI). И другой код, в котором запускается Discord бот.

main.py: (Основной)

...
...
...

root_logger= logging.getLogger()
root_logger.setLevel(logging.DEBUG)
handler = logging.FileHandler('PVPLog.log', 'w', 'utf-8') 
handler.setFormatter(logging.Formatter('%(name)s, %(asctime)s, [%(levelname)s], %(message)s'))
root_logger.addHandler(handler)

def log(log):
    logger.info(log)

def Start():
    
    import vb
    log("vb.py - запущен!")

class ThreadedApp(threading.Thread):
    def __init__(self):
        super().__init__()
        self._stop_event = threading.Event()

    def run(self):
        Start()

    def stop(self):
        self._stop_event.set()

class QueueHandler(logging.Handler):
    def __init__(self, log_queue):
        super().__init__()
        self.log_queue = log_queue

    def emit(self, record):
        self.log_queue.put(record)


def main():

    layout = [
            [sg.Multiline(size=(75, 35), key='-LOG-', disabled=True, autoscroll=True)],
            [sg.Button('Запустить', bind_return_key=True, key='-START-'), sg.Button('Завершить', key="-EXIT-")]
        ]

    window = sg.Window('VALHEIMBY LOGS - v1.0.0', layout,
            default_element_size=(30, 2),
            font=('Consolas', ' 10'),
            default_button_element_size=(8, 2), 
            icon=path_icon_log)

    appStarted = False

    logging.basicConfig(level=logging.DEBUG)
    log_queue = queue.Queue()
    queue_handler = QueueHandler(log_queue)
    logger.addHandler(queue_handler)
    threadedApp = ThreadedApp()

    while True:
        event, values = window.read(timeout=100)

        if event == '-START-':
            if appStarted is False:
                threadedApp.start()
                logger.debug('Логирование запущено! [PVPLogs]')
                window['-START-'].update(disabled=True)
                appStarted = True
        elif event == "-EXIT-":
            logger.debug('Приложение завершено!')
            window['-START-'].update(disabled=False)
            appStarted = False
            break
        elif event == WIN_CLOSED:
            break

        try:
            record = log_queue.get(block=False)
        except queue.Empty:
            pass
        else:
            msg = queue_handler.format(record)
            window['-LOG-'].update(f'{msg}\n', append=True)

    window.close()

if __name__ == '__main__':
    main()

При нажатие на кнопку "Запустить", импортируется vb.py - функционал Discord бота:

class ThreadedApp(threading.Thread):
    def __init__(self):
        super().__init__()
        self._stop_event = threading.Event()

    def run(self):
        Start() 

    def stop(self):
        self._stop_event.set()

class QueueHandler(logging.Handler):
    def __init__(self, log_queue):
        super().__init__()
        self.log_queue = log_queue

    def emit(self, record):
        self.log_queue.put(record)


def main():

    layout = [
            [sg.Multiline(size=(75, 35), key='-LOG-', disabled=True, autoscroll=True)],
            [sg.Button('Запустить', bind_return_key=True, key='-START-'), sg.Button('Завершить', key="-EXIT-")]
        ]

    window = sg.Window('VALHEIMBY LOGS - v1.0.0', layout,
            default_element_size=(30, 2),
            font=('Consolas', ' 10'),
            default_button_element_size=(8, 2), 
            icon=path_icon_log)

    appStarted = False

    logging.basicConfig(level=logging.DEBUG)
    log_queue = queue.Queue()
    queue_handler = QueueHandler(log_queue)
    logger.addHandler(queue_handler)
    threadedApp = ThreadedApp()

    while True:
        event, values = window.read(timeout=100)

        if event == '-START-':
            if appStarted is False:
                threadedApp.start()
                logger.debug('Логирование запущено!')
                window['-START-'].update(disabled=True)
                appStarted = True

vb.py: (Discord бот)

bot = commands.Bot(command_prefix=';', help_command=None)
now = datetime.now()
gettime = now.strftime("%d/%m/%Y | %H:%M:%S > ")

def signal_handler(signal, frame): 
  os._exit(0)

signal.signal(signal.SIGINT, signal_handler)

@bot.event
async def on_ready():
    print(f'{gettime}BOT CONNECTED - {bot.user} :)')
    print('config> LOG CHANNEL : %d' % (lchanID))
    if config.USEVCSTATS == True:
        print('config> CHANNEL VoIP: %d' % (chanID))

bot.run(config.BOT_TOKEN)

При выполнение возникает ошибка:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Users\Stepan\AppData\Local\Programs\Python\Python39\lib\threading.py", line 954, in _bootstrap_inner
    self.run()
  File "c:\Users\Stepan\Desktop\VALHEIMBY BOT\programma\basic.py", line 118, in run
    Start()
  File "c:\Users\Stepan\Desktop\VALHEIMBY BOT\programma\basic.py", line 69, in Start
    import s
  File "c:\Users\Stepan\Desktop\VALHEIMBY BOT\programma\s.py", line 11, in <module>
    import basic
  File "c:\Users\Stepan\Desktop\VALHEIMBY BOT\programma\basic.py", line 51, in <module>
    bot = commands.Bot(command_prefix=';', help_command=None)
  File "C:\Users\Stepan\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 98, in __init__
    super().__init__(**options)
  File "C:\Users\Stepan\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 1107, in __init__
    super().__init__(*args, **kwargs)
  File "C:\Users\Stepan\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 229, in __init__
    self.loop = asyncio.get_event_loop() if loop is None else loop
  File "C:\Users\Stepan\AppData\Local\Programs\Python\Python39\lib\asyncio\events.py", line 642, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1'.

Весь код:

discord: https://pastebin.com/PyCQcVLx
pysimplegui: https://pastebin.com/ivtaGYet


Ответы (1 шт):

Автор решения: eri

Говорит нет event loop - попробуй создать.

Команду bot.run( замени на bot.start

loop = asyncio.new_event_loop()
try:
    loop.run_until_complete(bot.start(config.BOT_TOKEN))
except KeyboardInterrupt:
    loop.run_until_complete(bot.close())
    # cancel all tasks lingering
finally:
    loop.close()

PS. signal в треде не сработает

→ Ссылка