I am facing currently the following problem: I have created a design for my PyQt layout, and trying to realize it manually, I read about possibilities how to generate python code from .ui file after QT Creator, but I want to learn the manual way. Here is my source code, I have divided all the necessary parts into group boxes, I don't know how to locate them properly.
And the next question, is it possible to hide the Group box "secret" when the Checkbox "Advanced" is off? I haven't found any tutorials like that.
My desired Layout
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton, QGridLayout, QCheckBox, QLabel, QGroupBox, QSpinBox, QVBoxLayout, QHBoxLayout, QGridLayout, QProgressBar
from PyQt5.Qt import QIcon
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowIcon(QIcon('icon.png'))
self.setFixedSize(400,200)
self.setWindowTitle('My app')
#self.statusBar().showMessage('ready')
groupBox1 = QGroupBox('Config')
vBox1 = QVBoxLayout(self)
readFile = QPushButton('Read File')
decodeFile = QPushButton('Decode')
chBox = QCheckBox('Advanced')
vBox1.addWidget(readFile)
vBox1.addWidget(decodeFile)
vBox1.addWidget(chBox)
groupBox1.setLayout(vBox1)
groupBox2 = QGroupBox('Secret')
gLayout = QGridLayout(self)
label1 = QLabel('Label 1')
label2 = QLabel('Label 2')
edit2 = QSpinBox()
edit3 = QSpinBox()
gLayout.addWidget(label1, 0, 0)
gLayout.addWidget(label2, 1, 0)
gLayout.addWidget(edit2, 0, 1)
gLayout.addWidget(edit3, 1, 1)
groupBox2.setLayout(gLayout)
groupBox3 = QGroupBox('Progress')
vBox2 = QVBoxLayout(self)
pBar = QProgressBar()
vBox2.addWidget(pBar)
groupBox3.setLayout(vBox2)
hbox1 = QHBoxLayout(self)
hbox1.addWidget(groupBox1)
hbox1.addWidget(groupBox2)
hbox1.addWidget(groupBox3)
self.setLayout(hbox1)
self.resize(480, 320);
self.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
I would also appreciate any critic about the source code. How to write in a better way
In order to accommodate the widget as samples in your figure you must use a combination of QVBoxLayout, QHBoxLayout, QFormLayout. In order for the occupied space to always be proportional, we must use the stretch:
{your layout}.addWidget(QWidget * widget, int stretch = 0, Qt::Alignment alignment = 0)
{your layout}.addLayout(QLayout * layout, int stretch = 0)
This factor is the weight given to the widget or sub-layouts within the parent layout.
To hide the QGroupBox
you must use the hide function, and to show it, it must be controlled with the signal stateChanged
of the QCheckBox
.
def onSecret(s):
if s == Qt.Checked:
groupBox2.show()
else:
groupBox2.hide()
onSecret(chBox.checkState())
chBox.stateChanged.connect(onSecret)
As the groupBox secret is going to be hidden the groupbox progress will stay in the middle, to push it to the part we will use a QSpacerItem
.
Screenshots:
Complete code:
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton, QFormLayout, QCheckBox, QLabel, QGroupBox, QSpinBox, QVBoxLayout, QHBoxLayout, QProgressBar, QSpacerItem, QSizePolicy
from PyQt5.QtCore import Qt
class Example(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent=parent)
self.initUI()
def initUI(self):
self.setFixedSize(400,200)
self.setWindowTitle('My app')
hbox = QHBoxLayout(self)
groupBox1 = QGroupBox("Config", self)
vbox = QVBoxLayout(groupBox1)
readFile = QPushButton("Read File", groupBox1)
vbox.addWidget(readFile, 1)
decodeFile = QPushButton("Decode", groupBox1)
vbox.addWidget(decodeFile, 1)
chBox = QCheckBox("Advanced", groupBox1)
vbox.addWidget(chBox, 1)
hbox.addWidget(groupBox1, 1)
vbox2 = QVBoxLayout()
groupBox2 = QGroupBox("Secret", self)
vbox3 = QVBoxLayout(groupBox2)
flay = QFormLayout()
label1 = QLabel("Label 1", groupBox2)
edit2 = QSpinBox(groupBox2)
flay.addRow(label1, edit2)
label2 = QLabel("Label 2", groupBox2)
edit3 = QSpinBox(groupBox2)
flay.addRow(label2, edit3)
vbox3.addLayout(flay, 1)
vbox2.addWidget(groupBox2)
groupBox3 = QGroupBox("Progress", self)
vbox4 = QVBoxLayout(groupBox3)
pBar = QProgressBar(groupBox3)
pBar.setValue(21)
vbox4.addWidget(pBar)
vbox2.addWidget(groupBox3)
spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
vbox2.addItem(spacerItem)
hbox.addLayout(vbox2, 1)
def onSecret(s):
if s == Qt.Checked:
groupBox2.show()
else:
groupBox2.hide()
onSecret(chBox.checkState())
chBox.stateChanged.connect(onSecret)
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())