问题不在于您从下一个返回后返回该页面时,因为始终调用initializePage(),无论“上一个”页面是页面索引中的上一个还是下一个(这是有道理的,因为页面顺序并不总是必须遵循“普通索引顺序”,因为它是从QWizard.nextId() 返回的,默认情况下调用当前页面的QWizardPage.nextId(),甚至可以返回一个小于当前)。
也就是说,在一种情况下,initializePage() 只被调用一次,如果你设置了QWizard.IndependentPages 选项,就会发生这种情况。如果你真的需要使用它,我认为唯一的选择是通过覆盖页面的 showEvent(event) 和 only if not event.spontaneous() 来设置值(否则即使页面是最小化后再次显示)。
这里真正重要的是项目委托的复选框通常显示如果为其索引设置了Qt.CheckStateRole,因为设置Qt.ItemIsUserCheckable仅意味着用户可以设置项目状态,不复选框可见。
事实上,除非某些特定的 OS/QtStyle 起作用,否则设置该标志根本不会产生任何影响,即使发生这种情况,一旦检查状态设置为三种状态中的任何一种(未检查、部分检查或选中)不会有任何区别:无论如何都会显示。
虽然这看起来有点违反直觉,但从 source code 可以清楚地看出它的行为,其中 StyleOptionViewItem 功能 HasCheckIndicator 设置为 True 当且只有 data(role=CheckStateRole) 不是“Null”时,如 Python 的 None .
无关紧要的注意事项:请注意,如果您使用更高级的模型(例如 QSql 模型),则“未设置”值(如在“Null”QVariant 中,例如,该字段没有数据集) 不总是 Python 的 None,而是“QPyNullVariant”。
考虑到上述概念,您应该在 QWizardPage 的__init__ 中设置模型及其项,然后仅使用initializePage 设置其标志。
class Page2(QtWidgets.QWizardPage):
def __init__(self, parent=None):
QtWidgets.QWizardPage.__init__(self, parent)
layout = QtWidgets.QGridLayout()
self.setLayout(layout)
self.tree = QtWidgets.QTreeView()
layout.addWidget(self.tree)
self.model = QtGui.QStandardItemModel()
self.tree.setModel(self.model)
self.model.dataChanged.connect(self.setCurrentState)
self.addCheckItem = QtGui.QStandardItem('item')
self.model.appendRow(self.addCheckItem)
# remember the default flags
self.defaultFlags = self.addCheckItem.flags()
# set the current "add_checkbox" value to None, which means that it
# has *no* state set at all, not even an Unchecked one
self.currentState = None
def setCurrentState(self, topLeft, bottomRight):
# remember the new check state
self.currentState = self.addCheckItem.checkState()
def initializePage(self):
if self.field('add_checkbox'):
# apply the new flags to allow the user to set the check state
self.addCheckItem.setFlags(
self.defaultFlags | QtCore.Qt.ItemIsUserCheckable)
# set the state if it has been previously set
if self.currentState is None:
self.addCheckItem.setCheckState(QtCore.Qt.Unchecked)
else:
self.addCheckItem.setCheckState(self.currentState)
else:
# prevent notifying setCurrentState() slot that we're changing the
# value, while still remembering the check state;
# note that blogking model signals is not a good practice, as it
# prevents the view to receive model changes, which usually results
# in painting, size, scrolling and mouse interaction issues, but we
# can ignore that in this case, since those changes are only taken
# into account once the view is shown, assuming that the view will
# update once it will be shown, and that will only happen *after*
# initializePage returns
self.model.blockSignals(True)
self.addCheckItem.setData(None, QtCore.Qt.CheckStateRole)
self.model.blockSignals(False)