QStandardItem 复选框更改反映在 Pyside 中的对象上
QStandardItem checkbox changes reflected on object in Pyside
如何将 UI 中的复选框与它们所代表的属性同步?因此,当我更改 UI 中的复选框状态时,它会正确设置 class 对象上 属性 的值以匹配复选框状态?
例如,如果我点击 FumeFX_001 的继续 Sim 复选框,它也应该更改 属性 以匹配。
打印按钮可帮助测试用户单击 ui 中的复选框时是否正在更新值。
import sys
from PySide import QtGui, QtCore
import pprint
class Operation(object):
def __init__(self, name='', script='', enabled=False):
self.name = name
self.script = script
self.enabled = enabled
class FumeFX(object):
def __init__(self, name):
self.name = name
self.cache = 'Z:/pipeline/max/release/test/tools/cache/####.aur'
self.operations = [
Operation('Sim', 'Z:/pipeline/sim.py', True),
Operation('Continue Sim', 'Z:/pipeline/cont_sim.py', False),
Operation('Wavelet', 'Z:/pipeline/wavelet.py', False),
Operation('Continue Wavelet', 'Z:/pipeline/cont_wavelet.py', False),
Operation('Post', 'Z:/pipeline/post.py', False),
Operation('Continue Post', 'Z:/pipeline/cont_post.py', False)
]
class Phoenix(object):
def __init__(self, name):
self.name = name
self.cache = 'Z:/pipeline/max/release/test/tools/cache/####.aur'
self.operations = [
Operation('Bounce', 'Z:/pipeline/sim.py', True),
Operation('Continue Bounce', 'Z:/pipeline/cont_sim.py', False),
Operation('Delete', 'Z:/pipeline/wavelet.py', False),
]
class Browser(QtGui.QDialog):
def __init__(self, parent=None):
super(Browser, self).__init__(parent)
self.initUI()
def initUI(self):
self.resize(400, 400)
self.setWindowTitle('Assets')
self.items_model = QtGui.QStandardItemModel()
self.ui_items = QtGui.QTreeView()
self.ui_items.setAlternatingRowColors(True)
self.ui_items.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.ui_items.header().setResizeMode(QtGui.QHeaderView.ResizeToContents)
self.ui_items.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
self.ui_items.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
self.ui_items.setModel(self.items_model)
self.ui_print = QtGui.QPushButton('Print')
grid = QtGui.QVBoxLayout()
grid.setContentsMargins(5, 5, 5, 5)
grid.addWidget(self.ui_items)
grid.addWidget(self.ui_print)
self.setLayout(grid)
self.nodes = [
FumeFX('FumeFX_001'),
FumeFX('FumeFX_002'),
Phoenix('Phoenix')
]
self.update_model()
self.ui_print.clicked.connect(self.print_info)
def print_info(self):
for n in self.nodes:
print n.name, n.cache
# pprint.pprint(vars(n))
for p in n.operations:
pprint.pprint(vars(p))
print '\n'
def update_model(self):
model = self.ui_items.model()
model.clear()
model.setHorizontalHeaderLabels(['Assets',''])
# Create Data
for x in self.nodes:
root = []
# Node Name
n_main = QtGui.QStandardItem()
n_main.setData(x.name, role=QtCore.Qt.DisplayRole)
n_main.setData(x, role=QtCore.Qt.UserRole)
root.append(n_main)
# Node Output
n_output = QtGui.QStandardItem()
n_output.setData(x.cache, role=QtCore.Qt.DisplayRole)
n_output.setData(x, role=QtCore.Qt.UserRole)
root.append(n_output)
# Operations
for op in x.operations:
row = []
op_name = QtGui.QStandardItem()
op_name.setData(op.name, role=QtCore.Qt.DisplayRole)
op_name.setData(op, role=QtCore.Qt.UserRole)
row.append(op_name)
op_enabled = QtGui.QStandardItem()
op_enabled.setData(QtCore.Qt.Checked, role=QtCore.Qt.CheckStateRole)
op_enabled.setData(op, role=QtCore.Qt.UserRole)
op_enabled.setCheckable(True)
row.append(op_enabled)
n_main.appendRow(row)
# add node to main treeview
model.appendRow(root)
self.ui_items.expandAll()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = Browser()
ex.show()
sys.exit(app.exec_())
首先,您必须使用默认值初始化复选框:
# Operations
for op in x.operations:
row = []
...
op_enabled = QtGui.QStandardItem()
op_enabled.setData(op, role=QtCore.Qt.UserRole)
op_enabled.setCheckable(True)
if op.enabled:
op_enabled.setCheckState(QtCore.Qt.Checked)
else:
op_enabled.setCheckState(QtCore.Qt.Unchecked)
row.append(op_enabled)
然后您可以将插槽连接到模型的 itemChanged
信号,只要检查状态发生变化,它就会更新值:
class Browser(QtGui.QDialog):
...
def initUI(self):
...
self.ui_print.clicked.connect(self.print_info)
self.items_model.itemChanged.connect(self.handleItemChanged)
def handleItemChanged(self, item):
if item.isCheckable():
op = item.data(QtCore.Qt.UserRole)
op.enabled = item.checkState() == QtCore.Qt.Checked
如何将 UI 中的复选框与它们所代表的属性同步?因此,当我更改 UI 中的复选框状态时,它会正确设置 class 对象上 属性 的值以匹配复选框状态?
例如,如果我点击 FumeFX_001 的继续 Sim 复选框,它也应该更改 属性 以匹配。
打印按钮可帮助测试用户单击 ui 中的复选框时是否正在更新值。
import sys
from PySide import QtGui, QtCore
import pprint
class Operation(object):
def __init__(self, name='', script='', enabled=False):
self.name = name
self.script = script
self.enabled = enabled
class FumeFX(object):
def __init__(self, name):
self.name = name
self.cache = 'Z:/pipeline/max/release/test/tools/cache/####.aur'
self.operations = [
Operation('Sim', 'Z:/pipeline/sim.py', True),
Operation('Continue Sim', 'Z:/pipeline/cont_sim.py', False),
Operation('Wavelet', 'Z:/pipeline/wavelet.py', False),
Operation('Continue Wavelet', 'Z:/pipeline/cont_wavelet.py', False),
Operation('Post', 'Z:/pipeline/post.py', False),
Operation('Continue Post', 'Z:/pipeline/cont_post.py', False)
]
class Phoenix(object):
def __init__(self, name):
self.name = name
self.cache = 'Z:/pipeline/max/release/test/tools/cache/####.aur'
self.operations = [
Operation('Bounce', 'Z:/pipeline/sim.py', True),
Operation('Continue Bounce', 'Z:/pipeline/cont_sim.py', False),
Operation('Delete', 'Z:/pipeline/wavelet.py', False),
]
class Browser(QtGui.QDialog):
def __init__(self, parent=None):
super(Browser, self).__init__(parent)
self.initUI()
def initUI(self):
self.resize(400, 400)
self.setWindowTitle('Assets')
self.items_model = QtGui.QStandardItemModel()
self.ui_items = QtGui.QTreeView()
self.ui_items.setAlternatingRowColors(True)
self.ui_items.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.ui_items.header().setResizeMode(QtGui.QHeaderView.ResizeToContents)
self.ui_items.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
self.ui_items.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
self.ui_items.setModel(self.items_model)
self.ui_print = QtGui.QPushButton('Print')
grid = QtGui.QVBoxLayout()
grid.setContentsMargins(5, 5, 5, 5)
grid.addWidget(self.ui_items)
grid.addWidget(self.ui_print)
self.setLayout(grid)
self.nodes = [
FumeFX('FumeFX_001'),
FumeFX('FumeFX_002'),
Phoenix('Phoenix')
]
self.update_model()
self.ui_print.clicked.connect(self.print_info)
def print_info(self):
for n in self.nodes:
print n.name, n.cache
# pprint.pprint(vars(n))
for p in n.operations:
pprint.pprint(vars(p))
print '\n'
def update_model(self):
model = self.ui_items.model()
model.clear()
model.setHorizontalHeaderLabels(['Assets',''])
# Create Data
for x in self.nodes:
root = []
# Node Name
n_main = QtGui.QStandardItem()
n_main.setData(x.name, role=QtCore.Qt.DisplayRole)
n_main.setData(x, role=QtCore.Qt.UserRole)
root.append(n_main)
# Node Output
n_output = QtGui.QStandardItem()
n_output.setData(x.cache, role=QtCore.Qt.DisplayRole)
n_output.setData(x, role=QtCore.Qt.UserRole)
root.append(n_output)
# Operations
for op in x.operations:
row = []
op_name = QtGui.QStandardItem()
op_name.setData(op.name, role=QtCore.Qt.DisplayRole)
op_name.setData(op, role=QtCore.Qt.UserRole)
row.append(op_name)
op_enabled = QtGui.QStandardItem()
op_enabled.setData(QtCore.Qt.Checked, role=QtCore.Qt.CheckStateRole)
op_enabled.setData(op, role=QtCore.Qt.UserRole)
op_enabled.setCheckable(True)
row.append(op_enabled)
n_main.appendRow(row)
# add node to main treeview
model.appendRow(root)
self.ui_items.expandAll()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = Browser()
ex.show()
sys.exit(app.exec_())
首先,您必须使用默认值初始化复选框:
# Operations
for op in x.operations:
row = []
...
op_enabled = QtGui.QStandardItem()
op_enabled.setData(op, role=QtCore.Qt.UserRole)
op_enabled.setCheckable(True)
if op.enabled:
op_enabled.setCheckState(QtCore.Qt.Checked)
else:
op_enabled.setCheckState(QtCore.Qt.Unchecked)
row.append(op_enabled)
然后您可以将插槽连接到模型的 itemChanged
信号,只要检查状态发生变化,它就会更新值:
class Browser(QtGui.QDialog):
...
def initUI(self):
...
self.ui_print.clicked.connect(self.print_info)
self.items_model.itemChanged.connect(self.handleItemChanged)
def handleItemChanged(self, item):
if item.isCheckable():
op = item.data(QtCore.Qt.UserRole)
op.enabled = item.checkState() == QtCore.Qt.Checked