我很忙! 发表于 2024-9-1 23:11

跪求,,,pyqt5 协程调用模块下载功能 界面无响应(已附源码)

本帖最后由 我很忙! 于 2024-9-7 16:04 编辑

pyqt5界面 调用模块的协程下载文件,代码正常跑,但是界面卡死无响应,下载完了,才恢复不卡,在pyqt界面块写协程,始终调用不到模块的的代码,没执行到,都跳过了,没进入到模块,

问了豆包几个小时,始终无法解决,无法正常调用模块

两种方法都试过了,要么能调用无响应,要么无法调用模块,但是也不会卡死


pyqt界面代码

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QLineEdit, QWidget, QLabel
from PyQt5.QtCore import QEventLoop
import asyncio
from count_module import count_to_number

class MainWindow(QMainWindow):
    def __init__(self):
      super().__init__()
      self.setWindowTitle("计数 PyQt 界面")
      layout = QVBoxLayout()

      self.input_label = QLabel("请输入数字:")
      self.line_edit = QLineEdit()
      self.start_button = QPushButton("开始计数")
      self.status_label = QLabel("状态:等待输入并点击开始计数。")

      self.start_button.clicked.connect(self.launch_counting)

      layout.addWidget(self.input_label)
      layout.addWidget(self.line_edit)
      layout.addSpacing(20)
      layout.addWidget(self.start_button)
      layout.addWidget(self.status_label)

      central_widget = QWidget()
      central_widget.setLayout(layout)
      self.setCentralWidget(central_widget)

    def launch_counting(self):
      text = self.line_edit.text()
      if text:
            number = int(text)
            self.status_label.setText("状态:正在计数...")
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            async def run_counting():
                await self.do_counting(number)
            loop.run_until_complete(run_counting())
            # 重置事件循环,避免潜在问题
            asyncio.set_event_loop(None)
      else:
            self.status_label.setText("状态:请输入有效的数字。")

    async def do_counting(self, number):
      await count_to_number(number)
      self.status_label.setText("状态:计数完成。")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

模块代码

import asyncio

async def count_to_number(number):
    print(number)
    for i in range(1, number + 1):
      print(i)
      await asyncio.sleep(1)

MarioCrane 发表于 2024-9-1 23:46

代码也不贴,只能给你算一卦了。下载的逻辑跑在了主线程,所有界面会卡住。

我很忙! 发表于 2024-9-2 00:50

MarioCrane 发表于 2024-9-1 23:46
代码也不贴,只能给你算一卦了。下载的逻辑跑在了主线程,所有界面会卡住。

不好意思,补上了,大概就是这样,pyqt主程序,调用了模块,模块可以正常走但是主页面窗口在模块代码没执行完之前一直都是无响应,

asd124689 发表于 2024-9-2 07:14

子线程 下载,完事后发送信号修改界面

bester 发表于 2024-9-2 08:28

Pyqt多线程/异步不可以直接操作界面,修改主线程界面的内容,需要通过信号

Do_zh 发表于 2024-9-2 08:45

用这个玩意。pyqtSignal

whitegold 发表于 2024-9-2 09:21

学习一下Pyqt多线程/异步

wangykwang 发表于 2024-9-2 09:54

继承 QThread 异步处理

15126819695 发表于 2024-9-2 14:14

没有使用多线程QT的多线程还是的得用Qthread

QvQsuipian 发表于 2024-9-4 19:43

主要改动说明
新建 CountingThread 类:

这个类继承自QThread,负责在单独的线程中执行计数操作。
使用 pyqtSignal 信号来更新UI状态。
异步方法:

在 CountingThread 中实现了 do_counting 方法,该方法中调用了你原来的 count_to_number 协程。
线程管理:

启动 CountingThread 并连接它的信号到主窗口的方法,以便在计数完成后更新UI。
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QLineEdit, QWidget, QLabel
from PyQt5.QtCore import QThread, pyqtSignal
import asyncio
from count_module import count_to_number

class CountingThread(QThread):
    update_status = pyqtSignal(str)

    def __init__(self, number):
      super().__init__()
      self.number = number

    async def do_counting(self):
      await count_to_number(self.number)
      self.update_status.emit("状态:计数完成。")

    def run(self):
      loop = asyncio.new_event_loop()
      asyncio.set_event_loop(loop)
      loop.run_until_complete(self.do_counting())
      # 结束事件循环
      loop.close()

class MainWindow(QMainWindow):
    def __init__(self):
      super().__init__()
      self.setWindowTitle("计数 PyQt 界面")
      layout = QVBoxLayout()

      self.input_label = QLabel("请输入数字:")
      self.line_edit = QLineEdit()
      self.start_button = QPushButton("开始计数")
      self.status_label = QLabel("状态:等待输入并点击开始计数。")

      self.start_button.clicked.connect(self.launch_counting)

      layout.addWidget(self.input_label)
      layout.addWidget(self.line_edit)
      layout.addSpacing(20)
      layout.addWidget(self.start_button)
      layout.addWidget(self.status_label)

      central_widget = QWidget()
      central_widget.setLayout(layout)
      self.setCentralWidget(central_widget)

    def launch_counting(self):
      text = self.line_edit.text()
      if text:
            try:
                number = int(text)
                self.status_label.setText("状态:正在计数...")

                # 创建并启动线程
                self.thread = CountingThread(number)
                self.thread.update_status.connect(self.update_status)
                self.thread.start()
            except ValueError:
                self.status_label.setText("状态:请输入有效的数字。")
      else:
            self.status_label.setText("状态:请输入有效的数字。")

    def update_status(self, message):
      self.status_label.setText(message)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())
页: [1]
查看完整版本: 跪求,,,pyqt5 协程调用模块下载功能 界面无响应(已附源码)