[SOLVED]:QWizardPage failing to update content.
-
Hello there.
In my application i am having a wizard. The layout on one of the pages depends on the choice the user makes in the previous page.
So, I want to allow the user to press the 'back' button and rethink his choice, which will change the layout of the next page.It works fine until the choice is actually changed. The next page doesn't change layout accordingly.
Here's what I mean:
@
global_num = 3
class Page1(QtGui.QWizardPage):
def init(self):
super().init()
self.setTitle('First Page')
layout = QtGui.QHBoxLayout()
btn = QtGui.QPushButton('Change State')def handler():
global global_num
global_num += 1btn.clicked.connect(handler)
layout.addWidget(btn)
self.setLayout(layout)class Page2(QtGui.QWizardPage):
def init(self):
super().init()
self.setTitle('Second Page')def initializePage(self):
layout = QtGui.QVBoxLayout()
self.setLayout(layout)
for i in range(0, global_num):
layout.addWidget(QtGui.QPushButton('Button %s' % i))wizard = QtGui.QWizard()
wizard.addPage(Page1())
wizard.addPage(Page2())
wizard.show()
@When the user clicks the button in the first page, it doesn't affect the structure on the second page, displaying more buttons in this case.
.iniatializePage() actually get called every time the page is viewed, but it doesn't seem to change anything beyond the first time page is shown.How can I get that to work?.
Thanks. -
Hi,
Don't you have an error about a layout already existing on your widget ?
In initializePage you try to replace the existing layout and buttons without removing the others already existing. I would set the layout in the init function so it's done only once, and only manage the buttons in initializePage, removing the old ones before creating the new ones.
Hope it helps
-
Thanks SGaist, it worked.
Here's a working version of the code just for reference:
@
from PySide import QtGui
import sysglobal_num = 3
class Page1(QtGui.QWizardPage):
def init(self):
super().init()
self.setTitle('First Page')
layout = QtGui.QHBoxLayout()
btn = QtGui.QPushButton('Change State')def handler():
global global_num
global_num += 1btn.clicked.connect(handler)
layout.addWidget(btn)
self.setLayout(layout)class Page2(QtGui.QWizardPage):
def init(self):
super().init()
self.setTitle('Second Page')
self.layout = QtGui.QVBoxLayout()
self.setLayout(self.layout)def initializePage(self):
for i in range(0, global_num):
self.layout.addWidget(QtGui.QPushButton('Button %s' % i))#when the user clicks Back button, erase page contents
def cleanupPage(self):
child = self.layout.takeAt(0)
while (child):
child.widget().deleteLater()
child = self.layout.takeAt(0)app = QtGui.QApplication(sys.argv)
wizard = QtGui.QWizard()
wizard.addPage(Page1())
wizard.addPage(Page2())
wizard.show()
app.exec_()
@And regarding the error, no errors were output.
-
Strange, a widget already having a layout should not let you changed it and IIRC shows a warning on the console.
Anyway, glad you have it working.
I thought about something: rather that using a global variable, did you had a look at the field/setField functions from QWizard/QWizardPage ? Might be a cleaner approach, i.e. using an invisible spin box to contain the number of buttons to show.
-
Sure, you simply have to make that a property to use the field concept.
-
I could get an int to be stored in a field, but not a list. I couldn't store a list, if i understand the "documentation":http://srinikom.github.com/pyside-docs/PySide/QtGui/QWizardPage.html#PySide.QtGui.PySide.QtGui.QWizardPage.registerField right, It seems only possible to store basic types such as int, str, bool, datetime as fields.
Anyway, here's my try :
@
from PySide import QtGui
import sys#global_num = 3
class Page1(QtGui.QWizardPage):
def init(self):
super().init()
self.setTitle('First Page')
layout = QtGui.QHBoxLayout()
btn = QtGui.QPushButton('Change State')
self.hiddenSpinBox = QtGui.QSpinBox()
self.registerField('list_field', self.hiddenSpinBox)
self.setField('list_field', [1,2,3])def handler():
self.setField('list_field', self.field('list_field').append('x'))btn.clicked.connect(handler)
layout.addWidget(btn)
self.setLayout(layout)class Page2(QtGui.QWizardPage):
def init(self):
super().init()
self.setTitle('Second Page')
self.layout = QtGui.QVBoxLayout()
self.setLayout(self.layout)def initializePage(self):
for i in range(0, len(self.field('list_field'))):
self.layout.addWidget(QtGui.QPushButton('Button %s' % i))#when the user clicks Back button, erase page contents
def cleanupPage(self):
child = self.layout.takeAt(0)
while (child):
child.widget().deleteLater()
child = self.layout.takeAt(0)app = QtGui.QApplication(sys.argv)
wizard = QtGui.QWizard()
wizard.addPage(Page1())
wizard.addPage(Page2())
wizard.show()
sys.exit(app.exec_())@
The code now tries to store a list named 'list_field' and appends a new element to it on every button press.It then uses the length of the list to determine how many buttons to create.
Any help would be appreciated.
-
IIRC you can use field with any type registered with QVariant, check the documentation about metatypes (I don't remember exactly how it works with python).
As for your problem, you are setting a list to a QSpinBox, it won't work. The QSpinBox user property is an int. You should be good with setField("list_field", 3)