在 Pyside 中使 QTreeview 的列可编辑

Make QTreeview's Column Editable in Pyside

如何使 QTreeView 的第二列可编辑以便用户可以更改名称?

import sys
import os
import random
from PySide import QtGui, QtCore

class ID_Asset(object):
    def __init__(self, buffer_id=0, name='', nodes=[]):
        self.buffer_id = buffer_id
        self.name = name if name else 'unknown'
        self.nodes = nodes if nodes is not None else []
        self.color = QtGui.QBrush(QtGui.QColor(0, 0, 0, 255))

        self.randomize_color()

    def randomize_color(self):
        r = random.randrange(0, 255)
        g = random.randrange(0, 255)
        b = random.randrange(0, 255)

        self.color = QtGui.QBrush(QtGui.QColor(r, g, b, 255))


class ObjectIDManager(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(ObjectIDManager, self).__init__(parent)

        self.TITLE = 'Object ID Manager'
        self.VERSION = "1.0.0" # MAJOR.MINOR.PATCH
        self.resize(270, 500)
        self.setWindowTitle(self.TITLE + " | " + self.VERSION)
        self.init_ui()

    def init_ui(self):

        # variables
        self.assets = []
        self.handlers = []

        self.items_model = QtGui.QStandardItemModel()
        self.ui_items = QtGui.QTreeView()
        # self.ui_items.setAlternatingRowColors(True)
        self.ui_items.setSortingEnabled(True)
        self.ui_items.setAllColumnsShowFocus(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.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        # self.ui_items.customContextMenuRequested.connect(self.open_menu)
        self.ui_items.sortByColumn(0, QtCore.Qt.AscendingOrder)
        self.ui_items.setModel(self.items_model)
        self.ui_items.setRootIsDecorated(False)

        gbox = QtGui.QGridLayout()
        gbox.setContentsMargins(10, 10, 10, 10)
        gbox.addWidget(self.ui_items)

        # main layout
        main_widget = QtGui.QWidget()
        main_widget.setLayout(gbox)
        self.setCentralWidget(main_widget)

        # signals
        self.initialize()

    # functions
    def initialize(self):
        self.process_model()

    def process_model(self):
        model = self.ui_items.model()
        model.clear()
        headers = ['ID', 'Name', 'Used', 'Color']
        model.setHorizontalHeaderLabels(headers)

        self.collect_assets()

        for x in self.assets:
            model.insertRow(0)

            # Append object
            model.setData(model.index(0, 0), x, role=QtCore.Qt.UserRole)
            model.setData(model.index(0, 0), x.buffer_id)
            model.setData(model.index(0, 1), x.name)
            model.setData(model.index(0, 2), len(x.nodes))
            model.setData(model.index(0, 3), x.color, QtCore.Qt.BackgroundRole)

            # item = model.itemFromIndex(model.index(0,0))

        self.ui_items.sortByColumn(0, QtCore.Qt.AscendingOrder)

    def collect_assets(self):
        ids = {
            0: ['a','b','c'],
            1: ['a','b','c','j'],
            30: ['b','c'],
            45: ['a',],
            60: ['a','b','c','d','e','f']
        }

        self.assets = []

        for key, value in ids.items():
            new_asset = ID_Asset(buffer_id=key, nodes=value)
            self.assets.append(new_asset)

        return self.assets

# Main
# -----------------------------------------------------------------------------
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = ObjectIDManager()
    window.show()
    app.exec_()

你不应该使用:

{Your QTreeView}.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)

因为您不能编辑任何项目。

必须逐个放置可编辑的属性,即{your QStandardItem}.setEditable({your value})

在你的情况下添加:

model.item(0, 0).setEditable(False)
model.item(0, 1).setEditable(True)
model.item(0, 2).setEditable(False)
model.item(0, 3).setEditable(False)

之后
...
model.setData(model.index(0, 0), x, role=QtCore.Qt.UserRole)
model.setData(model.index(0, 0), x.buffer_id)
model.setData(model.index(0, 1), x.name)
model.setData(model.index(0, 2), len(x.nodes))
model.setData(model.index(0, 3), x.color, QtCore.Qt.BackgroundRole)
....

完整代码:

import sys
import os
import random
from PySide import QtGui, QtCore

class ID_Asset(object):
    def __init__(self, buffer_id=0, name='', nodes=[]):
        self.buffer_id = buffer_id
        self.name = name if name else 'unknown'
        self.nodes = nodes if nodes is not None else []
        self.color = QtGui.QBrush(QtGui.QColor(0, 0, 0, 255))

        self.randomize_color()

    def randomize_color(self):
        r = random.randrange(0, 255)
        g = random.randrange(0, 255)
        b = random.randrange(0, 255)

        self.color = QtGui.QBrush(QtGui.QColor(r, g, b, 255))


class ObjectIDManager(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(ObjectIDManager, self).__init__(parent)

        self.TITLE = 'Object ID Manager'
        self.VERSION = "1.0.0" # MAJOR.MINOR.PATCH
        self.resize(270, 500)
        self.setWindowTitle(self.TITLE + " | " + self.VERSION)
        self.init_ui()

    def init_ui(self):

        # variables
        self.assets = []
        self.handlers = []

        self.items_model = QtGui.QStandardItemModel()
        self.ui_items = QtGui.QTreeView()
        # self.ui_items.setAlternatingRowColors(True)
        self.ui_items.setSortingEnabled(True)
        self.ui_items.setAllColumnsShowFocus(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.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        # self.ui_items.customContextMenuRequested.connect(self.open_menu)
        self.ui_items.sortByColumn(0, QtCore.Qt.AscendingOrder)
        self.ui_items.setModel(self.items_model)
        self.ui_items.setRootIsDecorated(False)

        gbox = QtGui.QGridLayout()
        gbox.setContentsMargins(10, 10, 10, 10)
        gbox.addWidget(self.ui_items)

        # main layout
        main_widget = QtGui.QWidget()
        main_widget.setLayout(gbox)
        self.setCentralWidget(main_widget)

        # signals
        self.initialize()

    # functions
    def initialize(self):
        self.process_model()

    def process_model(self):
        model = self.ui_items.model()
        model.clear()
        headers = ['ID', 'Name', 'Used', 'Color']
        model.setHorizontalHeaderLabels(headers)

        self.collect_assets()

        for x in self.assets:
            model.insertRow(0)
            # Append object
            model.setData(model.index(0, 0), x, role=QtCore.Qt.UserRole)
            model.setData(model.index(0, 0), x.buffer_id)
            model.setData(model.index(0, 1), x.name)
            model.setData(model.index(0, 2), len(x.nodes))
            model.setData(model.index(0, 3), x.color, QtCore.Qt.BackgroundRole)

            model.item(0, 0).setEditable(False)
            model.item(0, 1).setEditable(True)
            model.item(0, 2).setEditable(False)
            model.item(0, 3).setEditable(False)




            # item = model.itemFromIndex(model.index(0,0))

        self.ui_items.sortByColumn(0, QtCore.Qt.AscendingOrder)

    def collect_assets(self):
        ids = {
            0: ['a','b','c'],
            1: ['a','b','c','j'],
            30: ['b','c'],
            45: ['a',],
            60: ['a','b','c','d','e','f']
        }

        self.assets = []

        for key, value in ids.items():
            new_asset = ID_Asset(buffer_id=key, nodes=value)
            self.assets.append(new_asset)

        return self.assets

# Main
# -----------------------------------------------------------------------------
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = ObjectIDManager()
    window.show()
    app.exec_()

输出: