2016-12-13 2 views
1

Как я могу испустить сигнал при изменении флажка элемента treeview?python emit signal on on clicked QTreeview item checkbox изменен

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

ответ

0

Использовать элементChanged-сигнал от 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

Основная проблема с использованием 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