我在QWizardPage (比如qwpage2)上有一个QTreeView小部件,其中一列信息的标志取决于另一个QWizardPage (比如qwpage1)上的QRadioButton的状态。
treeview列的原始属性在qwpage2的initializePage方法中设置。如果我通过Next >浏览页面,一切都会正常工作。但是,如果我从qwpage2执行< Back操作,将qwpage1上的单选按钮更改为qwpage2,并将其设置为qwpage2,则不会更新这些标志。
我在qwpage1上有如下内容(在PyQt5中)
rbtn1 = QRadioButton()
rbtn2 = QRadioButton()
self.registerField ("remove_checkbox", rbtn1)
self.registerField ("add_checkbox", rbtn2)
self.checked_choice.addButton(rbtn1)
self.checked_choice.addButton(rbtn2)在qwpage2上
add_checkbox = self.field("add_checkbox")
p = QStandardItem()
if add_checkbox:
p.setFlags(p.flags() | Qt.ItemIsUserCheckable)
else:
p.setFlags(Qt.NoItemFlags)如果页面之前已初始化,我如何更改与treeview列关联的标志状态(本质上是复选框的存在)?
谢谢你的帮助
发布于 2019-08-19 05:49:12
问题不在于从下一个页面返回后返回页面的时间,因为initializePage()总是被调用,无论“上一个”页面是页面索引中的前一个页面还是下一个页面(这是有道理的,因为页面顺序并不总是遵循“普通索引顺序”,因为它是从QWizard.nextId()返回的,它默认调用当前页面的QWizardPage.nextId(),甚至可能返回一个小于当前页面的索引)。
也就是说,有一种情况下initializePage()只被调用一次,如果您设置了QWizard.IndependentPages选项,就会发生这种情况。如果您真的需要使用它,我认为唯一的选择是通过覆盖页面的showEvent(event)和 if not event.spontaneous()来设置值(否则,即使页面在最小化后再次显示,它也将始终处理所有内容)。
这里真正重要的是,如果为项目委托的索引设置了a Qt.CheckStateRole,则项目委托的复选框通常会显示为可见,因为设置Qt.ItemIsUserCheckable仅意味着用户可以设置项目状态,而不是设置复选框可见。
事实上,除非某些特定的OS/QtStyle生效,否则设置该标志根本不会有任何影响,即使发生了这种情况,一旦检查状态被设置为三种状态(未选中、PartiallyChecked或选中)中的任何一种,禁用它也不会有任何区别:无论如何都会显示它。
虽然这可能看起来有点违反直觉,但它的行为在source code中很明显,当StyleOptionViewItem特性HasCheckIndicator设置为True时,只有data(role=CheckStateRole)不是"Null",就像Python的None一样。
稍微不相关的注意:注意,如果你使用更高级的模型(比如QSql模型),一个“未设置”的值(比如在“空”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)https://stackoverflow.com/questions/57547398
复制相似问题