如何在 QStackedWidget 中制作 "finish" 按钮
How to make "finish" button in QStackedWidget
我正在尝试在 QStackedWidget 中创建 "Finish" 按钮。
在 "checkButtons" 函数中,我检查当前页面索引并设置点击事件和文本。我试图通过 class 名称来检查它,但它也不起作用。
这是一个代码:
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_())
如果您尝试按 "next"、"back" 然后再按 "next",程序将关闭。那么,我该如何解决呢?我应该为每个小部件制作控制按钮吗?
您必须使用 QStackedWidget 的 currentChanged 信号来知道您在哪个页面上,从而更改文本,但是在 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_())
我正在尝试在 QStackedWidget 中创建 "Finish" 按钮。
在 "checkButtons" 函数中,我检查当前页面索引并设置点击事件和文本。我试图通过 class 名称来检查它,但它也不起作用。
这是一个代码:
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_())
如果您尝试按 "next"、"back" 然后再按 "next",程序将关闭。那么,我该如何解决呢?我应该为每个小部件制作控制按钮吗?
您必须使用 QStackedWidget 的 currentChanged 信号来知道您在哪个页面上,从而更改文本,但是在 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_())