Как унаследовать QtWidgets.QWidget в моем классе и сделать тип моего класса - QtWidgets.QWidget? - PullRequest
1 голос
/ 31 марта 2019

Я пытаюсь сделать некоторый код на Maya, извините, если это вызовет путаницу в моем примере скрипта ниже. Проблема в том, что я хочу создать свой собственный класс PyQt, который позже будет использоваться как Widget в моем макете, но мое отсутствие знаний в этой области вызывает ошибку

# RuntimeError: '__init__' method of object's base class (test) not called. # 

Я прочитал несколько тем об этой ошибке, и люди предлагают исправить ее с помощью super (). Я попытался поставить "super ()", затем я получаю эту ошибку:

# TypeError: PySide2.QtCore.QObject isn't a direct base class of test #

Может кто-нибудь прояснить это для меня?

from PySide2 import QtGui, QtCore, QtWidgets
from shiboken2 import wrapInstance
import maya.OpenMaya as om
import maya.OpenMayaUI as omui
import maya.cmds as cmds
import os, functools


def getMayaWindow():
    pointer = omui.MQtUtil.mainWindow()
    if pointer is not None:
        return wrapInstance(long(pointer), QtWidgets.QWidget)

class testUi():
    def __init__(self):
        self.window = 'vl_test'
        self.title = 'Test Remastered'
        self.size = (1000, 650)

    def create(self):
        if cmds.window(self.window, exists=True):
            cmds.deleteUI(self.window, window=True)

        self.parentWindow = getMayaWindow()
        self.mainWindow = QtWidgets.QMainWindow(self.parentWindow)
        self.mainWindow.setObjectName(self.window)
        self.mainWindow.setWindowTitle(self.title)

        self.mainWidget = QtWidgets.QWidget()
        self.mainWindow.setCentralWidget(self.mainWidget)
        self.mainLayout = QtWidgets.QFormLayout(self.mainWidget)
        testik = test(self)
        self.mainLayout.addWidget(testik)

        self.mainButton = QtWidgets.QPushButton()
        self.mainLayout.addWidget(self.mainButton)
        self.mainButton.clicked.connect(partial(self.load_selected))


class test(QtWidgets.QWidget):
    def __init__(self, parent=None, maya_transform_nodes=[]):
        #super(QtWidgets.QWidget, self ).__init__(parent)
        qWid = QtWidgets.QWidget()
        self.setMinW = qWid.setMinimumWidth(300)
        self.setMinH = qWid.setMinimumHeight(300)
        self.sss = qWid.setStyleSheet("border:1px solid rgb(0, 255, 0); ")
        self.items = []

        self.transform_move = QtGui.QTransform()
        self.transform_scale = QtGui.QTransform()

        self.prev_mouse_pos = QtCore.QPoint(0, 0)

        self.color = QtGui.QColor(0, 255, 50, 50)
        self.clicked_color = QtGui.QColor(0, 255, 50, 150)
        self.right_clicked_color = QtGui.QColor(255, 0, 0, 150)

v = testUi()
v.create()

1 Ответ

2 голосов
/ 31 марта 2019

Когда вы создаете класс, у вас есть возможность наследовать от другого объекта, в этом случае, вероятно, QDialog, так как это главное окно вашего инструмента. Однако недостаточно просто наследовать его, вам нужно вызвать конструктор QDialog, чтобы он правильно инициализировался, и вы можете сделать это с помощью super.

С помощью super вы можете запускать метод из объекта вашего класса, от которого он унаследован. Это будет выглядеть примерно так: super(YOUR_CLASS_NAME, INSTANCE).METHOD_TO_RUN(PARAMETERS_TO_PASS). Так что более конкретно для запуска вашего __init__ это будет: super(testUi, self).__init__(parent), и это все исправит.

Вероятно, это было ужасное объяснение, поэтому, пожалуйста, Google super для более качественных примеров.

Я внес некоторые изменения в ваш скрипт, чтобы упростить его, и оставил в нем несколько комментариев:

from PySide2 import QtGui, QtCore, QtWidgets
from shiboken2 import wrapInstance
import maya.OpenMaya as om
import maya.OpenMayaUI as omui
import maya.cmds as cmds
import os, functools


def getMayaWindow():
    pointer = omui.MQtUtil.mainWindow()
    if pointer is not None:
        return wrapInstance(long(pointer), QtWidgets.QWidget)


class testUi(QtWidgets.QDialog):  # Need to inherit from a `QObject`

    def __init__(self, parent=None):  # It's typical to include the `parent` parameter and pass that through `super`.
        # If nothing was passed for parent, default to Maya's main window.
        if parent is None:
            parent = getMayaWindow()

        super(testUi, self).__init__(parent)  # Call `super` with the class's name, testUi, and its instance, self.
        self.window = 'vl_test'
        self.title = 'Test Remastered'
        self.size = (1000, 650)

        self.create()  # Just automatically call create in the instance's constructor.

    def create(self):
        if cmds.window(self.window, exists=True):
            cmds.deleteUI(self.window, window=True)

        self.setWindowTitle(self.title)
        self.resize(QtCore.QSize(*self.size))

        self.testik = test(self)  # Add `self.` so it belongs to this instance.

        self.mainButton = QtWidgets.QPushButton()

        self.mainLayout = QtWidgets.QVBoxLayout()  # QVBoxLayout seems to give a better result.
        self.mainLayout.addWidget(self.testik)
        self.mainLayout.addWidget(self.mainButton)
        self.setLayout(self.mainLayout)  # Don't forget to make this widget actually set to this layout and use it.


class test(QtWidgets.QFrame):

    def __init__(self, parent=None, maya_transform_nodes=[]):
        super(test, self).__init__(parent)  # Call `super` with the class's name, test, and its instance, self.

        self.setMinimumWidth(300)
        self.setMinimumHeight(300)
        self.setStyleSheet("QWidget {border: 1px solid rgb(0, 255, 0)};")

        self.items = []

        self.transform_move = QtGui.QTransform()
        self.transform_scale = QtGui.QTransform()

        self.prev_mouse_pos = QtCore.QPoint(0, 0)

        self.color = QtGui.QColor(0, 255, 50, 50)
        self.clicked_color = QtGui.QColor(0, 255, 50, 150)
        self.right_clicked_color = QtGui.QColor(255, 0, 0, 150)


v = testUi()
v.show()  # Call show to show it!

Правильно ли я предполагаю, что вы пытаетесь создать синоптику? Если да, вы можете проверить QGraphicsView, чтобы заполнить окно элементами и обрабатывать большую часть логики. В противном случае вам придется делать это на 100% самостоятельно, что может быть очень весело, но требует дополнительной работы.

...