简体   繁体   中英

PySide / PyQt: How to create custom classes?

I'm trying to create checkbox, frame, and grid layout objects and store them in their own list.

The output from Qt Designer looks like: 在此处输入图片说明

Essentially, I want to create Checkbox1, then create a frame and grid layout to store Checkbox2 and Checkbox3.

My approach was to first create an empty list to store the objects I'm creating: checkboxList = [] Then to append it with a call to create the appropriate object checkboxList.append(CreateCheckBox(self.frame_main, self.gridLayout_main, 0, 'Checkbox 1') (for example)

This produces the output: 在此处输入图片说明

The frame I created isn't visible! I'm guessing there are a few possible reasons for this:

  1. I'm creating the classes incorrectly
  2. I'm storing the objects I created incorrectly (ie init doesn't return anything so I'm not actually storing anything?)
  3. I'm not adding my objects to the main frame properly so they're not showing up

Why isn't my class implementation working like the code from Qt Designer and what/how do I make the changes to get a similar output?

The code imported from Qt Designer looks like this:

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_())

And my code with classes looks like:

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_())

El problema se soluciona maquetando correctamente tu aplicación, en la siguiente imagen se muestra el maquetado de QMainWindow, la imagen muestra que QMainWindow varias secciones.

在此处输入图片说明

In your case you should design the centralwidget,

在此处输入图片说明

Then, the answer can be implemented, observing that it is not necessary to use QGridLayout since it is used to distribute it as a matrix. I have created the addCheckbox function that adds the widget and stores it in the list.

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)

Screenshot:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM