Передача исключения в слот при передаче сигнала

#qt #pyqt #pyside #signals-slots

#qt #pyqt #pyside #сигналы-слоты

Вопрос:

Я должен передать исключение, возникшее в одной функции, в слот внутри другого класса.

 _qObject = QtCore.QObject()

except Exception, ex:
    QtCore.QObject.emit(_qObject, QtCore.SIGNAL("error_occured"))
  

Я хочу передать ex классу, который имеет

 QtCore.QObject.connect(_qObject, QtCore.SIGNAL("error_occured"), self.__errorOccured)
  

Это мой случай

 from PyQt4.QtCore import pyqtSignal, pyqtSlot
from PyQt4.QtGui import QWidget, QApplication

has_error = pyqtSignal(Exception)

class SomeOtherClass(QWidget):

    # this is my UI class
    def __init__(self, parent=None):
        super(SomeOtherClass, self).__init__(parent)

        # Initialise the Class and connect signal to slot
        has_error.connect(self.thrown_error)


    @pyqtSlot(Exception)
    def thrown_error(self, my_err):
        #Do Stuff with the Exception
        print(type(my_err), my_err)
        self.close()


def makeError():
    try:
        print 1/0
    except ZeroDivisionError, ze:
        has_error.emit(ze)

app = QApplication([])
SomeOtherClass()
  

Ответ №1:

Смотрите, например, приведенный ниже код:

 from PyQt4.QtCore import pyqtSignal, pyqtSlot
from PyQt4.QtGui import QWidget, QApplication
import sys    

class SomeClass(QWidget):
    # Declare a new signal - passes Exception
    has_error = pyqtSignal(Exception)

    def __init__(self, parent=None):
        super(SomeClass, self).__init__(parent)

    def run_something(self):
        #Force an Error
        try:
            1 / 0
        except ZeroDivisionError as ze:
            #Emit the Signal
            self.has_error.emit(ze)


class SomeOtherClass(QWidget):
    def __init__(self, parent=None):
        super(SomeOtherClass, self).__init__(parent)

        # Initialise the Class and connect signal to slot
        class1 = SomeClass()
        class1.has_error.connect(self.thrown_error)
        class1.run_something()

    @pyqtSlot(Exception)
    def thrown_error(self, my_err):
        #Do Stuff with the Exception
        print(type(my_err), my_err)


app = QApplication(sys.argv)
SomeOtherClass()
  

Смотрите новый способ подключения сигналов к слотам

Комментарии:

1. что @pyqtSlot(Exception) делает вышеуказанный thrown_error(...) метод

2. @pyqtSlot() является декоратором и Exception является типом. Он объявляет этот метод как слот, чтобы Qt не связывал его дважды. Пожалуйста, ознакомьтесь с документацией, которую я привел в нижней части моего примера.

3. также SomeClass() в моем случае у меня нет просто функции на уровне модуля.

4. В этом случае вам не нужен механизм сигнала / слотов. просто вызовите SomeClass.some_method(my_err) свой try...except блок

5. Или поместите a class вокруг вашей функции и используйте приведенный выше пример.

Ответ №2:

То, что предложил Shadow9043, тоже верно, но в комментариях все было искажено, но это то, что я нашел правильным и упрощенным подходом.

Короче говоря, длинная история!!!

 except Exception, ex:
    QtCore.QObject.emit(_qObject, QtCore.SIGNAL("error_occured"), str(ex))
  

и в классе, к которому я подключаю это исключение

я приму эту строку ex в качестве аргумента

 def __errorOccured(self, exStr):
    print exStr
  

Вот как у меня это работает, если у кого-то есть лучшее предложение о том, как я этого добился, пожалуйста, прокомментируйте.

 from PyQt4.QtCore import pyqtSignal, pyqtSlot
from PyQt4.QtGui import QWidget, QApplication
from PyQt4 import QtCore
import sys

_qObject = QtCore.QObject()


class SomeOtherClass(QWidget):

    # this is my UI class

    def __init__(self, parent=None):
        super(SomeOtherClass, self).__init__(parent)

        # Initialise the Class and connect signal to slot
        QtCore.QObject.connect(_qObject, QtCore.SIGNAL("error_occured"), self.thrown_error)


    def thrown_error(self, my_err):
        #Do Stuff with the Exception
        print(type(my_err), my_err)


def makeError():
    try:
        print 1/0
    except ZeroDivisionError, ex:
        QtCore.QObject.emit(_qObject, QtCore.SIGNAL("error_occured"), str(ex))

app = QApplication(sys.argv)
win = SomeOtherClass()
makeError()
win.show()
sys.exit(app.exec_())