如何解决Discord Python,在调用 client.close() 之后,我希望能够再次调用 client.start(),但不知何故客户端多次登录
我正在尝试使用基于 Qt 的 GUI 构建 discord Bot。我想要两个按钮,一个启动机器人,一个停止它。当我在 client.close()
后重新启动时,Bot 使用多个实例登录,但我不知道如何修复它。
代码:
import bot # some discord bot that can login on a server and send a message
import asyncio
from PySide6.QtWidgets import QLabel,QWidget,QPushButton,QTextbrowser,QComboBox
from qasync import QEventLoop,asyncslot,QApplication
from PySide6.QtCore import QFile
from PySide6.QtUiTools import quiloader
import PySide6.QtGui as QtGui
class main(QWidget):
def __init__(self):
super(main,self).__init__(Parent=None)
self.load_ui()
self.btn_startbot = self.findChild(QPushButton,'btn_startbot')
self.btn_startbot.clicked.connect(self.on_btn_startbot_clicked)
self.btn_stopbot = self.findChild(QPushButton,'btn_stopbot')
self.btn_stopbot.clicked.connect(self.on_btn_stopbot_clicked)
def load_ui(self):
loader = quiloader()
ui_file = QFile("form.ui") # some ui,that has buttons
ui_file.open(QFile.ReadOnly)
loader.load(ui_file,self)
ui_file.close()
@asyncslot()
async def on_btn_startbot_clicked(self):
print("clicked start bot")
self.bot = bot.MyBot(command_prefix='-',self_bot=False)
self.bot.sig_slot_handler.sig_send_log.connect(self.slot_log_msg)
await self.bot.start('Token')
@asyncslot()
async def on_btn_stopbot_clicked(self):
await self.bot.close()
@asyncslot(str)
async def slot_log_msg(self,logmsg):
print(logmsg)
我不知道这是否与事件循环有关,但我需要使用 qasync,因为 Qt 事件循环和 discord 的 async
事件循环发生冲突。
if __name__ == "__main__":
app = QApplication([])
loop = QEventLoop(app)
asyncio.set_event_loop(loop)
widget = main()
widget.show()
loop.run_forever()
最小机器人类:
class MyBot(commands.Bot):
sig_slot_handler = q_signal_slot_handler()
def __init__(self,command_prefix,self_bot,parent=None):
commands.Bot.__init__(self,command_prefix=command_prefix,self_bot=self_bot)
self.add_commands()
self.add_events()
def add_events(self):
@self.event
async def on_ready():
self.sig_slot_handler.send_log_signal(f'PyBot login')
def add_commands(self):
@self.command(brief="Send a Message",usage="<MESSAGE WORDS>",help="Send a Message in your active Text Channel. Type: -send <MESSAGE WORDS>")
async def send(ctx,*,message):
await ctx.message.delete()
self.sig_slot_handler.send_log_signal(f'{ctx.author} used send in {ctx.message.channel}.')
await ctx.send(message)
我还创建了一个类来处理 Qt 信号和插槽:
class q_signal_slot_handler(QObject):
sig_send_log = Signal(str)
def __init__(self,Parent=None):
super(q_signal_slot_handler,self).__init__(Parent=Parent)
def send_log_signal(self,logmsg):
self.sig_send_log.emit(logmsg)
在我按下停止然后重新开始后会发生什么,输出是这样的:
解决方法
问题是 sig_slot_handler 是所有 MyBot 的单个对象,因此您多次连接相同的信号,因此当发出信号时,将多次调用插槽。解决办法是把类的一个属性做成sig_slot_handler:
class MyBot(commands.Bot):
def __init__(self,command_prefix,self_bot,parent=None):
commands.Bot.__init__(self,command_prefix=command_prefix,self_bot=self_bot)
self.sig_slot_handler = q_signal_slot_handler()
self.add_commands()
self.add_events()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。