首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QtWidgets.QStackedWidget()的意外行为

QtWidgets.QStackedWidget()的意外行为
EN

Stack Overflow用户
提问于 2020-07-10 12:48:28
回答 1查看 32关注 0票数 0

我想使用pyqt5创建一个GUI,它在两个窗口(即WindowA和WindowB )之间来回切换。为了达到这个目的,我

  • 为WindowA创建了一个类,为WindowB创建了另一个类,每个类中都有一个按钮
  • 创建一个mainWindow类,它实例化一个类型为WindowA的对象和另一个类型为WindowB的对象,并将这两个对象添加到堆栈中。根据pyqt文档的说法

“QStackedWidget类提供了一个小部件堆栈,每次只能看到一个小部件。”

  • 在mainWindow类中定义两个方法,LaunchA和LaunchB,分别使用setCurrentWidget()方法将当前小部件设置为A或B,并在单击按钮时调用另一个方法。

头几次,效果很好。我点击按钮A,它带来窗口B。我点击按钮B,它带我回到窗口A。但是在那之后它开始注册多次点击,就好像我一次点击了当前按钮和所有先前显示的按钮。我不知道怎么解决这个问题。这是一个(最小的?)可再现的例子,显示了问题。我还实现了一个函数,它计算按下按钮的次数,这样您就可以看到预期结果和实际结果之间的差异。

代码语言:javascript
复制
import sys 
from PyQt5 import QtWidgets, QtCore
from PyQt5.Qt import QAction, QMenu


class WindowA(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(WindowA, self).__init__(parent)
        self.buttonA = QtWidgets.QPushButton("Button A - Press me!")
        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.buttonA)
        self.buttonA.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        layout.setContentsMargins(0,0,0,0)
        layout.setSpacing(1)
        self.setLayout(layout)
    def whenButtonPressed(self, count):
        print("Button A pressed. Total buttons pressed: " + str(count))

class WindowB(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(WindowB, self).__init__(parent)
        self.buttonB = QtWidgets.QPushButton("Button B - Press me!")
        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.buttonB)
        self.buttonB.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        layout.setContentsMargins(0,0,0,0)
        layout.setSpacing(1)
        self.setLayout(layout)
    def whenButtonPressed(self, count):
        print("Button B pressed. Total buttons pressed: " + str(count))

class mainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(mainWindow, self).__init__(parent)
        self.setGeometry(850, 250, 300, 150)
        self.count = 0
        # Instantiating the classes of each window and adding them to the stack
        self.__A = WindowA()
        self.__B = WindowB()
        self.__stack = QtWidgets.QStackedWidget(self)
        self.__stack.addWidget(self.__A)
        self.__stack.addWidget(self.__B)
        self.__stack.setContentsMargins(1,1,1,1)
        self.setCentralWidget(self.__stack)
        self.launchA()
    def launchA(self):
        self.__stack.setCurrentWidget(self.__A)
        self.__stack.currentWidget().buttonA.clicked.connect(lambda: self.printAndChange())
        self.show()
    def launchB(self):
        self.__stack.setCurrentWidget(self.__B)
        self.__stack.currentWidget().buttonB.clicked.connect(lambda: self.printAndChange())
        self.show()
    def printAndChange(self):
        self.count += 1
        self.__stack.currentWidget().whenButtonPressed(self.count)
        if isinstance(self.__stack.currentWidget(), WindowA) == True : 
            self.launchB()
        elif isinstance(self.__stack.currentWidget(), WindowA) == False:
            self.launchA()


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    app.setStyle('Fusion')
    w = mainWindow()
    sys.exit(app.exec_())
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-10 13:38:20

你在错误的地方连接对象-信号插槽。试一试:

代码语言:javascript
复制
import sys 
from PyQt5 import QtWidgets, QtCore
from PyQt5.Qt import QAction, QMenu


class WindowA(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(WindowA, self).__init__(parent)
        self.buttonA = QtWidgets.QPushButton("Button A - Press me!")
        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.buttonA)
        self.buttonA.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        layout.setContentsMargins(0,0,0,0)
        layout.setSpacing(1)
        self.setLayout(layout)
        
    def whenButtonPressed(self, count):
        print("Button A pressed. Total buttons pressed: " + str(count))


class WindowB(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(WindowB, self).__init__(parent)
        self.buttonB = QtWidgets.QPushButton("Button B - Press me!")
        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.buttonB)
        self.buttonB.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        layout.setContentsMargins(0,0,0,0)
        layout.setSpacing(1)
        self.setLayout(layout)
        
    def whenButtonPressed(self, count):
        print("Button B pressed. Total buttons pressed: " + str(count))


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        
        self.setGeometry(850, 250, 300, 150)
        self.count = 0
        # Instantiating the classes of each window and adding them to the stack
        self.__A = WindowA()
        self.__A.buttonA.clicked.connect(lambda: self.printAndChange())       # +++
                
        self.__B = WindowB()
        self.__B.buttonB.clicked.connect(lambda: self.printAndChange())       # +++
        
        self.__stack = QtWidgets.QStackedWidget(self)
        self.__stack.addWidget(self.__A)
        self.__stack.addWidget(self.__B)
        self.__stack.setContentsMargins(1, 1, 1, 1)
        self.setCentralWidget(self.__stack)
        self.launchA()
        
    def launchA(self):
        self.__stack.setCurrentWidget(self.__A)
#        self.__stack.currentWidget().buttonA.clicked.connect(lambda: self.printAndChange())
        self.show()
        
    def launchB(self):
        self.__stack.setCurrentWidget(self.__B)
#        self.__stack.currentWidget().buttonB.clicked.connect(lambda: self.printAndChange())
        self.show()
        
    def printAndChange(self):
        self.count += 1
        self.__stack.currentWidget().whenButtonPressed(self.count)
        if isinstance(self.__stack.currentWidget(), WindowA) == True : 
            self.launchB()
        elif isinstance(self.__stack.currentWidget(), WindowA) == False:
            self.launchA()


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    app.setStyle('Fusion')
    w = MainWindow()
    sys.exit(app.exec_())
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62834671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档