PySide / PyQt: как создавать собственные классы?
Я пытаюсь создать объекты-флажки, рамки и сетки и сохранить их в своем собственном списке.
Вывод из Qt Designer выглядит следующим образом:
По сути, я хочу создать Checkbox1, а затем создать макет рамки и сетки для хранения Checkbox2 и Checkbox3.
Мой подход состоял в том, чтобы сначала создать пустой список для хранения объектов, которые я создаю:checkboxList = []
Затем добавить его с помощью вызова, чтобы создать соответствующий объект checkboxList.append(CreateCheckBox(self.frame_main, self.gridLayout_main, 0, 'Checkbox 1')
(например)
Созданная мной рамка не видна! Я предполагаю, что есть несколько возможных причин для этого:
- Я неправильно создаю классы
- Я храню объекты, которые я создал неправильно (т.е. init ничего не возвращает, поэтому я ничего не храню?)
- Я не добавляю свои объекты в основной фрейм должным образом, поэтому они не отображаются
Почему моя реализация класса не работает, как код из 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)
Скриншот: