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: