Home > PyQt5, python > PyQt5: QStackedWidget

PyQt5: QStackedWidget

2 Aprile 2019

Torna all’indice degli appunti
QStackedWidget

Lo StackedWidget mette a disposizione una pila di widget visibili solo uno alla volta.
Immaginiamolo come un mazzo di carte una sopra l’altra.
Quando si crea lo StackedWidget con il costruttore QStackedWidget, inizialmente è vuoto e va di conseguenza popolato.
Quando vengono aggiunti i widgets, questi finiscono in una lista interna all’oggetto StackedWidget.

I metodi principali sono:

addWidget(widget):
aggiunge il widget in fondo alla lista del QStackedWidget, ritornando l’indice della posizione di inserimento.
Se al momento dell’inserimento, la lista del QStackedWidget è vuota, il widget aggiunto diventa il
current widget

>>> from PyQt5.QtWidgets import QApplication, QStackedWidget, QLabel
>>> app = QApplication([])
>>> sw = QStackedWidget()
>>> sw.addWidget(QLabel("Label 1"))
0

addWidget esegue un append sulla lista interna, infatti:

>>> sw.addWidget(QLabel("Label 2"))
1

Per ottenere il current widget quindi si utilizza il metodo currentwidget:

>>> current = sw.currentWidget()
>>> current.text()
'Label 1

Notare che il current widget rimane il primo inserito fino a che non lo si modifica tramite il metodo setCurrentWidget(widget).
Per ottenere un widget dalla lista interna del QStackedWidget si utilizza il metodo widget(index):

>> label2 = sw.widget(1)
>>> label2.text()
'Label 2'
>>> sw.setCurrentWidget(label2)
>>> sw.currentWidget().text()
'Label 2'

insertWidget(index, widget)
inserisce il widget all’indice dato. Se l’indice dato è “out of range”, viene effettuato l’append.
Come per addWidget, se la lista è vuota, il widget diventa il current widget.

>>> for index in range(sw.count()):
...     print("[{}] {}".format(index, sw.widget(index).text()))
...     
[0] Label 1
[1] Label 2
>>> sw.insertWidget(1, QLabel("Label 3"))
1
>>> for index in range(sw.count()):
...     print("[{}] {}".format(index, sw.widget(index).text()))
...     
[0] Label 1
[1] Label 3
[2] Label 2

removeWidget(widget)

Rimuove il widget passato come argomento. Il widget non viene cancellato, ma solo rimosso dallo stacked widget.
In caso si volesse riutilizzarlo ricordarsi di riassegnargli il parent!

>>> label3 = sw.widget(1)
>>> sw.removeWidget(label3)
>>> for index in range(sw.count()):
...     print("[{}] {}".format(index, sw.widget(index).text()))
...     
[0] Label 1
[1] Label 2

currentIndex:
simile a currentWidget ma invece che ritornare il widget corrente, ne ritorna l’indice:

>>> sw.currentWidget()
<PyQt5.QtWidgets.QLabel object at 0x0363D3A0>
>>> sw.currentIndex()
1

setCurrentIndex(index):
simile a setCurrentWidget ma invece che settare il widget corrente, via widget, lo setta via indice:

>>> sw.currentIndex()
1
>>> sw.setCurrentIndex(0)
>>> sw.currentIndex()
0
>>> sw.currentWidget().text()
'Label 1'

count:
ritorna il numero di widget della lista interna al QStackedWidget.

indexOf(widget):
ritorna l’indice del widget passato come argomento o -1 se non lo trova in lista:

>>> sw.indexOf(label1)
0
>>> sw.indexOf(label3)
-1

SEGNALI:

currentChanged(index): emesso quando il current widget cambia.
widgetRemoved(index): emesso quando un widget viene rimosso.

esempio:

import sys
from PyQt5.QtWidgets import (QMainWindow, QApplication, QPushButton, QWidget,
                             QLabel, QVBoxLayout, QStackedWidget, QComboBox)
from PyQt5.QtCore import Qt


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle("QStackedWidget Example")
        self.central_widget = FrameWidget(self)
        self.setCentralWidget(self.central_widget)
        self.resize(200, 200)


class FrameWidget(QWidget):
    def __init__(self, parent=None):
        super(FrameWidget, self).__init__(parent)
        self.count = 0

        self.stacked_w = QStackedWidget()
        self.stacked_w.setFixedSize(200, 50)

        self.combobox = QComboBox()
        self.combobox.activated.connect(self.stacked_w.setCurrentIndex)

        add_button = QPushButton('Add widget')
        add_button.clicked.connect(self.add_widget)

        insert_button = QPushButton('Insert widget')
        insert_button.clicked.connect(self.insert_widget)

        remove_button = QPushButton('Remove widget')
        remove_button.clicked.connect(self.remove_widget)

        self.stacked_w.currentChanged[int].connect(self.on_current_changed)
        self.stacked_w.widgetRemoved[int].connect(self.on_widget_removed)

        self.num_widgets_label = QLabel('{} widget(s)'.format(self.count))
        self.num_widgets_label.setAlignment(Qt.AlignCenter)

        layout = QVBoxLayout()
        layout.addWidget(self.combobox)
        layout.addWidget(self.stacked_w)
        layout.addStretch()
        layout.addWidget(add_button)
        layout.addWidget(insert_button)
        layout.addWidget(remove_button)
        layout.addWidget(self.num_widgets_label)
        self.setLayout(layout)

    def on_widget_removed(self, index):
        print("[SIG] Widget <%s> Removed!" % index)

    def on_current_changed(self, index):
        print("[SIG] Current Widget changed to <%s>" % index)

    def update_num_widgets(self, number):
        self.num_widgets_label.setText('{} widget(s)'.format(number))

    def add_widget(self):
        pag = self.count + 1
        index = self.stacked_w.addWidget(QLabel('Content {}'.format(pag)))
        self.combobox.addItem('Page {}'.format(pag))
        self.combobox.setCurrentIndex(index)
        self.stacked_w.setCurrentIndex(index)
        self.count += 1
        self.update_num_widgets(self.stacked_w.count())

    def insert_widget(self):
        pag = self.count + 1
        index = self.stacked_w.insertWidget(0, QLabel('Content {}'.format(pag)))
        self.combobox.insertItem(0, 'Page {}'.format(pag))
        self.combobox.setCurrentIndex(index)
        self.stacked_w.setCurrentIndex(index)
        self.count += 1
        self.update_num_widgets(self.stacked_w.count())

    def remove_widget(self):
        widget = self.stacked_w.currentWidget()
        if widget:
            self.combobox.removeItem(self.stacked_w.indexOf(widget))
            self.stacked_w.removeWidget(widget)
            self.update_num_widgets(self.stacked_w.count())


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

Torna all’indice degli appunti

Categorie:PyQt5, python Tag: ,
I commenti sono chiusi.