2016-12-13 9 views
1

Wie kann ich ein Signal ausgeben, wenn das Kontrollkästchen eines Treeview-Elements geändert wird?Python emittieren Signal bei angeklicktem QTreeview-Objekt Kontrollkästchen geändert

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() 

Antwort

0

Verwenden Sie das ItemChanged-Signal aus dem QStandardItemModel.

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() 
0

Ein großes Problem bei der itemChanged Signal ist, dass es nicht Sie nicht sagen, welche geändert. Es wäre so viel nützlicher, wenn es die spezifische Rolle der Daten gesendet hätte, die sich geändert hatten.

Es besteht immer die Gefahr, dass bei Änderungen an anderen Datentypen, die Sie nicht interessieren, falsche positive Ergebnisse erhalten werden (es gibt und eine beliebige Anzahl benutzerdefinierter Daten).

So eine robustere Lösung würde das Modell zu Unterklasse sein und ein eigenes Signal aussenden, das speziell die Rolle umfasst:

 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 
Verwandte Themen