选择选中的项目时遇到问题

时间:2021-04-10 05:11:55

标签: python pyqt pyqt5 qtreewidget qtreewidgetitem

我将应用程序简化为可展示的;这里的场景是用户点击“主题”按钮,主题窗口将被打开以选择一个选项;委托类(来自 QStyledItemDelegate)被定义为在 editorEvent 收到选中项目的 MouseButtonRelease 事件后立即取消选中其他选项(如下代码所示),最终当用户按下 Ok 按钮时,样式将根据所选的选项; 这是我的第一个问题:选中一个项目的复选框并没有选中该项目(选中后索引保持不变),这意味着用户不仅要选中复选框,还要单击该项目以选择它。如果不单击(选择)该项目,索引将保留在父项(“主题”)上,而不是切换到选中的子项,并且该项目不会突出显示。 (我希望我澄清了自己)

我尝试的是将“paint”方法添加到 Delegate 类,并希望通过在 QStyle 中定义状态来自动选择项目,但是,项目没有突出显示(表示被选中)和索引仍将保留在父“主题”上... 所以,为了解决这个问题,我在“接受”方法(表单类)中添加了:

if model.data(index) == 'Themes':
        index = self.theme.treeWidget.currentIndex().child(0,0)

当按下 Ok 按钮时,索引将被强制设置在第一个子项上,然后获取父项并对其进行迭代以查找选中的选项(并且还设置选择当前索引,现在该项目将突出显示)...好吧,这不是我要找的东西,我希望看到该项目在检查后立即突出显示(并被选中); 我相信必须有一种更好的方法来在收到 MouseButtonRelease 事件后立即在 Delagate 类中选择 Checked 项……非常感谢您的指导;此外,因为您现在在这里,我还想保留并保存设置,以便下次用户打开主题窗口时,应用程序会引用先前选择的选项并将其显示为选中项...

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

class Delegate(QtWidgets.QStyledItemDelegate):
    def paint(self, painter, option, index):
        if not index.parent().isValid():
            QStyledItemDelegate.paint(self, painter, option, index)
        else:
            widget = option.widget
            style = widget.style() if widget else QApplication.style()
            opt = QStyleOptionButton()
            opt.rect = option.rect
            opt.text = index.data()
            opt.state |= QStyle.State_On if index.data(Qt.CheckStateRole) else QStyle.State_Off
            style.drawControl(QStyle.CE_CheckBox, opt, painter, widget)

    def editorEvent(self, event, model, option, index):
        value = QtWidgets.QStyledItemDelegate.editorEvent(self, event, model, option, index)        
        if value:
            if event.type() == QtCore.QEvent.MouseButtonRelease:
                if index.data(QtCore.Qt.CheckStateRole) == QtCore.Qt.Checked:
                    parent = index.parent()
                    for i in range(model.rowCount(parent)):
                        if i != index.row():
                            ix = parent.child(i, 0)
                            model.setData(ix, QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole)
        return value

class Theme(QtWidgets.QMainWindow, Preferences_test.Ui_Preferences):
    def __init__(self, parent=None):
        super(Theme, self).__init__(parent)
        self.setupUi(self)
        self.treeWidget.setHeaderHidden(True)
        self.treeWidget.setItemDelegate(Delegate())
        self.treeWidget.expandAll()
        
class Form(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        layout = QVBoxLayout()
        self.pushButton = QtWidgets.QPushButton('Themes')
        layout.addWidget(self.pushButton)
        self.setLayout(layout)
        self.pushButton.clicked.connect(self.theme_call)
        
    def accept(self):
        index = self.theme.treeWidget.currentIndex()
        model = self.theme.treeWidget.model()
        if model.data(index) == 'Themes':
            index = self.theme.treeWidget.currentIndex().child(0,0)
        parent_idx = index.parent()
        for i in range(model.rowCount(parent_idx)):
            idx = parent_idx.child(i, 0)
            if (model.data(idx) == "Fusion") and idx.data(QtCore.Qt.CheckStateRole) == QtCore.Qt.Checked:
                app.setStyle('Fusion')
                # self.theme.treeWidget.itemFromIndex(idx).setSelected(True)
                return

            elif (model.data(idx) == "Light-Classic") and idx.data(QtCore.Qt.CheckStateRole) == QtCore.Qt.Checked:
                app.setStyle('Light-Classic')
                # self.theme.treeWidget.itemFromIndex(idx).setSelected(True)
                return

            else:
                pass
        # self.theme.close()

    def reject(self):
        self.theme.close()

    def theme_call(self):
        self.theme = Theme()
        self.theme.show()
        self.theme.buttonBox.accepted.connect(self.accept)
        self.theme.buttonBox.rejected.connect(self.reject)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    form = Form()
    form.show()
    app.exec_()

和设计器文件:[Preferences_test.py]

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Preferences(object):
    def setupUi(self, Preferences):
        Preferences.setObjectName("Preferences")
        Preferences.resize(278, 359)
        self.layoutWidget = QtWidgets.QWidget(Preferences)
        self.layoutWidget.setGeometry(QtCore.QRect(10, 10, 258, 341))
        self.layoutWidget.setObjectName("layoutWidget")
        self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget)
        self.gridLayout.setObjectName("gridLayout")
        self.treeWidget = QtWidgets.QTreeWidget(self.layoutWidget)
        self.treeWidget.setHeaderHidden(True)
        self.treeWidget.setObjectName("treeWidget")
        item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
        item_1 = QtWidgets.QTreeWidgetItem(item_0)
        item_1.setCheckState(0, QtCore.Qt.Unchecked)
        item_1 = QtWidgets.QTreeWidgetItem(item_0)
        item_1.setCheckState(0, QtCore.Qt.Unchecked)
        self.gridLayout.addWidget(self.treeWidget, 0, 0, 1, 1)
        self.buttonBox = QtWidgets.QDialogButtonBox(self.layoutWidget)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.gridLayout.addWidget(self.buttonBox, 3, 0, 1, 1)
        self.retranslateUi(Preferences)
        QtCore.QMetaObject.connectSlotsByName(Preferences)

    def retranslateUi(self, Preferences):
        _translate = QtCore.QCoreApplication.translate
        Preferences.setWindowTitle(_translate("Preferences", "Preferences"))
        self.treeWidget.headerItem().setText(0, _translate("Preferences", "1"))
        self.treeWidget.topLevelItem(0).setText(0, _translate("Preferences", "Themes"))
        self.treeWidget.topLevelItem(0).child(0).setText(0, _translate("Preferences", "Light-Classic"))
        self.treeWidget.topLevelItem(0).child(1).setText(0, _translate("Preferences", "Fusion"))

0 个答案:

没有答案