I am trying to build a UI using PyQt5 that places buttons in exact positions. I believe that QGridLayout is a good way to do this, versus plotting them directly in the QMainWindow. The reason I am looking at QGridLayout is because I would like to have a separation of the grid of buttons from other parts of the UI, such as an image to the right of the buttons grid (using QHBoxLayout).
When I plot the buttons directly in the QMainWindow, the buttons appear in the correct locations. However, when I use QGridLayout with the same coordinates, the buttons are not placed in the correct locations and appear to be squished.
Approach 1: I plot the buttons directly in the QMainWindow using the QPushButton .move() and .resize() methods. In this case the buttons are plotted in the correct locations.
# below imports, data variable, and main() are used for both examples
import sys
from PyQt5.QtWidgets import (QApplication, QPushButton, QMainWindow,
QGridLayout, QWidget)
data = [{'xmin': 2, 'ymin': 4, 'width': 205, 'height': 54, 'label': 'Go to Page 1'},
{'xmin': 34, 'ymin': 22, 'width': 141, 'height': 17, 'label': 'Go to Page 2'},
{'xmin': 2, 'ymin': 90, 'width': 187, 'height': 54, 'label': 'Go to Page 3'},
{'xmin': 34, 'ymin': 108, 'width': 122, 'height': 17, 'label': 'Go to Page 4'},
{'xmin': 2, 'ymin': 176, 'width': 231, 'height': 54, 'label': 'Go to Page 5'}]
class VisualizerWindow(QMainWindow):
def __init__(self):
super().__init__()
for rect in data:
button = QPushButton(rect['label'], parent=self)
button.move(rect['xmin'], rect['ymin'])
button.resize(rect['width'], rect['height']+10)
def main():
app = QApplication(sys.argv)
viz_window = VisualizerWindow()
viz_window.showMaximized()
sys.exit(app.exec())
if __name__ == '__main__':
main()

Approach 2: When I take the approach of using QMainWindow, QGridLayout, and then add QPushButtons through layout.addWidget(), the buttons are not placed in the correct locations on the screen, even though I am supplying the exact coordinates in the .addWidget() method.
class VisualizerWindow(QMainWindow):
def __init__(self):
super().__init__()
layout = QGridLayout()
for rect in data:
button = QPushButton(rect['label'], parent=self)
layout.addWidget(button, rect['xmin'],
rect['ymin'], rect['width'],
rect['height']+10)
widget = QWidget(self)
widget.setLayout(layout)
self.setCentralWidget(widget)

The Grid Layout in Approach 2 appears to be squished in the Main Window. Why am I seeing different plotting behavior between these two approaches? How can I use QGridLayout correctly to plot the buttons in the correct locations?