Why does grid layout only show me one button?

1

I'm trying to interface with PyQt5. I have copied an example of the internet where it shows how to make a grid and add widgets, but when I add 3 buttons it only shows me 1. What am I doing wrong?

This is the code:

import sys
from PyQt5 import QtWidgets, QtGui, QtCore

class Window(QtWidgets.QMainWindow):
    def __init__(self):
       super(Window, self).__init__()
       self.initUI()

    def initUI(self):
        bRun = QtWidgets.QPushButton("Run",self)
        bViewResult = QtWidgets.QPushButton("View",self)
        bExit = QtWidgets.QPushButton("Exit",self)

        grid = QtWidgets.QGridLayout()
        grid.setSpacing(10)

        grid.addWidget(bRun, 1, 0)
        grid.addWidget(bViewResult, 2, 0)
        grid.addWidget(bExit, 3, 0)
        self.setLayout(grid)


        self.setGeometry(300, 300, 350, 300)
        self.setWindowTitle('Example')
        self.show()
if __name__=='__main__':
   app = QtWidgets.QApplication(sys.argv)
   wind = Window()
   sys.exit(app.exec_())

And this is the result:

    
asked by Yorch 26.07.2018 в 11:10
source

2 answers

1

The response of @ Marine1 is partially correct, so I will complete the answer and explain in detail what is happening.

If a layout is not inside a widget it does not work, and that is the case with you, you never assigned the grid to any widget.

If the layout does not work because you see the button?

In Qt, the child is drawn with respect to the parent and in your case all the buttons have as a parent to Window so they will be drawn in the main window, the initial position of the buttons will be (0, 0) for that reason draw in the topLeft.

The correct structure is as follows:

└── Window
    └── centralwidget
        └── grid
            ├── bRun
            ├── bViewResult
            └── bExit

On the other hand, it is not necessary to pass a parent to the buttons, since when you set it in a layout, it will pass to the widget that is set as the parent.

Do not use self.setLayout (grid) , because as it shows the following image QMainWindow already has a layout and what you would be doing is to replace it eliminating the possibility of adding the statusbar, toolbar, dockwidgets, etc. As I show in my solution you must set this layout to the centralwidget with grid = QtWidgets.QGridLayout(centralwidget) or centralwidget.setLayout(grid) .

Using all the above we get the following:

import sys
from PyQt5 import QtWidgets, QtGui, QtCore

class Window(QtWidgets.QMainWindow):
    def __init__(self):
       super(Window, self).__init__()
       self.initUI()

    def initUI(self):
        bRun = QtWidgets.QPushButton("Run")
        bViewResult = QtWidgets.QPushButton("View")
        bExit = QtWidgets.QPushButton("Exit")

        centralwidget = QtWidgets.QWidget()
        # se esta indicando que es el widget central
        self.setCentralWidget(centralwidget)

        # establecemos que el grid estara dentro del centralwidget
        grid = QtWidgets.QGridLayout(centralwidget)
        # otro forma equivalente es:
        # grid = QtWidgets.QGridLayout()
        # centralwidget.setLayout(grid)
        grid.setSpacing(10)

        grid.addWidget(bRun, 1, 0)
        grid.addWidget(bViewResult, 2, 0)
        grid.addWidget(bExit, 3, 0)

        self.setGeometry(300, 300, 350, 300)
        self.setWindowTitle('Example')
        self.show()


if __name__=='__main__':
   app = QtWidgets.QApplication(sys.argv)
   wind = Window()
   sys.exit(app.exec_())

Exit:

    
answered by 26.07.2018 / 12:10
source
0

You must place those widgets and designs in the central widget of your QMainWindow . Here is the composition of QMainWindow :

QMainWindow already has a design that handles things like menu bars and status bars. It also has a central widget to add your own design to. As such, if you add the line of code

centralwidget = QtWidgets.QWidget()
self.setCentralWidget(centralWidget)

then your existing widget with design (centralWidget) will be placed in the design construction in QMainWindow . All this was fun to these answers (in English) that can help you. However, you have to establish that the grid will be inside the centralwidget:

grid = QtWidgets.QGridLayout(centralwidget)

Second you can start adding your Widgets.

grid.addWidget(bRun, 1, 0)
grid.addWidget(bViewResult, 2, 0)
grid.addWidget(bExit, 3, 0)

And finally you can show your creation:

self.show()

The documentation gives the reason and proposes a slightly different way:

  

If the QGridLayout is not the top-level layout (i.e. does not manage   all of the widget's area and children), you must add it to its parent   layout when you create it, but before you do anything with it. The   normal way to add to layout is by calling addLayout() on the parent   layout.

     

Once you have added your layout you can start putting widgets and other layouts into the cells of your grid layout using addWidget() , addItem() , and addLayout() . doc.qt.io about QGridLayout Class 26/7/2018

    
answered by 26.07.2018 в 11:51