0

I am trying to implement a Qwizard application using PyQt5 and I cannot figure out how to call different functions based on which next button is clicked. Apparently, next buttons belong to the Qwizard class and I cannot define specific behavior (like calling different functions) for them on each page. Here is an example:

import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class Window(QWizard):
    def __init__(self):
        super(Window, self).__init__()
        self.firstPage = Page1()
        self.secondPage = Page2()
        self.thirdPage = Page3()
        self.addPage(self.firstPage)
        self.addPage(self.secondPage)
        self.addPage(self.thirdPage)


class Page1(QWizardPage):
    def __init__(self, parent=None):
        super(Page1, self).__init__(parent)
        self.setTitle('''Page 1 Title''')
        self.vLayout = QVBoxLayout()
        self.lineEdit = QLineEdit()
        self.vLayout.addWidget(self.lineEdit)
        self.setLayout(self.vLayout)
        self.registerField('p1_lineEdit*', self.lineEdit, self.lineEdit.text(), self.lineEdit.textChanged)

    def f1(self):
        print("f1")
        if(len(self.lineEdit.text()) < 10):
            self.lineEdit.setText("0" * (10 - len(self.lineEdit.text())) + self.lineEdit.text())
    def validatePage(self):
        self.f1()
        return super(Page1, self).validatePage()

class Page2(QWizardPage):
    def __init__(self):
        super(Page2, self).__init__()
        self.setTitle('''Page 2 Title''')
        self.vLayout = QVBoxLayout()
        self.textBrowser = QTextBrowser()
        self.vLayout.addWidget(self.textBrowser)

        text = f'''Please make sure the provided number: {self.field('p1_lineEdit')} that you previously indicated, is valid.'''
        self.textBrowser.setText(text)
        self.setLayout(self.vLayout)

    def f2(self):
        print("f2")
        print(self.field('p1_lineEdit'))
    def validatePage(self):
        self.f2()
        return super(Page2, self).validatePage()

class Page3(QWizardPage):
    def __init__(self):
        super(Page3, self).__init__()
        self.setTitle('''Page 3 Title''')
    def f3(self):
        print("f3")
    def validatePage(self):
        self.f3()
        return super(Page3, self).validatePage()

def main():
    app = QApplication(sys.argv)
    app.setStyle('plastique')

    window = Window()
    window.setWizardStyle(1)
    window.show()
    app.exec_()

if __name__ == "__main__":
    sys.exit(main())

How can I differentiate next button behavior based on QwizardPage rather than Qwizard? Let's say I want f1() be called after pressing next button on page1, f2 after pressing next button on page 2 and f3() after page3.

UPDATE: I am adding the edited question following the guides about minimal reproducible example and XY problem. I'm trying to validate user inputs on the specific wizard pages after the next button is clicked and use those for populating subsequent pages. Here I'm asking for an input on page 1, pretending it if short and inserting it in the middle of a text in a text browser on page 2. However, I see None in place of registered field p1_lineEdit inside the text browser on page 2, but when I print it in f2() before moving to page 3, I see the correct value. I want the user to observe the correct value when page 2 loads.

import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class Window(QWizard):
    def __init__(self):
        super(Window, self).__init__()
        self.firstPage = Page1()
        self.secondPage = Page2()
        self.thirdPage = Page3()
        self.addPage(self.firstPage)
        self.addPage(self.secondPage)
        self.addPage(self.thirdPage)


class Page1(QWizardPage):
    def __init__(self, parent=None):
        super(Page1, self).__init__(parent)
        self.setTitle('''Page 1 Title''')
        self.vLayout = QVBoxLayout()
        self.lineEdit = QLineEdit()
        self.vLayout.addWidget(self.lineEdit)
        self.setLayout(self.vLayout)
        self.registerField('p1_lineEdit*', self.lineEdit, self.lineEdit.text(), self.lineEdit.textChanged)

    def f1(self):
        print("f1")
        if(len(self.lineEdit.text()) < 10):
            self.lineEdit.setText("0" * (10 - len(self.lineEdit.text())) + self.lineEdit.text())
    def validatePage(self):
        self.f1()
        return super(Page1, self).validatePage()

class Page2(QWizardPage):
    def __init__(self):
        super(Page2, self).__init__()
        self.setTitle('''Page 2 Title''')
        self.vLayout = QVBoxLayout()
        self.textBrowser = QTextBrowser()
        self.vLayout.addWidget(self.textBrowser)

        text = f'''Please make sure the provided number: {self.field('p1_lineEdit')} that you previously indicated, is valid.'''
        self.textBrowser.setText(text)
        self.setLayout(self.vLayout)

    def f2(self):
        print("f2")
        print(self.field('p1_lineEdit'))
    def validatePage(self):
        self.f2()
        return super(Page2, self).validatePage()

class Page3(QWizardPage):
    def __init__(self):
        super(Page3, self).__init__()
        self.setTitle('''Page 3 Title''')
    def f3(self):
        print("f3")
    def validatePage(self):
        self.f3()
        return super(Page3, self).validatePage()

def main():
    app = QApplication(sys.argv)
    app.setStyle('plastique')

    window = Window()
    window.setWizardStyle(1)
    window.show()
    app.exec_()

if __name__ == "__main__":
    sys.exit(main())
  • 1
    I have a question: Since the objective of pressing the "next button" is to change the page then my question is: do you want to execute that function before or after the page change? Does the result of this function influence if you change the page or not? – eyllanesc Jul 06 '20 at 17:11
  • The point of functions is to process some data on the current page and register fields based on this processed data so that they can be used to populate elements like line edit or text browser on the next page, but the problem is those fields are populated on init in the next page and the registered fields are None at that time. I don't know if I'm on the right track or should I do something differently. – NCheli Seril Jul 06 '20 at 18:46
  • Clearly you have an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem), instead of asking the underlying objective of your questions for a possible solution, I recommend rewriting your question and providing a better [MRE] – eyllanesc Jul 06 '20 at 19:02
  • Ok, I edited the code. Note that the text browser on page 2 shows None in place of p1_lineEdit when setting its text but in f2 (i.e. after the next on page 2 clicked?) the print outs the correct value. – NCheli Seril Jul 06 '20 at 20:38
  • please don't override your initial question but add it to the end, at the end explain the problem you have with that code. Also read [ask] and review [tour] – eyllanesc Jul 06 '20 at 20:44
  • Thanks! I added the edits as a new post. – NCheli Seril Jul 06 '20 at 22:18

1 Answers1

0

If you want to execute a function when the "Next" button is pressed, then you must use the validatePage() method that is called after pressing the button to validate whether to change the page or not:

import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *


class Window(QWizard):
    def __init__(self):
        super(Window, self).__init__()
        self.firstPage = Page1()
        self.secondPage = Page2()
        self.thirdPage = Page3()
        self.addPage(self.firstPage)
        self.addPage(self.secondPage)
        self.addPage(self.thirdPage)


class Page1(QWizardPage):
    def validatePage(self):
        self.f1()
        return super(Page1, self).validatePage()

    def f1(self):
        print("f1")


class Page2(QWizardPage):
    def validatePage(self):
        self.f2()
        return super(Page2, self).validatePage()

    def f2(self):
        print("f2")


class Page3(QWizardPage):
    def validatePage(self):
        self.f3()
        return super(Page3, self).validatePage()

    def f3(self):
        print("f3")


def main():
    app = QApplication(sys.argv)
    app.setStyle("plastique")

    window = Window()
    window.setWizardStyle(1)
    window.show()
    app.exec_()


if __name__ == "__main__":
    sys.exit(main())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241