PyQt QVBoxLayout 和缺少的小部件?

PyQt QVBoxLayout and missing widgets?

我正在尝试设置具有文本输入和组合框的 window。目前我只想查看相应小部件下显示的文本和选择。

我使用了 QVBoxLayout(),因为我稍后会添加更多东西,我认为这是布置 window.

的简单方法

遗憾的是,只有组合框会显示。代码:

from PyQt4 import QtCore, QtGui
import sys

class Polyhedra(QtGui.QMainWindow):

    def __init__(self):
        super(Polyhedra, self).__init__()

        self.initUI()

    def initUI(self): 

        # Poly names
        self.pNames = QtGui.QLabel(self)            
        polyNameInput = QtGui.QLineEdit(self) 
        # polyName entry
        polyNameInput.textChanged[str].connect(self.onChanged)  

        # Polytype selection
        self.defaultPolyType = QtGui.QLabel("Random polyhedra", self)
        polyType = QtGui.QComboBox(self)
        polyType.addItem("Random polyhedra")
        polyType.addItem("Spheres")
        polyType.addItem("Waterman polyhedra")
        polyType.activated[str].connect(self.onActivated)   

        # Layout
        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(polyNameInput)
        vbox.addWidget(self.pNames)
        vbox.addWidget(polyType)
        vbox.addWidget(self.defaultPolyType)
        vbox.addStretch()

        # Set up window        
        self.setGeometry(500, 500, 300, 300)
        self.setWindowTitle('Pyticle')
        self.show()

    # Combo box
    def onActivated(self, text):

        self.defaultPolyType.setText(text)
        self.defaultPolyType.adjustSize()  

    # Poly names         
    def onChanged(self, text):

        self.pNames.setText(text)
        self.pNames.adjustSize()   

def main():

    app = QtGui.QApplication(sys.argv)
    ex = Polyhedra()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

这是怎么回事?我是否遗漏了 QVBoxLayout() 的一些重要指令?

在装有 PyQt 4 的 Win 7 x64 机器上使用 Python 2.7。

编辑:其他问题(仍然与丢失的小部件有关)

我已根据以下说明修改了代码。 I then added more widgets when a certain option in the combobox is chosen (see below) but these widgets dont show.我试图将一个名为 'ranPolyWidget' 的子小部件添加到 'widget' 以进行数字输入。

# Combo box
def onActivated(self, text):

    if text=="Random polyhedra":
        self.randomSeedLbl = QtGui.QLabel("Seed: ", self)            
        randomSeed = QtGui.QLineEdit(self) 
        randomSeed.textChanged[str].connect(self.setSeed)
        ranPolyWidget = QtGui.QWidget(self.widget)
        rbox = QtGui.QVBoxLayout(ranPolyWidget)
        rbox.addWidget(randomSeed)
        self.layout().addWidget(ranPolyWidget)
        self.show()
    else:
        self.defaultPolyType.setText(text)
        self.defaultPolyType.adjustSize() 

和以前一样的问题,没有小部件。我错过了一些非常基本的东西吗?

您忘记将其设置为小部件或主程序 window,因此由于 QComboBox 是最后制作的,因此它是唯一显示的。基本上,所有内容都添加到布局中,但布局是 "free-floating",因此无法正常显示。您需要将布局绑定到 QWidget,我在这里就是这样做的。对于大多数小部件,您可以通过 QtGui.QVBoxLayout(小部件) 或 widget.setLayout(布局) 来完成此操作。

或者,如果您想要在一个小部件上使用多个布局,您可以有一个父布局,然后将每个子布局添加到主布局。

编辑:这是一个更好的答案:

制作一个小部件,将布局设置为小部件并设置为中心小部件。

QMainWindow-s 不喜欢您使用内置布局或覆盖它。

widget = QtGui.QWidget()
vbox = QtGui.QVBoxLayout(widget)
self.setCentralWidget(widget)

旧答案:

self.layout().addLayout(vbox).

这应该可以解决您的问题:

我所做的更改: 由于QMainWindow已经有了layout,所以在里面添加一个widget(28G)然后给widget设置VBoxLayout添加到main window.

from PyQt4 import QtCore, QtGui
import sys

class Polyhedra(QtGui.QMainWindow):

    def __init__(self):
        super(Polyhedra, self).__init__()

        self.initUI()

    def initUI(self): 

        # Poly names
        self.pNames = QtGui.QLabel(self)            
        polyNameInput = QtGui.QLineEdit(self) 
        # polyName entry
        polyNameInput.textChanged[str].connect(self.onChanged)  

        # Polytype selection
        self.defaultPolyType = QtGui.QLabel("Random polyhedra", self)
        polyType = QtGui.QComboBox(self)
        polyType.addItem("Random polyhedra")
        polyType.addItem("Spheres")
        polyType.addItem("Waterman polyhedra")
        polyType.activated[str].connect(self.onActivated)   

        # Layout
        widget = QtGui.QWidget()
        vbox = QtGui.QVBoxLayout(widget)
        vbox.addWidget(polyNameInput)
        vbox.addWidget(self.pNames)
        vbox.addWidget(polyType)
        vbox.addWidget(self.defaultPolyType)
        vbox.addStretch()

        # Set up window        
        self.setGeometry(500, 500, 300, 300)
        self.setWindowTitle('Pyticle')
        self.layout().addWidget(widget)
        self.show()

    # Combo box
    def onActivated(self, text):

        self.defaultPolyType.setText(text)
        self.defaultPolyType.adjustSize()  

    # Poly names         
    def onChanged(self, text):

        self.pNames.setText(text)
        self.pNames.adjustSize()   

def main():

    app = QtGui.QApplication(sys.argv)
    ex = Polyhedra()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

编辑:

要添加新的小部件,您应该将它们添加到中央小部件的布局中,并将它们作为该小部件的父级。

以下是我重构完整代码的方式:

from PyQt4 import QtCore, QtGui
import sys

class CentralWidget(QtGui.QWidget):

    def __init__(self, parent=None):
        super(CentralWidget, self).__init__(parent)

        # set layouts
        self.layout = QtGui.QVBoxLayout(self)
        # Poly names
        self.pNames = QtGui.QLabel(self)            
        polyNameInput = QtGui.QLineEdit(self) 
        # polyName entry
        polyNameInput.textChanged[str].connect(self.onChanged)  

        # Polytype selection
        self.defaultPolyType = QtGui.QLabel("Random polyhedra", self)
        polyType = QtGui.QComboBox(self)
        polyType.addItem("Random polyhedra")
        polyType.addItem("Spheres")
        polyType.addItem("Waterman polyhedra")
        polyType.activated[str].connect(self.onActivated)   

        self.layout.addWidget(polyNameInput)
        self.layout.addWidget(self.pNames)
        self.layout.addWidget(polyType)
        self.layout.addWidget(self.defaultPolyType)
        self.layout.addStretch()

    def onActivated(self, text):
        '''Adds randSeed to layout''' 

        if text=="Random polyhedra":
            self.randomSeedLbl = QtGui.QLabel("Seed: ", self)            
            randomSeed = QtGui.QLineEdit(self) 
            randomSeed.textChanged[str].connect(self.setSeed)
            self.layout.addWidget(randomSeed)
        else:
            self.defaultPolyType.setText(text)
            self.defaultPolyType.adjustSize()

    # Poly names         
    def onChanged(self, text):

        self.pNames.setText(text)
        self.pNames.adjustSize()  

class Polyhedra(QtGui.QMainWindow):
    def __init__(self):
        super(Polyhedra, self).__init__()

        # I like having class attributes bound in __init__
        # Not very Qt of me, but it's more 
        # so I break everything down into subclasses
        # find it more Pythonic and easier to debug: parent->child
        # is easy when I need to repaint or delete child widgets
        self.central_widget = CentralWidget(self)
        self.setCentralWidget(self.central_widget)

        # Set up window        
        self.setGeometry(500, 500, 300, 300)
        self.setWindowTitle('Pyticle')
        self.show()

    # Combo box
    def onActivated(self, text):
        '''Pass to child'''

        self.central_widget.onActivated(text)

def main():

    app = QtGui.QApplication(sys.argv)
    ex = Polyhedra()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()