PyQt5 button gets clicked signal when appeared on screen through stacked widget setCurrentWidget

Viewed 69

I have an app with a window and QStackedWidget on it. The first page of the stacked widget disappears changes to the second on click(or touch). There is a button on the second page.

class AppLauncher(QtWidgets.QMainWindow, AppWindow.Ui_MainWindow):
    def __init__(self, parent=None):
        super(AppLauncher, self).__init__(parent)
        self.setupUi(self)
        self.iddle = True
        self.fooButton.clicked.connect(self.foo)

    def foo(self):
        pass

    def eventFilter(self, obj, event):
        if (event.type() == QEvent.TouchBegin or \
            event.type() == QEvent.TouchUpdate or \
            event.type() == QEvent.MouseButtonPress) and self.manager_initialised :
                
                if self.iddle:
                    self.stackedScreens.setCurrentWidget(self.buttonPage)

        return super(AppLauncher, self).eventFilter(obj, event)

def main():
    app = QApplication(sys.argv)
    form = AppLauncher()
    form.setAttribute(QtCore.Qt.WA_AcceptTouchEvents, True)
    form.installEventFilter(form)
    form.show()
    
    app.exec_()
    
if __name__ == '__main__':
    main()

It works OK but if I touch an area of the first page where the button on the second page located, pages change in a moment and the button appears under the finger. And when I take off my finger, the button gets "clicked" signal.
This happens so fast that even a fast tap on the first page fires the signal.
This potentially leads to users not understanding that they clicked on button after they touched the first page.

How can I solve this problem? I thought that a clicked signal is fired only if finger was put and taken off after button appears.

1 Answers

check for mouseButtonRelease

class AppLauncher(QtWidgets.QMainWindow, AppWindow.Ui_MainWindow):
    def __init__(self, parent=None):
        super(AppLauncher, self).__init__(parent)
        self.setupUi(self)
        self.iddle = True
        self.fooButton.clicked.connect(self.foo)

    def foo(self):
        pass

    def eventFilter(self, obj, event):
        if (event.type() == QEvent.TouchBegin or \
            event.type() == QEvent.TouchUpdate or \
            event.type() == QEvent.MouseButtonRelease) and self.manager_initialised :
                
                if self.iddle:
                    self.stackedScreens.setCurrentWidget(self.buttonPage)

        return super(AppLauncher, self).eventFilter(obj, event)

def main():
    app = QApplication(sys.argv)
    form = AppLauncher()
    form.setAttribute(QtCore.Qt.WA_AcceptTouchEvents, True)
    form.installEventFilter(form)
    form.show()
    
    app.exec_()
    
if __name__ == '__main__':
    main()
Related