2

I am trying to create a program where the user has three options to answer a question. I used QGridLayout for this but only the last widget added to the QGridLayout is shown.

Expected:

################################
#             Text             #
################################

########## ########## ##########
#Button 1# #Button 2# #Button 3#
########## ########## ##########

Reality:

##########
#Button 3#
##########

Simplified Python 3 Code (No Text Widget):

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys

QApp = QApplication(sys.argv)

QMWRoot = QMainWindow()
QGLRoot = QGridLayout(QMWRoot)
QMWRoot.setLayout(QGLRoot)
QPB0 = QPushButton('B0x0', QMWRoot)
QGLRoot.addWidget(QPB0, 0, 0)
QPB1 = QPushButton('B0x1', QMWRoot)
QGLRoot.addWidget(QPB1, 0, 1)
QPB2 = QPushButton('B1x0', QMWRoot)
QGLRoot.addWidget(QPB2, 1, 0)
QMWRoot.show()

sys.exit(QApp.exec_())

Original (Unfinished) Python 3 Code:

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys

class Root(QMainWindow):
    def __init__(self, QApp):
        super().__init__()
        self.QApp = QApp
    def setupUi(self):
        self.setWindowTitle('')
        self.QGLRoot = QGridLayout()
        self.setLayout(self.QGLRoot)

        self.QLBTool = QLabel()
        self.QLBTool.setText('Tool')
        self.QGLRoot.addWidget(self.QLBTool, 0, 0)
        self.QPB0 = QPushButton(self)
        self.QPB0.setText('0')
        self.QGLRoot.addWidget(self.QPB0, 1, 0)
        self.QPB1 = QPushButton(self)
        self.QPB1.setText('1')
        self.QGLRoot.addWidget(self.QPB1, 1, 1)
        self.QPB2 = QPushButton(self)
        self.QPB2.setText('2')
        self.QGLRoot.addWidget(self.QPB2, 1, 2)
    def startUi(self):
        self.show()
    def updateUi(self):
        pass

QApp = QApplication(sys.argv)

App = Root(QApp)
App.setupUi()
App.startUi()

sys.exit(QApp.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Penguin
  • 93
  • 2
  • 10

1 Answers1

2

QMainWindow you have a special structure:

enter image description here

So in your case you must establish a centralwidget and there place the layout.

import sys

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class Root(QMainWindow):
    def __init__(self, QApp):
        super().__init__()
        self.QApp = QApp

    def setupUi(self):
        self.setWindowTitle('')
        widget = QWidget()
        self.setCentralWidget(widget)

        self.QGLRoot = QGridLayout()
        widget.setLayout(self.QGLRoot)

        self.QLBTool = QLabel()
        self.QLBTool.setAlignment(Qt.AlignHCenter)
        self.QLBTool.setText('Tool')

        self.QGLRoot.addWidget(self.QLBTool, 0, 0, 1, 3)

        self.QPB0 = QPushButton()
        self.QPB0.setText('0')
        self.QGLRoot.addWidget(self.QPB0, 1, 0)
        self.QPB1 = QPushButton()
        self.QPB1.setText('1')
        self.QGLRoot.addWidget(self.QPB1, 1, 1)
        self.QPB2 = QPushButton()
        self.QPB2.setText('2')
        self.QGLRoot.addWidget(self.QPB2, 1, 2)

    def startUi(self):
        self.show()

QApp = QApplication(sys.argv)
App = Root(QApp)
App.setupUi()
App.startUi()
sys.exit(QApp.exec_())

enter image description here

Compact and generalized code:

import sys

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, \
    QGridLayout, QLabel, QPushButton


class Root(QMainWindow):
    def __init__(self, QApp):
        super().__init__()
        self.setupUi()

    def setupUi(self):
        self.setWindowTitle('')

        widget = QWidget()
        self.setCentralWidget(widget)
        QGLRoot = QGridLayout(widget)

        options = ("0", "1", "2")

        QLBTool = QLabel('Tool')
        QLBTool.setAlignment(Qt.AlignHCenter)

        QGLRoot.addWidget(QLBTool, 0, 0, 1, len(options))

        for i, option in enumerate(options):
            button = QPushButton(option)
            QGLRoot.addWidget(button, 1, i)

QApp = QApplication(sys.argv)
App = Root(QApp)
App.show()
sys.exit(QApp.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • @ellyanesc, thanks for the answer. Am I allowed to set the QGridLayout as the central widget? – Penguin Jul 02 '18 at 08:40
  • @Penguin QGridLayout is not a widget, so you can not. – eyllanesc Jul 02 '18 at 08:42
  • @ellyanesc, is the Central Widget needed after setting the `self.QGLRoot` as layout? I'm pretty sure it's a no. – Penguin Jul 02 '18 at 08:53
  • @Penguin If you do not want to use it then you should not use QMainWindow but a QWidget. The QMainWindow is a special widget since as you see it has to place toolbars, statusbar, dockwidgets, etc. If you do not want that then change the QMainWindow to QWidget. :) – eyllanesc Jul 02 '18 at 08:56
  • @Penguin QMainWindow already has a layout by default, in that layout is the ToolBar, DockWidget, StatusBar, MenuBar and the centralWidget, so if you set a new layout you would be eliminating all of the above, which does not make sense so the correct thing would be to use QWidget instead of QMainWindow. – eyllanesc Jul 02 '18 at 08:59