简体   繁体   English

PyQt QVBoxLayout和丢失的小部件?

[英]PyQt QVBoxLayout and missing widgets?

I am trying to set up a window that has a text input & a combo box. 我正在尝试设置一个具有文本输入和组合框的窗口。 At the moment I just want to see the text & the selection displayed under the appropriate widget. 目前我只想看到相应小部件下显示的文本和选择。

I have used QVBoxLayout() as I will be adding more stuff later & thought it would be a simple way of laying out the window. 我已经使用了QVBoxLayout(),因为我稍后会添加更多内容并认为这将是一种布局窗口的简单方法。

Unfortunately only the combo box ever gets displayed. 不幸的是,只有组合框才会显示出来。 The code: 编码:

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

So whats going on here? 那么最近怎么样? Am I missing some important directive to QVBoxLayout()? 我错过了QVBoxLayout()的一些重要指令吗?

Using Python 2.7 on Win 7 x64 machine with PyQt 4. 在带有PyQt 4的Win 7 x64机器上使用Python 2.7。

EDIT: Additional problem (still related to missing widgets) 编辑:其他问题(仍然与丢失的小部件有关)

I have amended the code following the clarification below. 我在下面的澄清之后修改了代码。 I then added more widgets when a certain option in the combobox is chosen (see below) but these widgets dont show. 然后,当选择组合框中的某个选项时,我添加了更多小部件(见下文),但这些小部件没有显示。 I attempted to add a child widget to 'widget' called 'ranPolyWidget' to take a numerical input. 我试图将一个子窗口小部件添加到名为“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() 

Same issue as before, no widgets. 与以前相同的问题,没有小部件。 I am missing something pretty fundamental arent I? 我错过了一些非常基本的东西我不是吗?

You're forgetting to set it to the widget or main window, so since the QComboBox is the last one made, it's the only one displayed. 您忘记将其设置为窗口小部件或主窗口,因此,由于QComboBox是最后一个制作的,因此它是唯一显示的窗口。 Basically, everything is added to the layout, but the layout is "free-floating", and so it does not display properly. 基本上,所有内容都添加到布局中,但布局是“自由浮动”,因此无法正常显示。 You need to bind the layout to a QWidget, which I do here. 你需要将布局绑定到QWidget,我在这里做。 For most widgets, you can can do this by the QtGui.QVBoxLayout(widget) or by widget.setLayout(layout). 对于大多数小部件,您可以通过QtGui.QVBoxLayout(小部件)或widget.setLayout(布局)来完成此操作。

Alternatively, if you want multiple layouts on a widget, you can do have a parent layout and then add each child layout to the main layout. 或者,如果您想在窗口小部件上使用多个布局,则可以使用父布局,然后将每个子布局添加到主布局。

EDIT: This is a better answer: 编辑:这是一个更好的答案:

Make a widget, set layout to widget and set as central widget. 制作一个小部件,将布局设置为小部件并设置为中央小部件。

QMainWindow-s don't like you using the builtin layout or overriding it. QMainWindow-s不喜欢你使用内置布局或覆盖它。

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

Old Answer: 旧答案:

self.layout().addLayout(vbox). self.layout()。addLayout(VBOX)。

This should fix your issue: 这应该可以解决您的问题:

Changes I made: Since QMainWindow already has a layout, add in a widget (28G) and then set the VBoxLayout to the widget and add it to the main window. 我做的更改:由于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()

EDIT: 编辑:

For adding new widgets, you should add them to the layout of the central widget and parent them to that widget. 要添加新窗口小部件,您应该将它们添加到中央窗口小部件的布局中,并将它们添加到该窗口小部件。

Here's how I'd restructure your full code: 以下是我重新构建完整代码的方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM