Почему мои ошибки из сигналов pyqt замораживают пользовательский интерфейс, пока не будет вызвана другая функция python - PullRequest
0 голосов
/ 15 января 2019

В Maya 2016 все хорошо. Но в Maya 2017 (после того, как я выполнил все преобразования pyqt), любая Ошибка, возникающая в функции, вызываемой из сигнала qt, не отображается сразу. Затем, если я запускаю другой код в редакторе сценариев, например «print 0», появляется ошибка предыдущей функции

Чтобы попробовать, просто запустите код и нажмите кнопку «ошибка».

Я пробовал это на Windows и Mac. Также попросил друга примерить его - и у него была такая же проблема. Опять же, в Maya 2016 все хорошо. Проблема возникает только в майя 2017

from PySide2 import QtWidgets, QtGui, QtCore
from shiboken2 import wrapInstance
import maya.OpenMayaUI as mui


mainWin = None

def showUI():
    global mainWin
    if mainWin != None:
        print "reloading UI..."
        mainWin.close()
    mainWin = myWindow()
    mainWin.show()


def getMayaWindow():
    ptr = mui.MQtUtil.mainWindow()
    return wrapInstance(long(ptr), QtWidgets.QWidget)


class myWindow(QtWidgets.QDialog):

    def __init__(self, parent=getMayaWindow()):

        super(myWindow, self).__init__(parent, QtCore.Qt.WindowStaysOnTopHint)

        def funcApply():
            oooo # this should error!

        self.layout = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.TopToBottom, self)
        self.testButton = QtWidgets.QPushButton('error')
        self.layout.addWidget(self.testButton)
        self.testButton.clicked.connect(funcApply)

showUI()

1 Ответ

0 голосов
/ 17 января 2019

Как я уже говорил в комментариях, я могу повторить вашу ошибку в 2017 и 2017 году, обновление 2, но прекрасно работает в 2018 году.

К счастью, есть достаточно простое решение, в котором вам просто нужно переместить свой метод из __init__, чтобы сделать его обычным методом экземпляра. Делать это сейчас ошибки, как ожидалось. (Честно говоря, наличие вложенной функции внутри __init__ все равно немного странно, я бы переместил ее независимо от ошибки)

Интересно, статические методы имеют ту же проблему! Если вы попытаетесь позвонить им из вашего класса, они будут висеть. Но если вы вызываете его из-за пределов класса, он работает нормально, или если вы заключаете все это в try except, теперь оно будет работать при вызове из класса.

Проверьте следующий код. Я включил 3 случая, экземплярный метод, статический метод и статический метод, заключенный в try except:

from PySide2 import QtWidgets, QtGui, QtCore
from shiboken2 import wrapInstance
import maya.OpenMayaUI as mui


mainWin = None


def showUI():
    global mainWin
    if mainWin != None:
        print "reloading UI..."
        mainWin.close()
    mainWin = myWindow()
    mainWin.show()


def getMayaWindow():
    ptr = mui.MQtUtil.mainWindow()
    return wrapInstance(long(ptr), QtWidgets.QWidget)


class myWindow(QtWidgets.QDialog):

    def __init__(self, parent=getMayaWindow()):

        super(myWindow, self).__init__(parent, QtCore.Qt.WindowStaysOnTopHint)

        # Works.
        self.testButton = QtWidgets.QPushButton('error')
        self.testButton.clicked.connect(self.funcApply)

        # Fails.
        self.testButton2 = QtWidgets.QPushButton('error static method')
        self.testButton2.clicked.connect(self.staticFuncApply)

        # Works.
        self.testButton3 = QtWidgets.QPushButton('error static method with try/except')
        self.testButton3.clicked.connect(self.staticTryExceptFuncApply)

        self.layout = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.TopToBottom, self)
        self.layout.addWidget(self.testButton)
        self.layout.addWidget(self.testButton2)
        self.layout.addWidget(self.testButton3)
        self.setLayout(self.layout)  # Normally need to specify what layout this widget needs to use.

    # Move this out and make it a normal instanced method.
    # This will work as expected.
    def funcApply(self):
        oooo # this should error!

    # Static methods still broken, but ok in Maya 2018.
    @staticmethod
    def staticFuncApply():
        oooo

    # Static methods wrapped with try except works.
    @staticmethod
    def staticTryExceptFuncApply():
        try:
            oooo
        except Exception as e:
            print e


showUI()

# myWindow.staticFuncApply()  # Calling static method outside of class works ok.

Все это работает в Maya 2018, но статический метод не удастся в 2017 году. Надеюсь, вы можете избежать использования статических методов, так как оборачивать все это в try except не практичное решение. Вы также можете попытаться обновить Maya до 2017 года с обновлением 4, чтобы проверить, исправлен ли он.

Надеюсь, это поможет!

...