GUI 在循环时变得无响应

2023-12-07

单击按钮后,表单将变得无响应,直到解析函数完成其工作。

我想将 searchAll 函数移至线程。我确实阅读了类似问题的几个答案,但我不明白如何。

class MyForm(QDialog):


    def __init__(self):
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.ui.buttonOK.clicked.connect(self.searchAll)
        self.show()

    def searchAll(self):

        sID = self.ui.txtSellerID.text()
        sUrl = "https://removed.com/" + sID + "/p/?section=2&page=1"
        sr = requests.get(sUrl)
        soup1 = BeautifulSoup(sr.text, "html.parser")

        NumberOfPagesBlock = soup1.find_all("li", class_="text-gray")

        if not NumberOfPagesBlock:
            QMessageBox.about(self, "Warning", "Nothing Here")
        else:
            items = re.compile(r'[^\d.]+')
            PagesCount = -(-items // 60)

            for i in range(1, int(PagesCount + 1)):
                itemsIdDs = soup1.find_all("div", class_="large-single-item")

                for itemsIdD in itemsIdDs:
                    iUrl = ("https://removed.com/" + itemsIdDs.get('data-ean') + "/s")
                    r = requests.get(iUrl)
                    soup = BeautifulSoup(r.text, "html.parser")
                    seller = soup.find("div", id="productTrackingParams")
                    title = (str(ctr) + '- ' + "Title " + str(seller.get('data-title')))
                    self.ui.txtDetails.appendPlainText(title)


if __name__ == "__main__":

    app = QApplication(sys.argv)
    w = MyForm()
    w.show()
    sys.exit(app.exec_())

您必须在另一个线程中执行繁重的任务(请求+ BeautifulSoup),因为它们会阻塞 GUI 所在的主线程,从而阻止 GUI 正常工作,例如,通过冻结屏幕来体现这一点。在这种情况下,我将实现工作线程方法:

import re
import ssl
import sys
from functools import partial

import requests
from PyQt5.QtCore import QObject, QThread, QTimer, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox
from bs4 import BeautifulSoup

from foo_module import Ui_Dialog


class ScrapeWorker(QObject):
    started = pyqtSignal()
    finished = pyqtSignal()
    resultsChanged = pyqtSignal(str)
    errorSignal = pyqtSignal(str)

    @pyqtSlot(str)
    def run(self, text):
        self.started.emit()
        sUrl = "https://removed.com/{}/p/?section=2&page=1".format(text)
        try:
            sr = requests.get(sUrl)
        except Exception as e:
            self.errorSignal.emit("error: {}".format(e))
            self.finished.emit()
            return
        soup1 = BeautifulSoup(sr.text, "html.parser")
        NumberOfPagesBlock = soup1.find_all("li", class_="text-gray")
        if not NumberOfPagesBlock:
            self.errorSignal.emit("Nothing Here")
        else:
            items = re.compile(r"[^\d.]+")
            PagesCount = -(-items // 60)
            for i in range(1, int(PagesCount + 1)):
                itemsIdDs = soup1.find_all("div", class_="large-single-item")

                for itemsIdD in itemsIdDs:
                    iUrl = "https://removed.com/{}/s".format(itemsIdDs.get("data-ean"))
                    r = requests.get(iUrl)
                    soup = BeautifulSoup(r.text, "html.parser")
                    seller = soup.find("div", id="productTrackingParams")
                    title = "{}- Title {}".format(ctr, seller.get("data-title"))
                    self.resultsChanged.emit(title)
        self.finished.emit()


class MyForm(QDialog):
    def __init__(self):
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.ui.buttonOK.clicked.connect(self.searchAll)

        thread = QThread(self)
        thread.start()

        self.m_worker = ScrapeWorker()
        self.m_worker.moveToThread(thread)
        self.m_worker.started.connect(self.onStarted)
        self.m_worker.finished.connect(self.onFinished)
        self.m_worker.resultsChanged.connect(self.onResultChanged)
        self.m_worker.errorSignal.connect(self.onErrorSignal)

    @pyqtSlot()
    def searchAll(self):
        sID = self.ui.txtSellerID.text()
        wrapper = partial(self.m_worker.run, sID)
        QTimer.singleShot(0, wrapper)

    @pyqtSlot(str)
    def onResultChanged(self, title):
        self.ui.txtDetails.appendPlainText(title)

    @pyqtSlot()
    def onStarted(self):
        self.ui.buttonOK.setEnabled(False)

    @pyqtSlot()
    def onFinished(self):
        self.ui.buttonOK.setEnabled(True)

    @pyqtSlot(str)
    def onErrorSignal(self, message):
        QMessageBox.about(self, "Warning", message)


if __name__ == "__main__":

    app = QApplication(sys.argv)
    w = MyForm()
    w.show()
    sys.exit(app.exec_())
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GUI 在循环时变得无响应 的相关文章

随机推荐

  • PyQt6:如何在 QImageReader 中设置分配限制?

    我正在将应用程序从 PyQt5 更新到 PyQt6 该应用程序使用非常大的图像文件 我已经更新了代码以使用 PyQt6 但是 当我运行 Python 脚本时 我现在收到错误 QImageIOHandler 拒绝图像 因为它超出了当前分配 限
  • 如何在laravel中使用createMany方法插入多条记录

    我想使用 createMany 创建多记录 如何在没有数据复制的情况下将数组插入到此方法 public function update Request request Question question options request gt
  • 将嵌入引号的 csv 文件读取到 R 中

    我必须使用如下所示的 csv 文件 IDEA ID IDEA TITLE VOTE VALUE 56144 Net Present Value PLUS NPV 1 56144 Net Present Value PLUS NPV 1 如果
  • cakephp 表单验证

    有谁知道 cakePHP 中的表单是否有 VALIDATE 函数并查看错误数组 我检查了文档 但我发现的唯一东西是 SAVE 功能 我只需要知道我发送的数据是否有效并手动检查错误 Try this this gt ModelName gt
  • 在函数调用的同一行获取哈希键/值

    这是重现问题的代码 sub hello return h gt 1 n gt 1 print join values hello 我收到错误 arg 1 到值的类型必须是散列 不是子程序入口 在 第 4 行 靠近 执行 由于中止 到编译错误
  • MVVM:绑定一个 ViewModel,它将构造函数参数传递给 UserControl

    我的 WPF 应用程序有一个 MainWindow 其中包含一个名为 Tvshow GridView 的用户控件 主窗口
  • 多维 std::array [重复]

    这个问题在这里已经有答案了 在C 中 如何创建多维std array 我试过这个 std array
  • 如何创建“动态”WHERE 子句?

    第一 谢谢 我完成了我的另一个项目 并得到了很大的惊喜 现在一切都按预期进行 感谢一些有帮助的思想家 所以我开始下一个项目 我想要得到这样的东西 SELECT FROM tablename WHERE field1 content AND
  • 通过传递输出迭代器从函数填充 std::[container]

    我想通过传递输出迭代器从函数内部填充容器 因为据我所知 这是最有效的方法 例如 template
  • SDL 事件处理不起作用

    我目前正在通过阅读 Lazy foo 教程来学习 SDL 我在 Linux 上使用代码块 13 12 我无法使事件处理正常工作 我基本上是在尝试显示图像 效果很好 但无论我单击关闭按钮多少次 它都不会关闭 Code include
  • 比较向量值:1 个元素与所有其他元素

    我想知道如何将向量的 1 个元素与另一个向量中的所有元素进行比较 举个例子 假设 x lt c 1 10 y lt c 10 11 12 13 14 1 7 现在我可以逐个比较元素 x y 1 FALSE FALSE FALSE FALSE
  • 计算集合列表中所有组合的交集

    我有一套集合 我想找到仅在每个集合组合的交集中找到的项目数 我基本上想做与在维恩图中创建数字相同的事情 一个基本的例子可能会更清楚 a set 1 2 5 10 12 b set 1 2 6 9 12 15 c set 1 2 7 8 15
  • 如何分割 Tensorflow 数据集?

    我有一个基于一个 tfrecord 文件的张量流数据集 如何将数据集拆分为测试数据集和训练数据集 例如 70 训练 30 测试 Edit 我的张量流版本 1 8 我已经检查过 没有可能的重复项中提到的 split v 函数 我也在使用 tf
  • Angular 2 - 如何有条件地向我的组件添加样式?

    我有一个带有样式表的组件 可以正确加载 如下所示 Component selector open account styleUrls open account component scss templateUrl open account
  • 如何从不同的模型/控制器渲染局部视图?

    我有以下名为 Categories 的部分视图 位于 Views Category Categories 中 model IEnumerable
  • 如何将运行lwuit的j2me转换为android?

    如何将使用 lwuit 库的 J2ME 应用程序转换为 Android apk 我尝试使用 mircoemulator 进行转换 但是当我启动应用程序时 它显示错误并退出 读这篇文章 适用于 Android 的 LWUIT 这里清楚地讲述了
  • ggplot2中仅显示一个文本值

    我试图将文本打印限制为条形图中的一个变量 我怎样才能只标记粉红色的条601 215 399 456 ggplot df aes Var1 value label value fill Var2 geom bar stat identity
  • cassandra 2.2 CQl Shell 支持 python 2.7

    尝试启动 cql Shell 时出现错误 gt cqlsh CQL Shell supports only Python 2 7 gt 我已经安装了python2 7但它仍然给出相同的错误 我必须设置一些路径吗 我已经使用此命令从 data
  • Python - 使用 pandas 多重处理多个大尺寸文件

    我有一个y csv文件 文件大小为 10 MB 包含来自Jan 2020 to May 2020 我每个月还有一个单独的文件 例如data 2020 01 csv 它包含详细的数据 每个月文件的文件大小约为1 GB 我正在分割y csv按月
  • GUI 在循环时变得无响应

    单击按钮后 表单将变得无响应 直到解析函数完成其工作 我想将 searchAll 函数移至线程 我确实阅读了类似问题的几个答案 但我不明白如何 class MyForm QDialog def init self super init se