如何解决如何在python脚本之间传递值数据?
在两个不同的 Python 脚本之间进行通信(传递字符串)的正确方式是什么?
我有一个 ui.py 脚本,它利用 PySide6 生成 GUI,我有另一个 bot.py 脚本,它侦听不和谐/电报对话并使用异步函数捕获一些关键字。两个脚本都在同一个目录下。
我已将 bot.py 文件中的 Asyncio 事件循环代码放入名为 runscript() 的函数中,并使用 ui.py 中的 multiprocessing.Process 在单击 PySide6 QPushButton 后运行该函数。
所以这里的问题是我想在我的 GUI 中显示 bot.py 捕获的关键字,所以我需要将该字符串传递给 ui.py(需要以另一种方式传递字符串 - 从 ui.py 到 bot .py- 在未来),但我不知道如何做到这一点。我尝试过 multiprocessing.Pipe 但这会阻止我的代码,因为脚本会在新消息到达时(使用 Asyncio)从 discord/telegram 中获取消息,而我等不及要发生这种情况。
#bot.py
# do other stuff above here
@discord_client.event
async def on_message(message):
if message.channel.id in discord_channel_list:
discord_message = message.content
selected_symbol = message_analyzer(discord_message)
print(selected_symbol)
async def discord_connection():
await discord_client.start(discord_token)
def runscript():
connection = asyncio.get_event_loop()
connection.create_task(binance_connection())
connection.create_task(discord_connection())
connection.create_task(telegram_connection())
connection.create_task(connection_check())
try:
connection.run_forever()
except KeyboardInterrupt:
print("\nShutting down...")
except:
print("\nWARN! Shutting down...")
例如我需要获取 selected_symbol 的值并将其传输到 ui.py
#ui.py
import bot
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.start_button = QPushButton("Start")
self.start_button.clicked.connect(self.run)
def run(self):
bot_process = Process(target=bot.runscript)
bot_process.daemon = True
bot_process.start()
实现这一目标的正确方法是什么?提前致谢。
解决方法
总的来说,Qt 不是进程安全,因此您不应从另一个进程更新 GUI。另一种方法是创建一个 QThread(或 threading.Thread),它只解析 Queue 的信息并发出带有信息的信号以更新 GUI。另一种选择是使用执行上述操作的 QTimer:监视队列。
class Worker(QObject):
messageChanged = Signal(str)
def monitoring(p,worker):
while True:
try:
msg = p.recv()
except EOFError:
break
else:
worker.messageChanged.emit(msg)
r,w = Pipe(duplex=False)
p = Process(target=foo,args=(w,))
worker = Worker()
worker.messageChanged.connect(self.some_slot)
threading.Thread(target=monitoring,args=(r,worker),daemon=True).start()
p.start()
但是使用多处理会增加不必要的复杂性,您可以使用 qasync
(python -m pip install qasync
) 然后使用 asyncio:
import asyncio
from functools import cached_property
import sys
import discord
from PySide6 import QtCore,QtWidgets
from qasync import QEventLoop,asyncSlot
class DiscordManager(QtCore.QObject):
connected = QtCore.Signal()
disconnected = QtCore.Signal()
messageChanged = QtCore.Signal(discord.message.Message)
def __init__(self,parent=None):
super().__init__(parent)
self.client.event(self.on_message)
self.client.event(self.on_connect)
self.client.event(self.on_disconnect)
@cached_property
def client(self):
return discord.Client()
async def on_message(self,message):
self.messageChanged.emit(message)
async def start(self):
await self.client.start(
"<TOKEN>"
)
async def close(self):
await self.client.close()
async def on_connect(self):
self.connected.emit()
async def on_disconnect(self):
self.disconnected.emit()
class MainWindow(QtWidgets.QMainWindow):
def __init__(self,parent=None):
super().__init__(parent)
self.button = QtWidgets.QPushButton("Start")
self.label = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)
central_widget = QtWidgets.QWidget()
lay = QtWidgets.QVBoxLayout(central_widget)
lay.addWidget(self.button)
lay.addWidget(self.label)
self.setCentralWidget(central_widget)
self.button.clicked.connect(self.handle_clicked)
self.manager.connected.connect(self.handle_connected)
self.manager.disconnected.connect(self.handle_disconnected)
self.manager.messageChanged.connect(self.handle_message)
@cached_property
def manager(self):
return DiscordManager()
@asyncSlot()
async def handle_clicked(self):
if self.button.text() == "Start":
await self.manager.start()
else:
await self.manager.close()
def handle_message(self,message):
self.label.setText(message.content)
def handle_connected(self):
self.button.setText("Stop")
def handle_disconnected(self):
self.button.setText("Start")
def main():
app = QtWidgets.QApplication(sys.argv)
loop = QEventLoop(app)
asyncio.set_event_loop(loop)
w = MainWindow()
w.show()
loop.run_forever()
if __name__ == "__main__":
main()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。