[파이썬] PyQt 트리 뷰 (`QTreeView`) 및 트리 모델

파이썬에서는 PyQt를 사용하여 다양한 그래픽 사용자 인터페이스(GUI) 응용 프로그램을 개발할 수 있습니다. 그 중에서도 QTreeView와 트리 모델을 사용하면 트리 형태의 데이터를 표시하고 조작하는 데 효과적인 방법을 제공합니다.

트리 뷰는 일반적으로 파일 탐색기, 디렉토리 구조, 계층적 데이터 등을 표시하는 데 사용됩니다. 트리 모델은 트리 뷰에 데이터를 공급하고 관리하는 역할을 합니다.

1. PyQt 설치하기

먼저 PyQt를 설치해야 합니다. 아래 명령을 사용하여 PyQt를 설치할 수 있습니다:

pip install pyqt5

2. 기본적인 트리 뷰 생성하기

아래 예제 코드는 기본적인 트리 뷰를 생성하는 방법을 보여줍니다:

from PyQt5.QtWidgets import QApplication, QMainWindow, QTreeView, QVBoxLayout, QWidget
from PyQt5.QtCore import QAbstractItemModel

class TreeModel(QAbstractItemModel):
    # 트리 모델을 정의합니다.
    # 자세한 구현은 생략합니다.
    pass

if __name__ == '__main__':
    app = QApplication([])
    
    # 메인 윈도우를 생성합니다.
    main_window = QMainWindow()
    main_window.setWindowTitle("Tree View Example")
    
    # 트리 뷰의 모델을 생성합니다.
    model = TreeModel()
    
    # 트리 뷰를 생성하고 모델과 연결합니다.
    tree_view = QTreeView()
    tree_view.setModel(model)
    
    # 메인 윈도우의 레이아웃을 설정합니다.
    layout = QVBoxLayout()
    layout.addWidget(tree_view)
    
    # 메인 윈도우에 위젯을 설정합니다.
    widget = QWidget()
    widget.setLayout(layout)
    main_window.setCentralWidget(widget)
    
    # 메인 윈도우를 표시합니다.
    main_window.show()
    
    app.exec()

위 예제 코드에서는 QAbstractItemModel을 상속하여 TreeModel을 정의하고, QTreeViewTreeModel을 연결하여 트리 뷰를 생성합니다. 이때, QMainWindowQApplication을 사용하여 메인 윈도우를 생성하고 실행합니다.

3. 트리 뷰에 데이터 표시하기

실제로 유용한 트리 뷰를 만들려면 트리 모델에 데이터를 추가하고 표시할 필요가 있습니다. 아래 예제 코드는 트리 모델에 데이터를 추가하는 방법을 보여줍니다:

from PyQt5.QtCore import Qt, QModelIndex

class TreeModel(QAbstractItemModel):
    def __init__(self, root_data, parent=None):
        super().__init__(parent)
        self.root = Node(root_data)
    
    def rowCount(self, parent):
        if parent.column() > 0:
            return 0
        if not parent.isValid():
            parent_node = self.root
        else:
            parent_node = parent.internalPointer()
        return parent_node.child_count()

    def columnCount(self, parent):
        return 1

    def data(self, index, role):
        if not index.isValid():
            return None
        node = index.internalPointer()
        if role == Qt.DisplayRole:
            return node.get_data()
        return None

    def index(self, row, column, parent):
        if not self.hasIndex(row, column, parent):
            return QModelIndex()

        if not parent.isValid():
            parent_node = self.root
        else:
            parent_node = parent.internalPointer()

        child = parent_node.get_child(row)
        if child:
            return self.createIndex(row, column, child)
        else:
            return QModelIndex()
    
    def parent(self, index):
        if not index.isValid():
            return QModelIndex()
        node = index.internalPointer()
        parent_node = node.get_parent()
        if parent_node == self.root:
            return QModelIndex()
        return self.createIndex(parent_node.row(), 0, parent_node)

위 예제 코드에서는 TreeModel 클래스를 수정하여 데이터를 관리하고 트리 뷰에 표시할 수 있도록 합니다. Node 클래스는 데이터와 해당 노드의 부모, 자식 노드를 저장하는 역할을 합니다. TreeModel의 메서드들은 트리 모델의 데이터 구조를 조작하고, 트리 뷰에서 필요한 메서드를 구현합니다.

4. 트리 뷰 이벤트 처리하기

트리 뷰에서 발생하는 이벤트를 처리하는 방법도 중요합니다. 예를 들어, 노드를 클릭하거나 펼치고 접을 때 이벤트를 처리할 수 있습니다. 아래 예제 코드는 트리 뷰에서 노드를 클릭할 때 출력하는 방법을 보여줍니다:

from PyQt5.QtWidgets import QApplication, QMainWindow, QTreeView, QVBoxLayout, QWidget
from PyQt5.QtCore import QAbstractItemModel, Qt

class TreeModel(QAbstractItemModel):
    # 트리 모델 정의 생략
    
if __name__ == '__main__':
    app = QApplication([])
    main_window = QMainWindow()
    main_window.setWindowTitle("Tree View Example")

    # 트리 뷰의 모델을 생성한다.
    model = TreeModel()

    tree_view = QTreeView()
    tree_view.setModel(model)
    
    def on_tree_view_clicked(index):
        node = index.internalPointer()
        print("Clicked node:", node.get_data())

    # 트리 뷰에서 발생하는 클릭 이벤트를 처리한다.
    tree_view.clicked.connect(on_tree_view_clicked)

    layout = QVBoxLayout()
    layout.addWidget(tree_view)

    widget = QWidget()
    widget.setLayout(layout)
    main_window.setCentralWidget(widget)

    main_window.show()

    app.exec()

위 예제 코드에서는 on_tree_view_clicked 함수를 정의하여 트리 뷰에서 발생하는 클릭 이벤트를 처리합니다. 클릭된 노드의 데이터를 출력합니다. tree_view.clicked 시그널에 on_tree_view_clicked 슬롯을 연결하여 트리 뷰에서 발생하는 클릭 이벤트를 처리합니다.

이렇게 PyQt의 QTreeView와 트리 모델을 사용하면 트리 형태의 데이터를 효과적으로 표시하고 조작할 수 있습니다. 이를 활용하여 파일 탐색기, 계층적 데이터 등의 응용 프로그램을 개발할 수 있습니다.