트리뷰에 콤보박스를 추가해서 옵션을 선택하도록 하는 방법입니다.
- 일부 아이템에만 우측에 콤보박스 추가
- 버튼을 누르면 현재 선택된 아이템의 정보를 보여줌
결과 화면 :
설명 :
- 파일에서 데이터를 읽어와 treeView에 아이템을 추가합니다.(한 row에 아이템 2개씩 추가)
- 콤보박스가 없는 row : [정보가 있는 item, 빈 item] 두개 추가
- 콤보박스가 있는 row : [정보가 있는 item, 콤보박스의 초기값을 가지는 item] 두개 추가
- 콤보 박스를 추가 하고 싶은 아이템을 구분하기 위해, 데이터 파일에서 #count가 있으면 콤보 박스를 생성하게 했습니다.(콤보박스 초기값이 count)
- ComboBox를 보여줄 수 있는 Delegate를 만듭니다.
- column 1에 위의 combo box용 delegate를 설정해 줍니다.
self.treeView.setItemDelegateForColumn(1, ComboDelegate(self, ["count", "1", "2", "3"]))
전체 소스 코드 :
TreeView.py
from PyQt5.QtWidgets import QDialog, QTreeView, QStyledItemDelegate, QComboBox, QWidget, QApplication, \
QStyleOptionComboBox, QVBoxLayout, QPushButton, QLabel, QItemDelegate, QStyle
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtCore import Qt, QVariant
class TreeViewDialog(QDialog):
def __init__(self):
QDialog.__init__(self)
self.treeView = QTreeView(self)
self.model = TreeModel()
self.treeView.setModel(self.model)
self.treeView.setHeaderHidden(True)
self.treeView.setItemDelegateForColumn(1, ComboDelegate(self, ["count", "1", "2", "3"]))
self.treeView.setCurrentIndex(self.model.index(0, 0))
self.treeView.setColumnWidth(0, 300)
self.treeView.expandAll()
self.treeView.clicked.connect(self.treeViewClicked)
self.button = QPushButton(self)
self.button.setText("Show selected item")
self.button.clicked.connect(self.onButtonClicked)
self.label = QLabel(self)
self.label.setText("...")
vBox = QVBoxLayout(self)
vBox.addWidget(self.treeView)
vBox.addWidget(self.button)
vBox.addWidget(self.label)
self.setLayout(vBox)
self.resize(500, 300)
def onButtonClicked(self):
indexes = self.treeView.selectedIndexes()
txt = ''
for index in indexes:
txt += '{},'.format(index.data())
self.label.setText(txt)
def treeViewClicked(self, index):
if not index.isValid():
return
print('row {}, col {}'.format(index.row(), index.column()))
class TreeModel(QStandardItemModel):
def __init__(self):
super(TreeModel, self).__init__()
self.readData()
def readData(self):
rootParentItem = self.invisibleRootItem()
roots = set()
item = None
with open('data.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()
for line in lines:
line = line.strip()
subs = line.split(">")
category = subs[0]
if category not in roots:
item = self.appendChild(category, rootParentItem, category)
roots.add(category)
if len(subs) > 1:
name = subs[1]
self.appendChild(name, item, name)
def appendChild(self, title, parentItem, toolTip = None):
item2 = None
if '#count' in title:
item2 = TreeItem('count', "")
title = title.replace("#count", "")
else:
item2 = TreeItem('', '')
item2.setEditable(False)
item = TreeItem(title, toolTip)
item.setData(title)
item.setEditable(False)
parentItem.appendRow([item, item2])
return item
class TreeItem(QStandardItem):
def __init__(self, text, toolTip):
QStandardItem.__init__(self)
self.setText(text)
self.setToolTip(toolTip)
class ComboDelegate(QStyledItemDelegate):
def __init__(self, owner, items):
super(ComboDelegate, self).__init__(owner)
self.items = items
def createEditor(self, parent, option, index):
self.editor = QComboBox(parent)
self.editor.addItems(self.items)
return self.editor
def paint(self, painter, option, index):
if index.data(Qt.DisplayRole) == '': # 빈 아이템이면 콤보박스 안보임
QStyledItemDelegate.paint(self, painter, option, index)
else: # 값이 있는 아이템이면 콤보박스 보임
value = index.data(Qt.DisplayRole)
style = QApplication.style()
opt = QStyleOptionComboBox()
opt.text = str(value)
opt.rect = option.rect
style.drawComplexControl(QStyle.CC_ComboBox, opt, painter)
QStyledItemDelegate.paint(self, painter, option, index)
def setEditorData(self, editor, index):
value = index.data(Qt.DisplayRole)
num = self.items.index(value)
editor.setCurrentIndex(num)
if index.column() == 1:
editor.showPopup()
def setModelData(self, editor, model, index):
value = editor.currentText()
model.setData(index, QVariant(value), Qt.DisplayRole)
def updateEditorGeometry(self, editor, option, index):
editor.setGeometry(option.rect)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
treeview = TreeViewDialog()
treeview.show()
sys.exit(app.exec_())
data.txt
Fruits>Apple#count
Fruits>Banana#count
Fruits>Grape
Vegetables>Tomato#count
Vegetables>Cucumber#count
'개발 > Qt' 카테고리의 다른 글
[PyQt] 파이썬에서 Qt 리소스(Resource) 파일 활용하기 (0) | 2021.11.08 |
---|---|
[PyQt] StyleSheet 사용해서 QComboBox 색상 변경 (0) | 2021.11.06 |
[PyQt] QTreeView에서 각 아이템마다 다른 툴팁 설정하기 (0) | 2021.11.01 |
[PyQt] 파일에서 데이터 읽어 테이블로 보여주기(QTableWidget) (0) | 2021.10.30 |
[PyQt] 스크롤 가능한 영역(ScrollArea)에 사진 추가하기 (0) | 2021.10.28 |