PyQt5: проблемы с Mixin с метаклассом в производном классе QWidget

У меня возникают проблемы с попыткой добавить миксин с метаклассом в класс, основой которого является QWidget. Я знаю, что PyQt5 поддерживает совместное множественное наследование, и если мой класс MixIn имеет нет метакласса, тогда все работает нормально. Однако, если у него есть метакласс — будь то метакласс pyqtWrapperType, используемый QWidgets, или производный метакласс, я получаю следующую ошибку:

Process finished with exit code -1073741819 (0xC0000005)

Код остальной части сценария выполняется, но QWidget не отображается. Вот базовый код (без методов, так как я знаю, что они не нужны для решения проблемы)

import abc, sys
from PyQt5 import QtWidgets, QtCore

# Test Metaclass, will have more if metaclasses work
class MyMeta(abc.ABCMeta, QtCore.pyqtWrapperType):
    def __init__(cls, name, bases, attrs):
        super(MyMeta, cls).__init__(name, bases, attrs)

# MixIn class - ignore the calls to methods for now
# Have same issue if metaclass set to pyqtWrapperType
class LocatorWidget(metaclass=MyMeta):
    def __init__(self, locator=None, name='', parameters={}, **kwargs):
        super().__init__(**kwargs)
        # self.setup_parameters(parameters)
        self.locator = locator
        self.name = name if name else ''
        self.widgetType = self.__class__.__name__.replace('LW', '')
        # self.setup()

# Derived class with a QWidget base
class LWComboBox(QtWidgets.QComboBox, LocatorWidget):
    def __init__(self, locator, **kwargs):
        super().__init__(locator=locator, **kwargs)

def main():
    app = QtWidgets.QApplication(sys.argv)
    # locator is class in full code, using this as filler for now
    locator=[0,1,2,3]
    cb = LWComboBox(locator=locator)
    cb.addItems([str(x) for x in range(5)])
    # Test to see if attribute is set
    print(cb.locator)

    window = QtWidgets.QDialog()
    window.form = QtWidgets.QFormLayout()
    window.form.addRow(cb)
    window.setLayout(window.form)

    window.show()

if __name__ == '__main__':
    main()

У меня нет ошибки конфликта метаклассов: базовый класс и производные классы не имеют разных метаклассов, поскольку MyMeta является производным от pyqtWrapperType.

Если этот процесс не работает, мне интересно, следует ли мне придерживаться моей предыдущей идеи, которая заключалась в том, чтобы окутывать виджет атрибутами и методами, которыми я хочу поделиться, в отдельном классе, причем виджет является одним из атрибутов, но он было бы хорошо создать подклассы QWidgets напрямую с необходимыми абстрактными методами и атрибутами.

К вашему сведению, я запускаю PyCharm 2016.2.3 в Anaconda с PyQt5 версии 5.6 (PyQt не может быть обновлен до более поздних версий в Anaconda)


person Bill3000    schedule 15.03.2017    source источник


Ответы (1)


pyqtWrapperType больше не существует. Если вам нужен эквивалентный тип в PyQt5, вы можете использовать:

pyqtWrapperType = type(QtCore.QObject)

or:

from sip import wrappertype as pyqtWrapperType
person ekhumoro    schedule 16.03.2017
comment
У меня не было проблемы, что pyqtWrapperType не существует; быстрая проверка показывает, что у меня нет последней версии PyQt5. (У меня есть Anaconda и PyQt5 v 5.60). Я обновлю и применю ваше исправление и посмотрю, что произойдет, но изменение pyqtWrapperType на type(QtCore.QObject) в моей версии, похоже, не решило проблему. - person Bill3000; 16.03.2017
comment
После исправления нескольких несвязанных ошибок в вашем примере я обнаружил, что он отлично работает для меня при использовании предложенных мной изменений. - person ekhumoro; 16.03.2017
comment
Какую версию PyQt вы используете? Согласно [python .6.x6.nabble.com/, pyqtWrapperType был удален в PyQt 5.7 и по-прежнему доступен в 5.6. Anaconda (которую я использую) [github.com/ContinuumIO/anaconda-issues/ Issues/1023]( не поддерживает PyQt 5.7). Является ли это проблемой версии, когда мне придется вручную обновляться до 5.7? Когда я делаю type(QObject), он возвращает pyqtWrapperType для меня в PyQt 5.6. - person Bill3000; 17.03.2017
comment
FWIW, я использую PyQt-5.8. Не могли бы вы запустить пример в консоли и получить правильную трассировку? Сообщение об ошибке в вашем вопросе совершенно бесполезно и не имеет ничего общего с Python или PyQt. - person ekhumoro; 17.03.2017
comment
Я запустил его в консоли vanilla python (а также в QtConsole), и он вылетает в той же строке: cb = LWComboBox(locator=locator - это не связано с конкретной ошибкой. На обычной консоли падает сам python.exe с сообщением об ошибке An unhandled win32 exception occured in python.exe [8972]. В Jupyter QtConsole ядро ​​просто падает без сообщения об ошибке. Это работает, если вместо этого я сделаю cb QComboBox. Я включил использование type(QtCore.QObject) для метакласса. - person Bill3000; 20.03.2017
comment
@ Билл3000. С какой версией PyQt5 вы тестировали и откуда вы ее установили? - person ekhumoro; 20.03.2017