Layout apilado QStackedLayout¶
Otra disposición que da mucho juego es apilar los widgets usando un QStackedLayout
:
from PySide6.QtWidgets import (
QApplication, QMainWindow, QLabel, QStackedLayout, QWidget)
import sys
class Caja(QLabel):
def __init__(self, color):
super().__init__()
self.setStyleSheet(f"background-color:{color}")
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# creamos un layout apilado
layout = QStackedLayout()
# Añadimos varios widgets unos sobre otros
layout.addWidget(Caja("orange"))
layout.addWidget(Caja("magenta"))
layout.addWidget(Caja("purple"))
layout.addWidget(Caja("red"))
# creamos el widget dummy y le asignamos el layout apilado
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
El problema de este layout es que necesita controladores.
Vamos a definir un evento que capture cuando presionamos las flechas del teclado para poder alternar entre los widgets. Los eventos ya existen en el widget, lo que haremos es sobreescribir su comportamiento:
from PySide6.QtCore import Qt # nuevo
def keyPressEvent(self, event):
# detectamos la flecha presionada
if event.key() == Qt.Key_Right:
print("Flecha derecha presionada")
elif event.key() == Qt.Key_Left:
print("Flecha izquierda presionada")
# continuamos con el evento por defecto
event.accept()
Ahora utilizaremos el método setCurrentIndex
del layout para controlar el widget que se muestra teniendo en cuenta que el índice empieza valiendo 0 y al tener 4 widgets su valor máximo será 3. Este numero máximo podemos conseguirlo contando los elementos del layout con su método count
.
Al presionar la flecha derecha incrementaremos el índice y con la izquierda lo decrementaremos. Para generar un efecto infinito si el índice es menor que cero lo estableceremos al máximo, si es mayor que el máximo lo estableceremos a cero:
# necesitamos crear un accesor para usar el layout desde el evento
self.layout = layout
def keyPressEvent(self, event):
# recuperamos el índice
indice = self.layout.currentIndex()
# buscamos el indice máximo del layout contando cuantos widgets tiene
indice_maximo = self.layout.count() - 1
# dependiendo de la flecha presionada sumamos o restamos
if event.key() == Qt.Key_Right:
indice += 1
elif event.key() == Qt.Key_Left:
indice -= 1
# rectificamos el índice para generar el efecto infinito
if indice > indice_maximo:
indice = 0
if indice < 0:
indice = indice_maximo
# finalmente establecemos el nuevo índice
self.layout.setCurrentIndex(indice)
# continuamos con el evento por defecto
event.accept()
En este experimento hemos introducido los eventos
, pero podríamos haber utilizado unos botones para cambiar de índice sin problema.
Última edición: 22 de Marzo de 2021