본문으로 바로가기
반응형

QTreeView 는 엑셀처럼 여러 행과 열을 가진 데이터를 나열할 때 많이 사용합니다. 또는 탐색기의 폴더 구조와 유사한 트리 데이터를 구성하고 싶을 때 사용하는 위젯입니다.

 

QTreeView를 만드는 과정은 다음과 같습니다. 먼저 QTreeView 위젯 객체를 생성합니다. 다음은 QTreeView 에 추가할 데이터 객체인 QStandItemModel 을 생성합니다. QTreeView 가 트리 구조에서 껍데기라면 QStandItemModel 는 내부의 데이터를 관리하는 객체입니다. QStandItemModel 객체는 QTreeView setModel() 함수를 이용해서 추가합니다. 이렇게 추한  QStandItemModel 에 타이틀과 행 단위의 데이터를 추가합니다.

 

QTreeView 객체를 생성합니다. 그리고 직접 만든 create_model() 함수를 통해 QStandItemModel 객체를 만든 후  QTreeView setModel() 함수를 이용해서 추가합니다.

from PyQt5.QtWidgets import QTreeView

self.tree_view = QTreeView()
model = self.create_model()
self.tree_view.setModel(model)

 

create_model() 함수는 다음과 같습니다. QStandItemModel 객체를 생성하고 타이틀을 설정합니다. QStandItemModel 매개변수로 넘긴 2개의 숫자는 row, column 개수 입니다.

from PyQt5.QtGui import QStandardItemModel
from PyQt5.Qt import Qt

def create_model(self):
    model = QStandardItemModel(0, 3)
    model.setHeaderData(self.one, Qt.Horizontal, "Name")
    model.setHeaderData(self.two, Qt.Horizontal, "Size")
    model.setHeaderData(self.tree, Qt.Horizontal, "Type")
    return model

 

다음은 이전에 추가한 QStandItemModel 객체에 행을 추가하는 함수를 만듭니다. 매개변수에 QStandItemModel 을 넘겨 받아서 값을 하나씩 추가합니다. insertRow() 는 행의 인덱스를 가리키며, 매번 0 을 입력하기 때문에 새로 추가한 데이터는 제일 상위로 올라갑니다. 동일한 행에서의 데이터의 위치값은 model.index(0, self.one) 으로 구분합니다. 두 번째 매개변수로 입력한 self.one 은 열 번호에 해당합니다.

def add_file(self, model, file_name, file_size, file_type):
    model.insertRow(0)
    model.setData(model.index(0, self.one), file_name)
    model.setData(model.index(0, self.two), file_size)
    model.setData(model.index(0, self.tree), file_type)

 

위에서 소개한 두 개의 함수를 이용해서 QTreeView 를 완성하는 소스는 다음과 같습니다.

# QTreeView 추가
self.tree_view = QTreeView()
model = self.create_model()
self.tree_view.setModel(model)
self.add_file(model, 'File1', '350', 'File Folder')
self.add_file(model, 'File2', '480', 'File Folder')
self.add_file(model, 'File3', '1000', 'File Folder')

 

전체 소스는 다음과 같습니다.

#-*- coding:utf-8 -*-
import sys
from PyQt5.QtWidgets import QMainWindow,QApplication, QTreeView
from PyQt5.QtGui import QStandardItemModel
from PyQt5.Qt import Qt


class MainWindow(QMainWindow):
    one, two, tree = range(3)  # treeview 의 열에 해당하는 index 번호 생성

    def __init__(self):
        super().__init__()
        self.setGeometry(100, 100, 600, 300)
        self.setWindowTitle('Test Signal')

        # QTreeView 추가
        self.tree_view = QTreeView()
        model = self.create_model()
        self.tree_view.setModel(model)
        self.add_file(model, 'File1', '350', 'File Folder')
        self.add_file(model, 'File2', '480', 'File Folder')
        self.add_file(model, 'File3', '1000', 'File Folder')

        self.setCentralWidget(self.tree_view)

    def create_model(self):
        model = QStandardItemModel(0, 3)
        model.setHeaderData(self.one, Qt.Horizontal, "Name")
        model.setHeaderData(self.two, Qt.Horizontal, "Size")
        model.setHeaderData(self.tree, Qt.Horizontal, "Type")
        return model

    def add_file(self, model, file_name, file_size, file_type):
        model.insertRow(0)
        model.setData(model.index(0, self.one), file_name)
        model.setData(model.index(0, self.two), file_size)
        model.setData(model.index(0, self.tree), file_type)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())

 

