【问题标题】:Use control panel for discord bot with PyQt5使用 PyQt5 的 discord bot 控制面板
【发布时间】:2020-08-23 03:27:00
【问题描述】:

我想用 PyQt5 在 python 中为我的 discord 机器人做一个控制面板。我已经有了我的窗口:

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1023, 457)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
       
#some other widgets

        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(330, 30, 91, 31))
        font = QtGui.QFont()
        font.setPointSize(16)
        self.pushButton.setFont(font)
        self.pushButton.setObjectName("pushButton")

#some other widgets         

和主要代码:

import discord
import sys
from window import Ui_MainWindow
from PyQt5 import QtCore, QtGui, QtWidgets

prefix = ""
bot = discord.Client

class MyClient(bot):

    async def on_connect(self):
        print("Bot connected to")

    async def on_ready(self):
        print('Logged on as {0}!'.format(self.user))

        for guild in self.guilds:
            if guild.id == 354061299596132392:
                print("guild find")


    async def on_message(self, message):
        print(message.content)

    async def on_diconnect(self):
        print("bot disconnected")



def launcher():
    client = MyClient()
    client.run('TOKEN')



def windowLauncher():



    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    ui.pushButton.clicked.connect(launcher)
    MainWindow.show()
    sys.exit(app.exec_())


windowLauncher()

但是当我执行这个主代码时,窗口会启动,当我按下按钮启动机器人时,窗口会崩溃,但机器人正在运行。我已经尝试过使用线程,但没有成功。

【问题讨论】:

  • 你不能只使用线程同时运行两个事件循环吗?因为您的问题看起来像是来自双事件循环。

标签: python pyqt pyqt5 python-asyncio discord.py


【解决方案1】:

discord 使用异步,它有自己的事件循环,而 Qt 处理另一个事件循环,导致一个事件循环阻塞另一个。在这种情况下,解决方案是两者都使用相同的事件循环,并且有几个库实现它:

  • qasync (python -m pip install qasync)
  • asyncqt (python -m pip install asyncqt)

综合以上,解决办法是:

import asyncio
import sys

import discord
from qasync import QEventLoop, asyncSlot
# or
# from asyncqt import QEventLoop, asyncSlot

from PyQt5 import QtCore, QtGui, QtWidgets

from window import Ui_MainWindow


prefix = ""


class MyClient(discord.Client):
    async def on_connect(self):
        print("Bot connected to")

    async def on_ready(self):
        print("Logged on as {0}!".format(self.user))

        for guild in self.guilds:
            if guild.id == 354061299596132392:
                print("guild find")

    async def on_message(self, message):
        print(message.content)

    async def on_diconnect(self):
        print("bot disconnected")


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.client = MyClient()
        self.pushButton.clicked.connect(self.on_clicked)

    @asyncSlot()
    async def on_clicked(self):
        await self.client.start("YOUR_TOKEN")


def windowLauncher():

    app = QtWidgets.QApplication(sys.argv)
    loop = QEventLoop(app)
    asyncio.set_event_loop(loop)

    w = MainWindow()
    w.show()
    loop.run_forever()


if __name__ == "__main__":
    windowLauncher()

【讨论】:

  • @FabienDenoyelle 避免提供令牌、密码等敏感信息。
  • asyncqtqasync 有比较吗?如果我的理解是正确的,qasync 最初是作为 asyncqt 的一个分支,旨在作为延续,因为当时 asyncqt 似乎没有维护。但是asyncqt的维护后来恢复了,所以两人最终成为了竞争对手。与每个开源分叉一样,两者都会导致重复工作和生态系统的分裂,在这种情况下,没有合理的工程原因,例如重要的创新或权衡选择的差异。它们因纯粹的历史偶然性而平行存在。
  • @user4815162342 你在开头指出的是正确的,qasync 是 asynqt 的一个分支,因为它有几个初始错误并且 repo 没有激活,一段时间后两个 repos 都更新了(他们消除了历史错误)。 qasync 自述文件中指出了这一点
  • 感谢您的确认。不过,现在它们之间是否存在已知差异?选择在项目中使用哪一个时相关的东西。
  • @user4815162342 mmm,没有相关区别
猜你喜欢
  • 2021-03-29
  • 1970-01-01
  • 2021-06-15
  • 2020-08-02
  • 2020-11-15
  • 2020-09-21
  • 2021-07-03
  • 2021-01-19
  • 2022-10-21
相关资源
最近更新 更多