Неожиданное поведение QtWidgets.QStackedWidget () - PullRequest
0 голосов
/ 10 июля 2020

Я хочу создать GUI, используя pyqt5, который переключается между двумя windows, а именно WindowA и WindowB. Для этого я

  • создал класс для WindowA и другой класс для WindowB, с кнопкой в ​​каждом.
  • Создал класс mainWindow, который создает экземпляр объекта введите WindowA и еще один типа WindowB, и добавили оба объекта в стек. Согласно документации pyqt ,

«Класс QStackedWidget предоставляет стек виджетов, в котором одновременно виден только один виджет».

  • Определены два метода внутри класса mainWindow, LaunchA и LaunchB, которые устанавливают текущий виджет на A или B соответственно с помощью метода setCurrentWidget () и вызывают другой при нажатии кнопки.

Первые пару раз работает нормально. Я нажимаю кнопку A, она переходит в окно B. Я нажимаю кнопку B, она возвращает меня в окно A. Однако после этого начинается регистрация нескольких щелчков, как если бы я нажал текущую кнопку и все ранее показанные одновременно. Не знаю, как это исправить. Вот (минимальный?) Воспроизводимый пример, демонстрирующий проблему. Я также реализовал функцию, которая подсчитывает, сколько раз были нажаты кнопки, чтобы вы могли видеть разницу между ожидаемым результатом и фактическим результатом.

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_())

1 Ответ

0 голосов
/ 10 июля 2020

вы находитесь не в том месте, связывая объект-сигнал-слот. Попробуйте:

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_())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...