파일 정보를 보여주는 탐색기 만들기

 

다음은 로컬 PC 의 파일 목록을 QTreeView 에 표현하는 방법을 알아보겠습니다. 아래 소개한 방법을 응용하면 윈도우 탐색기와 동일한 트리 구조를 구현할 수 있습니다. 방법은 간단합니다. PyQt5 에서는 로컬 PC 의 파일정보를 쉽게 처리할 수 있는 QFileSystemModel 클래스를 제공하기 때문입니다. QFileSystemModel 클래스로 Model 객체를 만들어서 QTreeView setModel() 함수를 이용해 세팅하면 끝입니다.

 

좀더 상세히 알아보겠습니다. QFileSystemModel() 클래스로 모델 객체를 생성합니다. 다음은 어디서부터 파일 목록을 불러올지 결정해야 합니다. QtCore.QDir.rootPath() 는 윈도우가 설치되어 있는 디스크 루트를 반환합니다. 보통 “C:\\” 드라이버입니다. QtCore.QDir.rootPath() 을 사용하지 않고 사용자가 직접 setRootPath() 에 입력할 수도 있습니다. QTreeView 에 추가할 QFileSystemModel 모델 객체의 세팅은 끝났습니다.

self.path_root = QtCore.QDir.rootPath()
self.model = QFileSystemModel()
self.model.setRootPath(self.path_root)

 

QTreeView 객체를 생성하고 setModel() 함수를 이용해서 QFileSystemModel() 객체를 세팅합니다. 다음은 QFileSystemModel 객체에 들어가 있는 파일 목록에서 어느 부분을 보여줄지 결정해야 합니다. 그것이 바로 QTreeView setRootIndex() 함수 입니다. 함수에 들어갈 매개변수인 인덱스 값은 QFileSystemModel index() 함수로 추출합니다. index() 의 매개변수에는 폴더 위치를 입력합니다. 이렇게 추출한 인덱스 값이 setRootIndex() 의 매개변수가 됩니다.

self.index_root = self.model.index(self.model.rootPath())

self.tree_view = QTreeView()
self.tree_view.setModel(self.model)
self.tree_view.setRootIndex(self.index_root)
self.tree_view.clicked.connect(self.on_treeView_clicked)

 

전체 소스는 다음과 같습니다.

#-*- coding:utf-8 -*-
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QTreeView
from PyQt5.Qt import QFileSystemModel
from PyQt5 import QtCore
from PyQt5.QtCore import pyqtSlot


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setGeometry(100, 100, 600, 300)
        self.setWindowTitle('Test Signal')

        # 전체 파일 경로를 가져온다.
        self.path_root = QtCore.QDir.rootPath()
        self.model = QFileSystemModel()
        self.model.setRootPath(self.path_root)

        self.index_root = self.model.index(self.model.rootPath())

        self.tree_view = QTreeView()
        self.tree_view.setModel(self.model)
        self.tree_view.setRootIndex(self.index_root)
        self.tree_view.clicked.connect(self.on_treeView_clicked)

        self.setCentralWidget(self.tree_view)

    @pyqtSlot(QtCore.QModelIndex)
    def on_treeView_clicked(self, index):
        indexItem = self.model.index(index.row(), 0, index.parent())

        fileName = self.model.fileName(indexItem)
        filePath = self.model.filePath(indexItem)

        print(fileName)
        print(filePath)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())

 

실행한 결과를 볼까요? C 드라이버의 모든 폴더와 파일을 가져와서 QTreeView 에 추가했으며 파일타입, 수정날짜, 사이즈 등의 정보도 쉽게 표현할 수 있었습니다.

반응형