Как сделать кнопку «Готово» в QStackedWidget

#python-3.x #pyqt5 #qstackedwidget

#python-3.x #pyqt5 #qstackedwidget

Вопрос:

Я пытаюсь создать кнопку «Готово» в QStackedWidget.

В функции «checkButtons» я проверяю индекс текущей страницы и устанавливаю события нажатия и текст. Я пытался проверить это по имени класса, но это тоже не работает.

Вот код:

 import sys

from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QDialog, QComboBox, QStackedWidget, QWidget,
            QPushButton, QLabel, QVBoxLayout, QHBoxLayout, QStyle)


class Main(QDialog):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        # Main window setup
        self.setWindowTitle("Stacked widget example")
        self.setWindowIcon(self.style().standardIcon(QStyle.SP_FileDialogNewFolder))
        self.setMinimumSize(400, 400)
        self.setMaximumSize(640, 480)

        self.rootVBox = QVBoxLayout()
        self.rootHBox = QHBoxLayout()
        self.rootHBox.addStretch()
        self.rootVBox.addStretch()

        self.pages = [FirstPage, SecondPage]
        self.stacked = QStackedWidget(self)
        for i in self.pages: self.stacked.addWidget(i(self))

        self.pageState = True
        self.buttonNext = QPushButton("Next")
        self.buttonNext.clicked.connect(self.buttonNextConnect)

        self.buttonBack = QPushButton("Back")
        self.buttonBack.clicked.connect(self.buttonBackConnect)

        self.rootHBox.addWidget(self.buttonBack)
        self.rootHBox.addWidget(self.buttonNext)

        self.rootVBox.addLayout(self.rootHBox)
        self.setLayout(self.rootVBox)

    def checkButtons(self):
        print(self.stacked.currentIndex())

        # I tried to check self.stacked.currentIndex() but it didn't work too
        # if self.stacked.currentWidget().__class__ == self.pages[-1]:
        if self.stacked.currentIndex() == len(self.pages) - 1:
            self.buttonNext.setText("Finish")
            self.buttonNext.clicked.connect(self.close)

        elif self.stacked.currentIndex() < len(self.pages) - 1:
            self.buttonNext.setText("Next")
            self.buttonNext.clicked.connect(self.buttonNextConnect)

    def buttonNextConnect(self):
        self.stacked.setCurrentIndex(self.stacked.currentIndex()   1)
        self.checkButtons()

    def buttonBackConnect(self):
        self.stacked.setCurrentIndex(self.stacked.currentIndex() - 1)
        self.checkButtons()

    def finish(self):
        self.close()


class FirstPage(QWidget):
    def __init__(self, parent=None):
        super(FirstPage, self).__init__(parent)
        label = QLabel("First page")
        rootVBox = QVBoxLayout()
        rootHBox = QHBoxLayout()

        rootHBox.addWidget(label)
        rootVBox.addLayout(rootHBox)
        self.setLayout(rootVBox)


class SecondPage(QWidget):
    def __init__(self, parent=None):
        super(SecondPage, self).__init__(parent)
        label = QLabel("Second page")
        rootVBox = QVBoxLayout()
        rootHBox = QHBoxLayout()

        rootHBox.addWidget(label)
        rootVBox.addLayout(rootHBox)
        self.setLayout(rootVBox)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = Main()
    main.show()

    sys.exit(app.exec_())
  

Если вы попытаетесь нажать «далее», «назад», а затем «далее» снова, программа будет закрыта. Итак, как я могу это исправить? Должен ли я просто создавать кнопки управления для каждого виджета?

Ответ №1:

Вы должны использовать сигнал currentChanged QStackedWidget, чтобы узнать, на какой странице вы находитесь, и, таким образом, изменить текст, но в слоте buttonNextConnect вы должны проверить, находитесь ли вы уже на последней странице, прежде чем переключаться на новую страницу, если вы затем вызываете, чтобы закончить, и если вы не переходите на другую страницу

 class Main(QDialog):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        # Main window setup
        self.setWindowTitle("Stacked widget example")
        self.setWindowIcon(self.style().standardIcon(QStyle.SP_FileDialogNewFolder))
        self.setMinimumSize(400, 400)
        self.setMaximumSize(640, 480)

        rootVBox = QVBoxLayout(self)
        rootHBox = QHBoxLayout()
        rootHBox.addStretch()
        rootVBox.addStretch()

        self.pages = [FirstPage, SecondPage]
        self.stacked = QStackedWidget(self)

        for i in self.pages: self.stacked.addWidget(i(self))

        self.buttonNext = QPushButton("Next")
        self.buttonNext.clicked.connect(self.buttonNextConnect)

        self.buttonBack = QPushButton("Back")
        self.buttonBack.clicked.connect(self.buttonBackConnect)

        rootHBox.addWidget(self.buttonBack)
        rootHBox.addWidget(self.buttonNext)

        rootVBox.addLayout(rootHBox)

        self.stacked.currentChanged.connect(self.on_currentChanged)

    def buttonNextConnect(self):
        if self.stacked.currentIndex() == self.stacked.count() -1:
            self.finish()
        if self.stacked.currentIndex() < self.stacked.count() -1:
            self.stacked.setCurrentIndex(self.stacked.currentIndex()   1)

    def buttonBackConnect(self):
        if self.stacked.currentIndex() > 0:
            self.stacked.setCurrentIndex(self.stacked.currentIndex() - 1)

    def on_currentChanged(self, index):
        if index == self.stacked.count() -1:
            self.buttonNext.setText("Finish")
        else:
            self.buttonNext.setText("Next")

    def finish(self):
        self.close()
  

Другой вариант — использовать QWizard и QWizardPage:

 import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class Main(QtWidgets.QWizard):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        buttons = [
            QtWidgets.QWizard.Stretch, 
            QtWidgets.QWizard.BackButton,
            QtWidgets.QWizard.NextButton, 
            QtWidgets.QWizard.FinishButton
        ]
        self.setButtonLayout(buttons)
        self.addPage(FirstPage())
        self.addPage(SecondPage())

class FirstPage(QtWidgets.QWizardPage):
    def __init__(self, parent=None):
        super(FirstPage, self).__init__(parent)
        self.setTitle("First page")

class SecondPage(QtWidgets.QWizardPage):
    def __init__(self, parent=None):
        super(SecondPage, self).__init__(parent)
        self.setTitle("Second page")

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