Why Can't I Add a Qgridlayout to a Qmainwindow

Why can't I add a QGridLayout to a QMainWindow?

What you can do is create a QWidget set it as the central widget and give this one a layout. QMainWindow has its own layout already to place statusbar and mainmenu thus you can't set another one directly.

Not able to display widgets in QGridLayout from MainWindow

QMainWindow has already a fixed layout. So you cannot reassign one. See here: http://doc.qt.io/qt-5/qmainwindow.html#details

QMainWindow has its own layout to which you can add QToolBars,
QDockWidgets, a QMenuBar, and a QStatusBar. The layout has a center
area that can be occupied by any kind of widget.

What you can do is set an "empty" widget as central widget and give it the layout.

QWidget *centralWidget = new QWidget(); //set parent to this
//...
reminderTextEdit = new QTextEdit("");
reminderTextEdit->setPlaceholderText("What do you want to be reminded of?");
//...

centralWidget->setLayout(gridLayout);
setCentralWidget(window);

EDIT:

As @thuga mentioned in the comments: when you add a widget to the layout it will take the responsibility of the item (reparent them). So when you add the items to the layout you don't need to declare a parent in the first place.

The same goes for the widget you provide to setCentralWidget

QWidget::setLayout: Attempting to set QLayout on MainWindow , which already has a layout

You can't set a QLayout directly on the QMainWindow. You need to create a QWidget and set it as the central widget on the QMainWindow and assign the QLayout to that.

wid = QtGui.QWidget(self)
self.setCentralWidget(wid)
layout = QtGui.QVBoxLayout()
wid.setLayout(layout)

NOTE: This is for Qt4 -- see the other answer on this question for the Qt5 updated code.

PyQt5 QMainWindow not displaying central widget

Unfortunately, the OP claimed that

the problem is that the central widget is not showing on QMainWindow even after using setCentralWidget function .

without elaborating in detail.

I had a rough look onto the source and came to the conclusion that

  • widgets have been added to layout
  • layout is set to widget
  • the widget has been set to QMainWindow.

So far so fine.

Then I copied the complete source of OP to my local box.

To make it running I had to add/modify a variety of things:

  1. All Qt imports were missing. I added

    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
  2. For sys.argv (in app = QApplication(sys.argv)), import sys is needed as well.

  3. The widgets Board and Clock were missing.

    #board = Board()
    #clock = Clock()
    clock = QLabel('Clock')
    #board.setStyleSheet('background-color: pink')
  4. The test = QLabel('test') wasn't added to the grid layout.

    grid.addWidget(test, 2, 1, 10, 10)

After having fixed all of this, the (modified) source was this:

#!/usr/bin/python3

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

class MainGrid(QWidget):

def __init__(self):
super().__init__()
self.initGrid()

def initGrid(self):
grid= QGridLayout()

test = QLabel('test')
#board = Board()
#clock = Clock()
clock = QLabel('Clock')
#board.setStyleSheet('background-color: pink')
test.setStyleSheet('background-color: pink')
clock.setStyleSheet('background-color: blue')

grid.addWidget(test, 2, 1, 10, 10)
grid.addWidget(clock, 13, 4, 3, 3)

self.setLayout(grid)


class MainWin(QMainWindow):

def __init__(self):
super().__init__()
self.initUI()

def initUI(self):
centralGrid = MainGrid()
centralGrid.setStyleSheet('background-color: red')
centralGrid.sizeHint()
self.setCentralWidget(centralGrid)

self.setGeometry(200, 100, 1000, 600)
self.setWindowTitle('Simple Checkers')
self.show()

if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
gui = MainWin()
sys.exit(app.exec_())

Note:

I added the "hut" in the first line

#!/usr/bin/python3

for my own convenience.

Then I ran it in cygwin64 (because I only had Windows 10 with cygwin at hand):

$ chmod a+x testQMainWindowCentralWidget.py

$ ./testQMainWindowCentralWidget.py

and got:

snapshot of ./testQMainWindowCentralWidget.py

Now, the QMainWindow.setCentralWidget() works as expected.

I don't know which issues the OP actually ran in.

I'm not sure whether the exposed code of OP was the exact copy/paste and the missing details were the actual source of OP's problems.

When I tried to make it running I carefully considered the trace-backs I got in the first attempts and fixed the bugs step-by-step respectively until I got the above result.

Wrong layout in QMainWindow?

When you pass the parent to a QWidget this will locate a position with respect to its parent and generate widgets like the ones you have obtained, to solve this, layouts are used, QMainWindow is a special QWidget since it has predefined elements, so it already has a layout:

Sample Image

In QMainWindow the widget must be added to the centralwidget with the setCentralWidget function, in your case:

class MyApp(QMainWindow):
"""Main application class"""
def __init__(self, parent=None):
super().__init__(parent)
self.initUi()

def initUi(self):
[...]
centralWidget = Main(self)
self.setCentralWidget(centralWidget)

complete code:

class Main(QWidget):
"""The main widget with label and LineEdit"""
def __init__(self, parent=None):
super().__init__(parent)
self.initUi()

def initUi(self):
"""Initialize the UI of the main widget"""
self.mySourceLabel = QLabel("Select your file:")
self.mySourceLine = QLineEdit()
self.mySourceLine.setPlaceholderText("File name here")

# Set layout
grid = QGridLayout()
#grid.setSpacing(5)
grid.addWidget(self.mySourceLabel, 0, 0)
grid.addWidget(self.mySourceLine, 1, 0)
self.setLayout(grid)

class MyApp(QMainWindow):
"""Main application class"""
def __init__(self, parent=None):
super().__init__(parent)
self.initUi()

def initUi(self):
"""Initialize UI of an application"""
# main window size, title
self.setGeometry(400, 300, 400, 300)
self.setWindowTitle("Version upgrade ")

# create central widget, create grid layout
centralWidget = Main(self)
self.setCentralWidget(centralWidget)

Screenshot:

Sample Image

Adding QWidget into QGridLayout adds border to layout?

Look into Qt's stylesheets. You should be able to style your QTableWidget in any way you want to.

Keep in mind a QTableWidget is specialized version of QTableView, so you have set your stylesheet to a QTableView:

m_table->setStyleSheet("QTableView {background: transparent; border: 1px solid green;}");

Here are some links to get you started with Qt stylesheets:

https://doc.qt.io/qt-5/stylesheet.html

https://doc.qt.io/qt-5/stylesheet-syntax.html

https://doc.qt.io/qt-5/stylesheet-examples.html

Opening new Window having grid layout in Pyqt5

Try it:

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

### global variables
# global memorysize # ---
# global numberofholes # ---
###


class Window(QWidget):
def __init__(self,parent=None):
super(Window,self).__init__(parent)
self.setWindowTitle("Memory 1")
self.setGeometry(50, 50, 500, 300)
self.home()

def home(self):
self.grid = QGridLayout()
self.setLayout(self.grid)

self.memory = QLabel(self)
self.memory.setText("Total Memory size")
self.grid.addWidget(self.memory, 0, 0)

self.memoryinput = QLineEdit(self)
self.grid.addWidget(self.memoryinput, 0, 20)

self.holes = QLabel(self)
self.holes.setText("Number of holes")
self.grid.addWidget(self.holes, 5, 0)

self.inputholes = QLineEdit(self)
self.grid.addWidget(self.inputholes, 5, 20)

self.submit = QPushButton("OK", self)
self.grid.addWidget(self.submit, 10, 0)

# Action on clicking submit
self.submit.clicked.connect(self.getholes)

def getholes(self):
memorysize = float(self.memoryinput.text())
numberofholes = int(self.inputholes.text())
self.hide() # --- close()
self.window2 = Window2(memorysize, numberofholes) # --- self
self.window2.show()


# second window for holes input
class Window2(QWidget): # --- QMainWindow,
def __init__(self, memorysize, numberofholes, parent=None):
super().__init__(parent)

self.memorysize, self.numberofholes = memorysize, numberofholes
print("memorysize=`{}`,\nnumberofholes=`{}`".format(self.memorysize, self.numberofholes))

self.setWindowTitle("Memory 2")
self.setGeometry(50,50,500,300)
self.home()
self.show()

def home(self):
self.grid = QGridLayout()
self.setLayout(self.grid)
print(self.numberofholes)

for n in range (2):
self.start_add = QLabel(self)
self.start_add.setText("Starting Address")

self.inputstart = QLineEdit(self)

self.size = QLabel(self)
self.size.setText("Size")

self.inputsize = QLineEdit(self)

self.grid.addWidget(self.start_add, 2*n+1, 0)
self.grid.addWidget(self.inputstart,2*n+1, 1)
self.grid.addWidget(self.size, 2*n+1, 2)
self.grid.addWidget(self.inputsize, 2*n+1, 3)

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

Sample Image

Qt Layout on QMainWindow

You don't have to create a QVBoxLayout manually. Just select your central QWidget and press a make-layout button.

alt text



Related Topics



Leave a reply



Submit