PyQt5 中线程应用程序中的信息错误对话管理

我是 GUI 编程的新手,需要有关 QThread 应用程序的帮助。我有一个 gui 程序,可以进行查询并在屏幕上列出查询的结果。我希望在屏幕上的列表完成后打开一个信息对话框。我为此编写了一个函数,当操作成功时,它可以正常工作。但是我无法弄清楚如果出现无效链接条目时如何显示错误对话框。感谢您的帮助。

-我已经注释掉了一些我尝试过但失败的方法。

import sys
import requests
from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtCore import QThread
from PyQt5.QtWidgets import QMainWindow,QApplication,QMessageBox
from bs4 import BeautifulSoup
from time import sleep


class Ui_MainWindow(object):
    def setupUi(self,MainWindow):
        MainWindow.setobjectname("MainWindow")
        MainWindow.resize(476,391)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setobjectname("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(0,270,471,81))
        self.pushButton.setobjectname("pushButton")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(0,31))
        self.lineEdit.setobjectname("lineEdit")
        self.listWidget = QtWidgets.QListWidget(self.centralwidget)
        self.listWidget.setGeometry(QtCore.QRect(0,50,192))
        self.listWidget.setobjectname("listWidget")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0,476,21))
        self.menubar.setobjectname("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setobjectname("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.running = False
        self.pushButton.clicked.connect(self.startBs4Worker)

    def retranslateUi(self,MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow","MainWindow"))
        self.pushButton.setText(_translate("MainWindow","GET"))

    def reveiceData(self,data):
        # This method is the method that will 
        # process the data sent by the thread.
        if data == None:
            return

        _translate = QtCore.QCoreApplication.translate
        item = QtWidgets.QListWidgetItem()
        font = QtGui.QFont()
        font.setfamily("Arial")
        font.setPointSize(11)
        item.setfont(font)
        item.setCheckState(QtCore.Qt.Checked)
        item.setText(_translate("MainWindow",data))
        self.listWidget.addItem(item)

    def setThreadStatus(self):
        self.running = not self.running

    def startBs4Worker(self):
        if self.running:
            print("Thread is still running ...")
            return
        else:
            self.thread = QThread()

            # We send the URL address that the thread will process as a parameter.
            self.worker = Bs4Worker(url=self.lineEdit.text())

            self.worker.moveToThread(self.thread)
            self.thread.started.connect(self.worker.run)
            self.worker.finished.connect(self.thread.quit)
            self.worker.finished.connect(self.worker.deleteLater)
            self.worker.finished.connect(self.setThreadStatus)
            self.thread.finished.connect(self.thread.deleteLater)
            self.worker.notifyProgress.connect(self.reveiceData)
            self.worker.finished.connect(self.uyariBox) #---> With this place active,I couldn't figure out how to activate the Error message when wrong connection was entered.
            self.running = True
            self.thread.start()


    def uyariBox(self):
        self.msg = QMessageBox()
        self.msg.thread()
        self.msg.setWindowTitle("Bilgi !")
        self.msg.setText("Tüm Sonuçlar Getirildi")
        self.msg.setIcon(QMessageBox.Information)
        self.msg.exec_()



class Bs4Worker(QThread):
    notifyProgress = QtCore.pyqtSignal(str)

    def __init__(self,url,parent=None):
        QThread.__init__(self,parent)
        self.url = url

    def run(self):
        try:
            r = requests.get(self.url)
            soup = BeautifulSoup(r.content)
            linkler = soup.find_all("a")
            for link in linkler:
                baslik = link.get("title")

                # Sending header information to master class
                self.notifyProgress.emit(baslik)
            self.finished.connect(ui.uyariBox) #---> When you activate this place,the warning appears instantly and disappears immediately.
                                               #--->  and there is no click anywhere in the app. (Since completion is not pressed in the warning message)

            self.finished.emit()

           # self.finished.connect(ui.uyariBox) #----> Warning does not appear when you activate this place.


        except:

            print("link error")
            self.finished.emit()
            # When I create a new QMessageBox to show the error message,the application crashes.
    
Uygulama = QApplication(sys.argv)
menu = QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(menu)
menu.show()
sys.exit(Uygulama.exec_())
xyxocaz 回答:PyQt5 中线程应用程序中的信息错误对话管理

您可以将运算结果作为字符串传递给 uyariBox 方法。

首先,您可以在 Bs4Worker 中创建另一个信号:

class Bs4Worker(QThread):
    result = QtCore.pyqtSignal(str)

将之前的 worker.finished 连接更改为 worker.result

def startBs4Worker(self):
    else:
         self.worker.result.connect(self.uyariBox)
         #Previous was self.worker.finished.connect(self.uyariBox)

向函数添加变量:

def uyariBox(self,message):
    self.msg = QMessageBox()
    self.msg.thread()
    self.msg.setWindowTitle("Bilgi !")
    self.msg.setText(message)
    self.msg.setIcon(QMessageBox.Information)
    self.msg.exec_()

然后使用信号传递操作的结果:

    def run(self):
        try:
            self.result.emit("Tüm Sonuçlar Getirildi")
        except Exception as e:
            self.result.emit(f"Error: {e}")

完整代码:

import sys
import requests
from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtCore import QThread,pyqtSignal
from PyQt5.QtWidgets import QMainWindow,QApplication,QMessageBox
from bs4 import BeautifulSoup
from time import sleep


class Ui_MainWindow(object):
    def setupUi(self,MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(476,391)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(0,270,471,81))
        self.pushButton.setObjectName("pushButton")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(0,31))
        self.lineEdit.setObjectName("lineEdit")
        self.listWidget = QtWidgets.QListWidget(self.centralwidget)
        self.listWidget.setGeometry(QtCore.QRect(0,50,192))
        self.listWidget.setObjectName("listWidget")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0,476,21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.running = False
        self.pushButton.clicked.connect(self.startBs4Worker)

    def retranslateUi(self,MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow","MainWindow"))
        self.pushButton.setText(_translate("MainWindow","GET"))

    def reveiceData(self,data):
        # This method is the method that will
        # process the data sent by the thread.
        if data == None:
            return

        _translate = QtCore.QCoreApplication.translate
        item = QtWidgets.QListWidgetItem()
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(11)
        item.setFont(font)
        item.setCheckState(QtCore.Qt.Checked)
        item.setText(_translate("MainWindow",data))
        self.listWidget.addItem(item)

    def setThreadStatus(self):
        self.running = not self.running

    def startBs4Worker(self):
        if self.running:
            print("Thread is still running ...")
            return
        else:
            self.thread = QThread()

            # We send the URL address that the thread will process as a parameter.
            self.worker = Bs4Worker(url=self.lineEdit.text())

            self.worker.moveToThread(self.thread)
            self.thread.started.connect(self.worker.run)
            self.worker.finished.connect(self.thread.quit)
            self.worker.finished.connect(self.worker.deleteLater)
            self.worker.finished.connect(self.setThreadStatus)
            self.thread.finished.connect(self.thread.deleteLater)
            self.worker.notifyProgress.connect(self.reveiceData)
            self.worker.result.connect(
                self.uyariBox)  # ---> With this place active,I couldn't figure out how to activate the Error message when wrong connection was entered.
            self.running = True
            self.thread.start()

    def uyariBox(self,message):
        self.msg = QMessageBox()
        self.msg.thread()
        self.msg.setWindowTitle("Bilgi !")
        self.msg.setText(message)
        self.msg.setIcon(QMessageBox.Information)
        self.msg.exec_()


class Bs4Worker(QThread):
    result = QtCore.pyqtSignal(str)
    notifyProgress = QtCore.pyqtSignal(str)

    def __init__(self,url,parent=None):
        QThread.__init__(self,parent)
        self.url = url

    def run(self):
        try:
            r = requests.get(self.url)
            soup = BeautifulSoup(r.content)
            linkler = soup.find_all("a")
            for link in linkler:
                baslik = link.get("title")

                # Sending header information to master class
                self.notifyProgress.emit(baslik)
            self.finished.connect(
                ui.uyariBox)  # ---> When you activate this place,the warning appears instantly and disappears immediately.
            # --->  and there is no click anywhere in the app. (Since completion is not pressed in the warning message)

            self.finished.emit()
            self.result.emit("Tüm Sonuçlar Getirildi")
        # self.finished.connect(ui.uyariBox) #----> Warning does not appear when you activate this place.

        except Exception as e:

            print("link error")
            self.finished.emit()
            self.result.emit(f"Error: {e}")
            # When I create a new QMessageBox to show the error message,the application crashes.


Uygulama = QApplication(sys.argv)
menu = QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(menu)
menu.show()
sys.exit(Uygulama.exec_())
本文链接:https://www.f2er.com/908955.html

大家都在问