Как наследовать QtWidgets.QWidget в моем классе и сделать тип моего класса — QtWidgets.QWidget?

#python #pyqt #pyside #maya

#python #pyqt #pyside #maya

Вопрос:

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

 # 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. Сделайте super(Test, self).__init__(parent) и используйте self вместо qWid .

Ответ №1:

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

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

Вероятно, это было ужасное объяснение, поэтому, пожалуйста, погуглите 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!
  

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

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

1. Вы потрясающие, спасибо за вашу работу и комментарии в скриптах. Это было действительно полезно, и я думаю, я понял, как это работает. Да, я пытаюсь создать синоптики?! (не знал, что для этого есть такое слово). Я знаю, что существует QGraphicsView, но хотел попробовать создать какой-нибудь виджет самостоятельно. Еще раз спасибо.