在QWizardPage上获取QTreeView以正确更新

2024-09-30 12:29:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我在QWizardPage(例如,qwpage2)上有一个QTreeView小部件,其中一列信息的标志取决于另一列QRadioButton(例如,qwpage1)上的QRadioButton小部件的状态

treeview列的原始属性是在qwpage2initializePage方法中设置的。如果我Next >浏览这些页面,一切正常。但是,如果I < Backqwpage2,将qwpage1上的单选按钮更改为Next >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列之前已经初始化过页面,那么如何更改与该列关联的标志状态(本质上是复选框的存在)

谢谢你的帮助


Tags: selfadd部件标志状态页面nexttreeview
1条回答
网友
1楼 · 发布于 2024-09-30 12:29:34

问题不在于从下一页向后返回后,何时返回到该页,因为总是调用initializePage(),无论“上一页”是页索引中的上一页还是下一页(这很有意义,因为页顺序并不总是必须遵循“普通索引顺序”,因为它是从^{}返回的,默认情况下,它调用当前页的^{},甚至可以返回小于当前页的索引。
也就是说,有一种情况initializePage()只被调用一次,如果设置QWizard.IndependentPages选项,就会发生这种情况。如果您真的需要使用它,我认为唯一的替代方法是通过覆盖页面的showEvent(event)onlyif not event.spontaneous()来设置值(否则,即使页面最小化后再次显示,它也将始终处理所有内容)

这里真正重要的是,如果为其索引设置了Qt.CheckStateRole,则通常会显示项目委托的复选框,因为设置Qt.ItemIsUserCheckable只意味着用户可以设置项目状态而不是复选框可见。
事实上,除非某些特定的OS/QtStyle起作用,否则设置该标志根本不会有任何效果,即使发生这种情况,一旦检查状态设置为三种状态(Unchecked、PartiallyChecked或Checked)中的任何一种,禁用该标志也不会有任何区别:它无论如何都会显示出来

虽然这看起来有点违反直觉,但它的行为在source code中很明显,其中StyleOptionViewItem特性HasCheckIndicator在data(role=CheckStateRole)不为“Null”时设置为True,就像Python的None

Slighlty无关注意:请注意,如果您使用的是更高级的模型(如QSql模型),“unset”值(如在“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)

相关问题 更多 >

    热门问题