python在点击的QTreeview项目复选框上发出信号

时间:2016-12-13 20:08:30

标签: python pyside signals-slots qtreeview

如果更改树视图项目的复选框,我该如何发出信号?

import sys
from PySide import QtGui, QtCore

class Browser(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Browser, self).__init__(parent)

        self.initUI()

    def initUI(self):
        self.resize(200, 300)
        self.setWindowTitle('Assets')
        self.setModal(True)

        self.results = ""

        self.uiItems = QtGui.QTreeView()
        self.uiItems.setAlternatingRowColors(True)
        self.uiItems.setSortingEnabled(True)
        self.uiItems.sortByColumn(0, QtCore.Qt.AscendingOrder)
        self.uiItems.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self.uiItems.header().setResizeMode(QtGui.QHeaderView.ResizeToContents)

        grid = QtGui.QGridLayout()
        grid.setContentsMargins(0, 0, 0, 0)
        grid.addWidget(self.uiItems, 0, 0)
        self.setLayout(grid)

        self.show()
        self.create_model()

    def create_model(self):
        items = [
            'Cookie dough',
            'Hummus',
            'Spaghetti',
            'Dal makhani',
            'Chocolate whipped cream'
        ]

        model = QtGui.QStandardItemModel()
        model.setHorizontalHeaderLabels(['Name'])

        for item in items:
            model.insertRow(0)

            # Append object
            model.setData(model.index(0, 0), QtCore.Qt.Unchecked, role = QtCore.Qt.CheckStateRole)
            model.setData(model.index(0, 0), item)

            item = model.itemFromIndex(model.index(0,0))
            item.setCheckable(True)


        self.uiItems.setModel(model)


def main():
    app = QtGui.QApplication(sys.argv)
    ex = Browser()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

2 个答案:

答案 0 :(得分:1)

使用QStandardItemModel中的itemChanged信号。

import sys
from PyQt4 import QtGui, QtCore

class Browser(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Browser, self).__init__(parent)

        self.initUI()

    def initUI(self):
        self.resize(200, 300)
        self.setWindowTitle('Assets')
        self.setModal(True)

        self.results = ""

        self.uiItems = QtGui.QTreeView()
        self.uiItems.setAlternatingRowColors(True)
        self.uiItems.setSortingEnabled(True)
        self.uiItems.sortByColumn(0, QtCore.Qt.AscendingOrder)
        self.uiItems.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self.uiItems.header().setResizeMode(QtGui.QHeaderView.ResizeToContents)

        grid = QtGui.QGridLayout()
        grid.setContentsMargins(0, 0, 0, 0)
        grid.addWidget(self.uiItems, 0, 0)
        self.setLayout(grid)

        self.show()
        self.create_model()

    def create_model(self):
        items = [
            'Cookie dough',
            'Hummus',
            'Spaghetti',
            'Dal makhani',
            'Chocolate whipped cream'
        ]

        model = QtGui.QStandardItemModel()
        model.setHorizontalHeaderLabels(['Name'])

        for item in items:
            model.insertRow(0)

            # Append object
            model.setData(model.index(0, 0), QtCore.Qt.Unchecked, role = QtCore.Qt.CheckStateRole)
            model.setData(model.index(0, 0), item)

            item = model.itemFromIndex(model.index(0,0))
            item.setCheckable(True)

        # Added the following line.
        model.itemChanged.connect(self.test)
        self.uiItems.setModel(model)

    # Added the following method.
    def test(self, item):
        if item.text() == "Hummus":
            if item.checkState() == QtCore.Qt.Checked:
                # Hummus is selected
                # do something here
                pass
            else:
                # Hummus is deselected
                # do something here
                pass
        if item.text() == "Spaghetti":
            if item.checkState() == QtCore.Qt.Checked:
                # Spaghetti is selected
                # do something here
                pass
            else:
                # Spaghetti is deselected
                # do something here
                pass


def main():
    app = QtGui.QApplication(sys.argv)
    ex = Browser()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

答案 1 :(得分:1)

使用itemChanged信号的一个主要问题是它没有告诉您 更改了什么。如果它发送了已更改的数据的特定角色,那将会非常有用。

实际上,总是存在从您不感兴趣的其他类型数据的更改中获得误报的危险(有fifteen pre-defined data roles,以及任意数量的用户定义数据)。

因此,更强大的解决方案是对模型进行子类化并发出特定包含角色的自定义信号:

        model = StandardItemModel()
        ...

        self.uiItems.setModel(model)
        model.itemDataChanged.connect(self.handleItemDataChanged)

    def handleItemDataChanged(self, item, role):
        if role == QtCore.Qt.CheckStateRole:
            print(item.text(), item.checkState())


class StandardItemModel(QtGui.QStandardItemModel):
    itemDataChanged = QtCore.Signal(object, object)

    def setData(self, index, value, role=QtCore.Qt.EditRole):
        oldvalue = index.data(role)
        result = super(StandardItemModel, self).setData(index, value, role)
        if result and value != oldvalue:
            self.itemDataChanged.emit(self.itemFromIndex(index), role)
        return result