Python Forum
Displaying various layouts in a single window
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Displaying various layouts in a single window
#1
Hi

I try to have several layouts displayed in a single window. I don't know the best way to do so, maybe should I remove all widgets of the current display and create the widgets of the new one. As I don't know how to do that, I decided to set the central widget of a main window to layouts defined as objets. To try this method, I coded the following script.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
source='/home/remi/Documents/programmation/python_env/essai/racine.py'
#  
#  Copyright 2020 Rémi Mathieu <remi@remi-Vostro-3550> 
# 

from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QApplication, QHBoxLayout, QVBoxLayout,  QPushButton
from functools import partial

class Racine(QMainWindow):
	def __init__(self):
		super(Racine,self).__init__()
	def init(self, label, localRange):
		self.setObjectName=label
		self.setWindowTitle(label)
		self.setGeometry(localRange[0],localRange[1],localRange[2],localRange[3])
		self.a=A()
		self.a.init('A',self)
		self.b=B()
		self.b.init('B',self)
		
class A(QtWidgets.QWidget):
	def __init__(self):
		super(A,self).__init__()
		self.lesboutons=[('A','a', True), ('B', 'b', False), ('Act_B', 'act_b', True)]
		zs=QHBoxLayout(self)
		for libellé, signal, actif in self.lesboutons:
			btn=qpb(self, libellé, signal, actif, zs, False)
			btn.clicked.connect(partial(self.execut, signal))
	def init(self,label,appli):
		self.appli=appli
		self.label=label
	def act(self):
		auto=self.appli.a
		self.appli.setWindowTitle(auto.label)
		self.appli.setCentralWidget(auto)
	def execut(self, code):
		print ('A ' + code)
		if code=='act_b':
			self.findChild(QtWidgets.QPushButton,code).setEnabled(True)
			self.findChild(QtWidgets.QPushButton,'a').setEnabled(False)
			self.appli.b.act()
		
class B(QtWidgets.QWidget):
	def __init__(self):
		super(B,self).__init__()
		self.lesboutons=[('A','a', False), ('B', 'b', True), ('Act_A', 'act_a', True)]
		zs=QHBoxLayout(self)
		for libellé, signal, actif in self.lesboutons:
			btn=qpb(self, libellé, signal, actif, zs, False)
			btn.clicked.connect(partial(self.execut, signal))
	def init(self,label,appli):
		self.appli=appli
		self.label=label
	def act(self):
		auto=self.appli.b
		self.appli.setWindowTitle(auto.label)
		self.appli.setCentralWidget(auto)
#		self.appli.show()	
	def execut(self, code):
		print ('B ' + code)
		if code=='act_a':
			self.findChild(QtWidgets.QPushButton,code).setEnabled(True)
			self.findChild(QtWidgets.QPushButton,'a').setEnabled(False)
			self.appli.a.act()

def qpb(self, title, name, active, qlay, stretch=True):
	btn=QPushButton(title)
	btn.setObjectName(name)
	btn.setEnabled(active)
	qlay.addWidget(btn)
	if stretch:
		lay.addStretch()
	return btn
		
def main(args):
	app = QtWidgets.QApplication(args)
	application=Racine()
	application.init("Racine", [250,200,800,300])
	application.setCentralWidget(application.a)
	application.show()
	app.exec()
	return 0

if __name__ == '__main__':
	import sys
	main(sys.argv)
	sys.exit()
When I click on "Act_B" button in the A layout, the B layout is display. But, when I click on the "Act_A" of the B layout, I get the following error :

Error:
Traceback (most recent call last): File "/home/remi/Documents/programmation/python_env/essai/racine.py", line 68, in execut self.appli.a.act() File "/home/remi/Documents/programmation/python_env/essai/racine.py", line 39, in act self.appli.setCentralWidget(auto) RuntimeError: wrapped C/C++ object of type A has been deleted Abandon (core dumped)
Thank you for giving me a help.

Arbiel
Reply
#2
I remember Qt having some sort of stacked layout widget thst should work well for this.
Reply
#3
Hi deanhystad

Thank you.

Your answer led me to tutorialpoint.com pages where I found valuable pieces of information. I did not yet test, but I understand now how to achieve my goal.

Arbiel
Reply
#4
https://www.learnpyqt.com/courses/start/layouts/

an example

from PyQt5.QtWidgets import QMainWindow, QApplication, QTabWidget, QStackedLayout, QWidget
from PyQt5.QtGui import QPalette, QColor


class Color(QWidget):

    def __init__(self, color, *args, **kwargs):
        super(Color, self).__init__(*args, **kwargs)
        self.setAutoFillBackground(True)
        
        palette = self.palette()
        palette.setColor(QPalette.Window, QColor(color))
        self.setPalette(palette)
        
        
class MainWindow(QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        
        self.setWindowTitle("My Awesome App")


        tabs = QTabWidget()
        tabs.setDocumentMode(True)
        tabs.setTabPosition(QTabWidget.East)
        tabs.setMovable(True)

        for n, color in enumerate(['red','green','blue','yellow']):
            tabs.addTab( Color(color), color)

        self.setCentralWidget(tabs)
        self.setGeometry(50, 50, 300, 400)
        
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    win = MainWindow()
    win.setWindowTitle("QStackedLayout")
    win.show()
    sys.exit(app.exec_())
Reply
#5
Hi Axel

I thank you for your input.

However, the example you posted does not exactly answer my issue. It allows for the changing of the color of the background of a widget, when my issue is to completely modify its layout.

Thank you anyway, any example is good to understand a little better how to code a gui.

Arbiel
Reply
#6
Axel's code demonstrates how to use a QTabWidget. There is no changing background colors. Each time you see a different color it is because that is a different widget and you are seeing a different widget because the QTabWidget hid the previous widgets and is exposing new widgets. This is exactly what you were talking about.
Reply
#7
Hi

Ok. Thank you for the correction. After a while, I eventually understood the use I can do of QTabWidget, itself being possibly stacked into a QStackedWidget.

Arbiel
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Interaction between Matplotlib window, Python prompt and TKinter window NorbertMoussy 3 348 Mar-17-2024, 09:37 AM
Last Post: deanhystad
Star [PyQt] Python GUI - PyQt Containers and Layouts Explained panofish 0 912 Aug-28-2022, 07:29 PM
Last Post: panofish
  [Tkinter] Tk window not displaying until loop has completed Ganga 8 15,167 Aug-09-2021, 06:42 PM
Last Post: Ganga
  tkinter window and turtle window error 1885 3 6,625 Nov-02-2019, 12:18 PM
Last Post: 1885
  [Tkinter] Call a function when switching layouts 4096 0 3,507 Sep-22-2019, 07:39 PM
Last Post: 4096
  update a variable in parent window after closing its toplevel window gray 5 8,979 Mar-20-2017, 10:35 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020