2017-12-09 76 views
0

숨겨진 루트가있는 QTreeWidget, 헤더로 2 개의 자식 및 그 하위에 2 개의 자식이 있습니다. 즉이 예에서는 아마도 관계가 있지만, I는 현재 I는 self.CurrentIndexLabel를 사용하여 현재 선택된 레이블을 추적 HEADER 1 ITEM 12 setCheckState 데 필요한 item = {} 사전, 변수를 사용QTreeWidget 자식의 자식 setCheckedState를 설정하는 방법은 무엇입니까?

ROOT (HIDDEN) 
    | 
    |- HEADER 1 (CHILD, NOT CHECKABLE) 
    |  | 
    |  |- ITEM 11 (CHILD, CHECKABLE) 
    |  |- ITEM 12 (CHILD, CHECKABLE) 
    | 
    |- HEADER 2 (CHILD) 
    |  | 
    |  | - ITEM 21 (CHILD, CHECKABLE) 
    |  | - ITEM 22 (CHILD, CHECKABLE) 

. 나는 그런처럼 나무를 채운 :

TreeList = ({ 
    'Header1': (('Item11', 'Item12',)), 
    'Header2': (('Item21', 'Item22',)), 
}) 

item = {'Item12': {'ItemEnabled': 1}} # 0 = No, 1 = Yes 

for key, value in TreeList.items(): 
    parent = QTreeWidgetItem(self.ListTreeView, [key]) 
    for val in value: 
     child = QTreeWidgetItem([val]) 
     child.setFlags(child.flags() | Qt.ItemIsUserCheckable) 
     child.setCheckState(0, Qt.Unchecked) 
     parent.addChild(child) 

가 처음에 나는 항목이 각 항목에 대한 변수를 압정으로 고정하고, item = {} 사전에 따라 선택 또는 선택 해제 여부를 설정해야 사용자가 항목을 선택하거나 선택 취소 할 때, I 항목이 사용 가능한지 여부를 반영하여 item = {} 사전을 변경해야합니다.

신호 및 슬롯을 사용하여 변경을 감지해야한다고 가정하지만 목록에서 항목을 플래그로 지정하는 방법을 파악하지 못하고 사용자 검사를 반영하는 방법을 모르겠습니다. 또는 TreeList에있는 항목을 선택 취소하십시오.

1 또는 0을 사용하여 검사를 추적하거나 선택 취소하여 사전 item = {}을 현재 상태로 업데이트하는 것이 이상적입니다.

이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 저는 파이썬에 익숙하지 않으므로 제발 참아주십시오.

+0

나는'item' DICT의 구조가 생각 : 키로 QTreeWidgetItem 텍스트 값을 사용 (여전히 더 나은 또는, QTreeWidgetItem 객체 자체는) 그래서 예를 들어 item = {'Item12': {'ItemEnabled': True}}

같은 딕셔너리가 쉬울 것 부적당하다. 'QTreeWidgetItem' 값을 키로 사용하는 것이 더 쉬울 것이므로'item = { 'Item12': { 'ItemEnabled': True}}'와 같은 사전을 사용하십시오. 또한이 키는'Qt.DisplayRole' 대신'Qt.UserRole'을 사용하여 저장할 수 있습니다. –

+0

이것은 제가 사용하고있는 사전의 매우 단순한 버전입니다. 내가 필요한 20 가지 항목 추적 할. –

답변

0

QTreeWidgetItem이 선택되거나 선택 해제되면 QTreeWidget.itemChanged(item, column) 신호가 방출됩니다. 그래서 그것을 사용하고 슬롯에 귀하의 item을 업데이트 할 수 있습니다.

그리고 내가 말한 것처럼, item의 구조가 부적절하다고 생각합니다.

from PyQt4 import QtCore, QtGui 
import sys 


class MyApplication(QtGui.QMainWindow): 
    def __init__(self): 
     super(MyApplication, self).__init__() 
     self.item = {'Item12': {'ItemEnabled': True}} 
     self.setupUi() 

     TreeList = ({ 
      'Header1': ('Item11', 'Item12',), 
      'Header2': ('Item21', 'Item22',), 
     }) 

     for key, value in TreeList.items(): 
      parent = QtGui.QTreeWidgetItem(self.treeWidget, [key]) 
      for val in value: 
       child = QtGui.QTreeWidgetItem([val]) 
       child.setFlags(child.flags() | QtCore.Qt.ItemIsUserCheckable) 
       child.setCheckState(0, QtCore.Qt.Checked if val in self.item else QtCore.Qt.Unchecked) 
       parent.addChild(child) 

     self.treeWidget.itemChanged.connect(self.treeWidgetItemChanged) 

    def setupUi(self): 
     self.centralwidget = QtGui.QWidget(self) 
     self.gridLayout = QtGui.QGridLayout(self.centralwidget) 
     self.treeWidget = QtGui.QTreeWidget(self.centralwidget) 
     self.gridLayout.addWidget(self.treeWidget) 
     self.setCentralWidget(self.centralwidget) 

    def treeWidgetItemChanged(self, widgetItem, column): 
     print("Item {} is checked: {}".format(widgetItem, widgetItem.checkState(column) == QtCore.Qt.Checked)) 
     itemName = str(widgetItem.text(column)) 
     try: 
      self.item[itemName]['ItemEnabled'] = widgetItem.checkState(column) == QtCore.Qt.Checked 
     except KeyError: 
      self.item[itemName] = {'ItemEnabled': widgetItem.checkState(column) == QtCore.Qt.Checked} 

     print(self.item) 


if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    w = MyApplication() 
    w.show() 
    sys.exit(app.exec_()) 
+0

사용자가 체크 박스를 체크하거나 체크하지 않을 때 문제가 해결되지만'item = {} '사전을 읽고 QTreeView의 체크 박스에'ItemEnabled' 값을 적용하면 어떨까요? 참고로 필자는 PyQt5와 Python 3을 사용하고 있으므로 답변을 수정해야 작업 할 수 있습니다. –

+0

그것도 끝났습니다 (필자는 내 대답을 여러 번 편집했습니다 : p). PyQt5를 설치하지 않았지만 많은 노력을 기울이지 않아도 작동합니다. –

+0

이 방법이 효과적이지만, 여전히 내가 원하는 컨트롤을 제공하지 못합니다. 'self.treeWidget.itemChanged.connect (self.treeWidgetItemChanged)'를 사용하지 않고'treeWidgetItemChanged'를 호출하는 방법이 있습니까? 필자가 생각하기에'self.treeWidget'이'self.item' 전에 인스턴스화되기 때문입니다. 'widgetItem'은'self.treeWidget'에서 전달 된 객체이기 때문에 대답은 no라고 가정합니다. 그 부분에 대해 새로운 질문이 필요할 수도 있습니다. –