我将应用程序简化为可展示的;这里的场景是用户点击“主题”按钮,主题窗口将被打开以选择一个选项;委托类(来自 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"))