PySide / PyQt: как создавать собственные классы?

Я пытаюсь создать объекты-флажки, рамки и сетки и сохранить их в своем собственном списке.

Вывод из Qt Designer выглядит следующим образом:

По сути, я хочу создать Checkbox1, а затем создать макет рамки и сетки для хранения Checkbox2 и Checkbox3.

Мой подход состоял в том, чтобы сначала создать пустой список для хранения объектов, которые я создаю:checkboxList = []Затем добавить его с помощью вызова, чтобы создать соответствующий объект checkboxList.append(CreateCheckBox(self.frame_main, self.gridLayout_main, 0, 'Checkbox 1') (например)

Это производит вывод:

Созданная мной рамка не видна! Я предполагаю, что есть несколько возможных причин для этого:

  1. Я неправильно создаю классы
  2. Я храню объекты, которые я создал неправильно (т.е. init ничего не возвращает, поэтому я ничего не храню?)
  3. Я не добавляю свои объекты в основной фрейм должным образом, поэтому они не отображаются

Почему моя реализация класса не работает, как код из Qt Designer, и что / как я могу внести изменения, чтобы получить похожий вывод?

Код, импортированный из Qt Designer, выглядит следующим образом:

from PySide import QtCore, QtGui

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(494, 210)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.frame_main = QtGui.QFrame(self.centralwidget)
        self.frame_main.setGeometry(QtCore.QRect(20, 10, 435, 141))
        self.frame_main.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame_main.setFrameShadow(QtGui.QFrame.Raised)
        self.frame_main.setObjectName("frame_main")
        self.gridLayout_2 = QtGui.QGridLayout(self.frame_main)
        self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_2.setSpacing(0)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.gridLayout_main = QtGui.QGridLayout()
        self.gridLayout_main.setSpacing(0)
        self.gridLayout_main.setObjectName("gridLayout_main")
        self.frame2 = QtGui.QFrame(self.frame_main)
        self.frame2.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame2.setFrameShadow(QtGui.QFrame.Raised)
        self.frame2.setObjectName("frame2")
        self.gridLayout_16 = QtGui.QGridLayout(self.frame2)
        self.gridLayout_16.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_16.setObjectName("gridLayout_16")
        self.gridLayout2 = QtGui.QGridLayout()
        self.gridLayout2.setObjectName("gridLayout2")
        spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
        self.gridLayout2.addItem(spacerItem, 0, 0, 1, 1)
        self.checkBox2 = QtGui.QCheckBox(self.frame2)
        self.checkBox2.setObjectName("checkBox2")
        self.gridLayout2.addWidget(self.checkBox2, 0, 1, 1, 1)
        self.checkBox3 = QtGui.QCheckBox(self.frame2)
        self.checkBox3.setObjectName("checkBox3")
        self.gridLayout2.addWidget(self.checkBox3, 1, 1, 1, 1)
        self.gridLayout_16.addLayout(self.gridLayout2, 0, 0, 1, 1)
        self.gridLayout_main.addWidget(self.frame2, 1, 1, 1, 1)
        self.checkBox1 = QtGui.QCheckBox(self.frame_main)
        self.checkBox1.setObjectName("checkBox1")
        self.gridLayout_main.addWidget(self.checkBox1, 0, 1, 1, 1)
        spacerItem1 = QtGui.QSpacerItem(50, 20, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
        self.gridLayout_main.addItem(spacerItem1, 0, 0, 1, 1)
        self.gridLayout_2.addLayout(self.gridLayout_main, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 494, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
        self.checkBox2.setText(QtGui.QApplication.translate("MainWindow", "Checkbox2", None, QtGui.QApplication.UnicodeUTF8))
        self.checkBox3.setText(QtGui.QApplication.translate("MainWindow", "Checkbox3", None, QtGui.QApplication.UnicodeUTF8))
        self.checkBox1.setText(QtGui.QApplication.translate("MainWindow", "Checkbox1", None, QtGui.QApplication.UnicodeUTF8))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

И мой код с классами выглядит так:

from PySide import QtCore, QtGui


class CreateCheckBox(QtGui.QCheckBox):
    def __init__(self, frame, grid, gridLoc, name, parent=None):
        #QtGui.QCheckBox.__init__(self, parent=parent)  Is this the same as the super below?
        super(CreateCheckBox, self).__init__(parent)
        self.checkbox = QtGui.QCheckBox(frame)
        grid.addWidget(self.checkbox, gridLoc, 2, 1, 1)
        self.checkbox.setText(name)


class CreateFrame(QtGui.QFrame):
    def __init__(self, parentFrame, parentGridLayout, gridLoc, parent=None):
        #QtGui.QFrame.__init__(self, parent=parent)  Is this the same as the super below?
        super(CreateFrame, self).__init__(parent)
        self.frame = QtGui.QFrame(parentFrame)
        self.frame.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtGui.QFrame.Raised)
        parentGridLayout.addWidget(self.frame, gridLoc, 2, 1, 1)


class CreateGridLayout(QtGui.QGridLayout):
    def __init__(self, parentFrame, parent=None):
        super(CreateGridLayout, self).__init__(parent)
        #QtGui.QGridLayout.__init__(self)  # This line throws an error if I include parent=parent, why?..
        self.gridLayoutSecondary = QtGui.QGridLayout(parentFrame)
        self.gridLayoutSecondary.setContentsMargins(0, 0, 0, 0)
        self.gridLayoutPrimary = QtGui.QGridLayout()
        spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
        self.gridLayoutPrimary.addItem(spacerItem, 0, 0, 1, 1)
        self.gridLayoutSecondary.addLayout(self.gridLayoutPrimary, 0, 0, 1, 1)


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(494, 210)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.frame_main = QtGui.QFrame(self.centralwidget)
        self.frame_main.setGeometry(QtCore.QRect(20, 10, 435, 141))
        self.frame_main.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame_main.setFrameShadow(QtGui.QFrame.Raised)
        self.frame_main.setObjectName("frame_main")
        self.gridLayout_main = QtGui.QGridLayout()
        self.gridLayout_main.setSpacing(0)
        self.gridLayout_main.setObjectName("gridLayout_main")
        spacerItem1 = QtGui.QSpacerItem(50, 20, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
        self.gridLayout_main.addItem(spacerItem1, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 494, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        # List that contains new checkboxes
        checkboxList = []
        # List that contains new frames
        frameList = []
        # List than contains grid layouts for new frames
        gridLayoutList = []

        # Create 'checkBox1'
        checkboxList.append(CreateCheckBox(self.frame_main, self.gridLayout_main, 0, 'Checkbox 1'))
        # Create 'frame2'
        frameList.append(CreateFrame(self.frame_main, self.gridLayout_main, 1))
        # Create 'gridLayout2'
        gridLayoutList.append(CreateGridLayout(frameList[0]))
        # Create 'checkBox2'
        checkboxList.append(CreateCheckBox(frameList[0], gridLayoutList[0], 0, 'Checkbox 2'))
        # Create 'checkBox3'
        checkboxList.append(CreateCheckBox(frameList[0], gridLayoutList[0], 1, 'Checkbox 3'))

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

1 ответ

Решение

Все проблемы решаются правильно и корректно, в зависимости от того, что вы видите, - это QMainWindow, то есть изображение, которое вы можете получить с помощью QMainWindow varias secciones.

введите описание изображения здесь

В вашем случае вы должны разработать центральный виджет,

введите описание изображения здесь

Затем ответ можно реализовать, заметив, что нет необходимости использовать QGridLayout, поскольку он используется для его распределения в виде матрицы. Я создал функцию addCheckbox, которая добавляет виджет и сохраняет его в списке.

from PyQt4 import QtGui, QtCore


class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent=parent)

        # add menubar
        self.menubar = QtGui.QMenuBar(self)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 494, 21))
        self.setMenuBar(self.menubar)
        # add statusbar
        self.statusbar = QtGui.QStatusBar(self)
        self.setStatusBar(self.statusbar)

        # set central widget
        self.centralwidget = QtGui.QWidget(self)
        self.setCentralWidget(self.centralwidget)

        lay = QtGui.QVBoxLayout(self.centralwidget)
        self.checkBox = QtGui.QCheckBox("checkbox1", self)
        lay.addWidget(self.checkBox)

        self.frame = QtGui.QFrame(self)
        lay.addWidget(self.frame)

        self.layout_of_frame = QtGui.QVBoxLayout(self.frame)

        self.checkBoxList = []
        self.addCheckbox("checkbox2")
        self.addCheckbox("checkbox3")
        self.addCheckbox("checkbox4")
        self.addCheckbox("checkbox5")

    def addCheckbox(self, text):
        checkbox = QtGui.QCheckBox(text, self)
        self.layout_of_frame.addWidget(checkbox)
        self.checkBoxList.append(checkbox)

Скриншот:

введите описание изображения здесь

Другие вопросы по тегам