布局PyQt5的不等部分

Unequal parts of layout PyQt5

我目前面临以下问题:我已经为我的 PyQt 布局创建了一个设计,并尝试手动实现它,我阅读了如何从 .ui 生成 python 代码的可能性。 QT Creator 之后的文件,但我想学习手动方式。这是我的源代码,我已经将所有必要的部分分成组框,我不知道如何正确定位它们。

下一个问题,是否可以在复选框 "Advanced" 关闭时隐藏组框 "secret"?我还没有找到任何类似的教程。

我想要的布局

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

我也很感激任何对源代码的批评。如何写得更好

为了容纳小部件作为图中的示例,您必须组合使用 QVBoxLayout、QHBoxLayout、QFormLayout。为了使占用的 space 始终成比例,我们必须使用拉伸:

{your layout}.addWidget(QWidget * widget, int stretch = 0, Qt::Alignment alignment = 0)
{your layout}.addLayout(QLayout * layout, int stretch = 0)

这个因素是赋予父布局中的小部件或子布局的权重。

要隐藏 QGroupBox 必须使用 hide 函数,要显示它必须用 QCheckBox 的信号 stateChanged 控制。

def onSecret(s):
    if s == Qt.Checked:
        groupBox2.show()
    else: 
        groupBox2.hide()

onSecret(chBox.checkState())
chBox.stateChanged.connect(onSecret)

由于 groupBox 秘密将被隐藏,groupbox 进度将停留在中间,将其推送到我们将使用 QSpacerItem.

的部分

截图:

完整代码:

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