@soks_of_fate

Как исправить ошибку взаемодействия Дискорд бота и окна?

Вот код который я писал, но у меня возникла проблема. Когда я нажимаю на кнопку "Move to channel" то ничего не происходит. А после закрытия окна появляется ошибка:

Traceback (most recent call last):
  File "C:\Users\vitli\PycharmProjects\pythonProject\main.py", line 167, in <module>
    loop = asyncio.get_event_loop()
  File "C:\Users\vitli\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 'MainThread'.


import discord
from discord.ext import commands
from tkinter import *
from tkinter import ttk
import asyncio
import queue
import threading

intents = discord.Intents.all()
intents.voice_states = True
intents.typing = False

bot = commands.Bot(command_prefix='^', intents=intents)
bot_queue = queue.Queue()
entry2 = None
root = None


@bot.event
async def on_ready():
    print(f'We have logged in as {bot.user}')


async def main():
    await bot.start('тут токен')
    await process_bot_queue()




def run_bot():
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.create_task(main())
    loop.run_forever()




def create_window():
    global entry2, root

    root = Tk()
    root.title("Discord Bot Window")
    root.geometry("700x400")
    root.resizable(False, False)

    def click_button2():
        channel_name = entry2.get()
        asyncio.run(get_voice_list(channel_name))

    btn2 = ttk.Button(root, text="Calculate", command=click_button2)
    btn2.pack()
    btn2.place(x=310, y=30)
    entry2 = ttk.Entry(root)
    entry2.pack()
    entry2.place(x=300, y=60, width=300, height=50)

    # ...

    root.mainloop()


def click_button3(channel_name, nickname, label):
    bot_queue.put((channel_name, nickname, label))


async def move_user_to_channel(channel_name, nickname, label):
    voice_channel = discord.utils.get(bot.get_all_channels(), name=channel_name)
    if voice_channel is not None:
        member = discord.utils.get(voice_channel.guild.members, display_name=nickname)
        if member is not None:
            await member.move_to(voice_channel)
            label["text"] = f'{nickname} has been moved to voice channel {channel_name}.'
        else:
            label["text"] = f'Member with nickname {nickname} not found.'
    else:
        label["text"] = f'Voice channel {channel_name} not found.'







async def process_bot_queue():
    while True:
        item = bot_queue.get()
        if isinstance(item, tuple):
            channel_name, nickname, label = item
            await move_user_to_channel(channel_name, nickname, label)  # Удалите bot.loop из вызова
        elif isinstance(item, str):
            www = item
            loop = asyncio.get_event_loop()
            loop.create_task(get_voice_list(www))
        bot_queue.task_done()






async def get_voice_list(www):
    await bot.wait_until_ready()
    try:
        if "music" in www:
            print("Found")
        else:
            guild_id = int(www)
            guild = bot.get_guild(guild_id)
            if guild is not None:
                voice_channels = guild.voice_channels
                channel_names = [channel.name for channel in voice_channels]
                create_channel_buttons(channel_names)
    except ValueError:
        print("Invalid input value.")


def create_channel_buttons(channel_names):
    for i, channel_name in enumerate(channel_names):
        btn = ttk.Button(root, text=channel_name, command=lambda name=channel_name: open_new_window(name))
        btn.pack()
        btn.place(x=10, y=150 + i * 30)


def open_new_window(channel_name):
    new_window = Toplevel(root)
    new_window.title(channel_name)
    new_window.geometry("500x500")

    label_nickname = ttk.Label(new_window, text="Nickname:")
    label_nickname.pack()
    label_nickname.place(x=10, y=10)

    entry_nickname = ttk.Entry(new_window)
    entry_nickname.pack()
    entry_nickname.place(x=80, y=10)

    btn_move = ttk.Button(new_window, text="Move to channel",
                          command=lambda: click_button3(channel_name, entry_nickname.get(), label3))
    btn_move.pack()
    btn_move.place(x=200, y=10)

    label3 = ttk.Label(new_window)
    label3.pack()
    label3.place(x=10, y=50)

    voice_channel = discord.utils.get(bot.get_all_channels(), name=channel_name)
    if voice_channel is not None:
        participants = voice_channel.members
        participant_names = [member.display_name for member in participants]
        participant_list = "\n".join(participant_names)
        label_participants = ttk.Label(new_window, text=f'Participants in channel {channel_name}:\n{participant_list}')
        label_participants.pack()
        label_participants.place(x=10, y=90)


if __name__ == '__main__':
    bot_thread = threading.Thread(target=run_bot)
    bot_thread.start()

    create_window()

    loop = asyncio.get_event_loop()
    loop.create_task(process_bot_queue())
    loop.run_forever()


Да, это спагетти код, но я не дуал что кто-то кроме меня увидет его поэтому не напрягался о его красоте. Прошу, если кто-то знает как исправить
  • Вопрос задан
  • 50 просмотров
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
#
    loop = asyncio.get_event_loop()
    loop.create_task(process_bot_queue())
    loop.run_forever()

Что вообще вот этот код делает в теле программы, если у тебя вызов create_window() не вернёт управление, пока окно GUI не будет закрыто?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы