PyQt QVBoxLayout和丢失的小部件?

时间:2015-06-09 16:08:03

标签: python pyqt4

我正在尝试设置一个带有文本输入和窗口的窗口。一个组合框。目前我只是想看看文字&选择显示在适当的小部件下。

我已经使用过QVBoxLayout(),因为我稍后会添加更多内容。以为这是铺设窗户的简单方法。

不幸的是只有组合框才会显示出来。代码:

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。

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

我在下面的澄清之后修改了代码。然后,当选择组合框中的某个选项时,我添加了更多小部件(见下文),但这些小部件没有显示。我试图将一个子窗口小部件添加到名为“ranPolyWidget”的“窗口小部件”中以进行数字输入。

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

与以前相同的问题,没有小部件。我错过了一些非常基本的东西,不是吗?

1 个答案:

答案 0 :(得分:2)

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

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

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

创建一个小部件,将布局设置为小部件并设置为中央小部件。

QMainWindow不喜欢你使用内置布局或覆盖它。

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

旧答案:

self.layout()。addLayout(VBOX)。

这可以解决您的问题:

我所做的改变: 由于QMainWindow已经有一个布局,添加一个小部件(28G),然后将VBoxLayout设置为小部件并将其添加到主窗口。

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