2View1Model_Demo/
├─ main.py # 실행 진입점 (QApplication 생성 + 메인 위젯 표시)
└─ widget.py # 하나의 QFileSystemModel(모델)을
# - QTreeView (폴더 트리)
# - QListView (선택된 폴더 안의 파일/폴더 목록)
# 두 개의 View가 함께 공유하는 예제 위젯.
# widget.py
import sys
from PySide6.QtCore import QDir
from PySide6.QtWidgets import (
QWidget, QSplitter,
QFileSystemModel, QTreeView, QListView,
QVBoxLayout
)
class Widget(QWidget):
"""
하나의 QFileSystemModel(모델)을
- QTreeView (폴더 트리)
- QListView (선택된 폴더 안의 파일/폴더 목록)
두 개의 View가 함께 공유하는 예제 위젯.
"""
def __init__(self, parent=None):
super().__init__(parent)
# [1] 기본 창 설정
self.setWindowTitle("Model/View 데모 - QTreeView + QListView")
self.resize(800, 400)
# [2] 공통 모델 생성 (파일 시스템 모델)
self.model = QFileSystemModel(self)
# Data(현재 작업 디렉토리를 루트 경로) 설정
root_path = QDir.currentPath()
self.model.setRootPath(root_path)
# [3] 스플리터 생성 (왼쪽 트리, 오른쪽 리스트)
splitter = QSplitter(self)
# --- (1) TreeView 설정 ---
self.tree_view = QTreeView(splitter)
self.tree_view.setModel(self.model)
# 트리뷰 루트 인덱스 설정
self.tree_view.setRootIndex(self.model.index(root_path))
# 폴더만 보이게 하고 싶다면 옵션들 조정 가능 (예: self.tree_view.setRootIsDecorated(True) 등)
# --- (2) ListView 설정 ---
self.list_view = QListView(splitter)
self.list_view.setModel(self.model)
self.list_view.setRootIndex(self.model.index(root_path))
# [4] 트리에서 선택이 바뀌면, 리스트 뷰도 같이 변경되도록 연결
# selectionModel()은 "선택 상태"를 관리하는 모델
self.tree_view.selectionModel().currentChanged.connect(
self.on_tree_current_changed
)
# [5] 전체 레이아웃
layout = QVBoxLayout(self)
layout.addWidget(splitter)
self.setLayout(layout)
# 슬롯 함수: 트리에서 선택된 폴더에 맞춰 리스트뷰 갱신
def on_tree_current_changed(self, current, previous):
"""
트리에서 선택이 바뀔 때마다 호출됨.
- current : 현재 선택된 QModelIndex
- previous: 이전에 선택되어 있던 QModelIndex
"""
# current가 디렉토리이면, 그 폴더를 리스트뷰의 루트로 사용
if self.model.isDir(current):
self.list_view.setRootIndex(current)
else:
# 파일을 클릭한 경우 → 그 파일이 속한 부모 폴더를 리스트에 표시
parent_index = current.parent()
self.list_view.setRootIndex(parent_index)
# 프로그램 시작 시 첫 항목 자동 선택을 해제하고 싶을 때 추가
from PySide6.QtCore import QTimer, QModelIndex
QTimer.singleShot(0, self._clear_initial_selection)
def _clear_initial_selection(self):
sel_model = self.tree_view.selectionModel()
if sel_model is not None:
sel_model.clearSelection() # 선택 상태 제거
self.tree_view.setCurrentIndex(QModelIndex()) # current index 도 무효화
3.1 모델 생성 – QFileSystemModel
# [2] 공통 모델 생성 (파일 시스템 모델)
self.model = QFileSystemModel(self)
# Data(현재 작업 디렉토리를 루트 경로) 설정
root_path = QDir.currentPath()
self.model.setRootPath(root_path)
QFileSystemModel 은 디스크의 폴더/파일 구조를 Model로 표현하는 Qt의 준비된 모델 클래스입니다.
setRootPath()로 “어디부터 보여줄지”를 지정합니다.
여기서는 QDir.currentPath() → 현재 작업 폴더
이 객체 변수 model 안에 실제 파일/폴더 정보가 담기고, 그 정보를 여러 View 에서 동시에 읽어갈 수 있음.
Model/View 개념 포인트
- QFileSystemModel은 파일/폴더 정보(데이터)를 가진 Model 객체이고, - 나중에 여러 View가 이 모델을 공유하면서 서로 다른 방식으로 같은 데이터를 보여줄 수 있습니다.
- self.model 객체는 단 하나 같은 모델을 공유 - QTreeView, QListView 둘 다 setModel(self.model)로 연결 - 두 View는 “같은 데이터를 다른 모양으로 보여주는” 역할만 함 - 데이터는 모델 하나, 표현은 여러 뷰로 다양하게
지금 있는 QTreeView QListView에 추가로 QTableView를 하나 더 배치하여동일한 QFileSystemModel을 공유하는 3중 뷰 만들기
# widget.py 힌트 코드
from PySide6.QtWidgets import QTableView # 상단 import에 추가
# __init__ 안에서
# --- (3) QTableView 설정 ---
self.table_view = QTableView(splitter)
self.table_view.setModel(self.model)
self.table_view.setRootIndex(self.model.index(root_path))
# on_tree_current_changed 안에서
if self.model.isDir(current):
self.list_view.setRootIndex(current)
self.table_view.setRootIndex(current) # ← 추가
else:
parent_index = current.parent()
self.list_view.setRootIndex(parent_index)
self.table_view.setRootIndex(parent_index) # ← 추가