2014-09-02 1 views
0

QTreeView에 "폴더"와 "파일"을 표시하고 싶습니다. 폴더는 파일을 포함 할 수 있습니다.이 관계로 인해 폴더 항목이 트리보기의 파일 항목 위에 표시되기를 바랍니다. 뷰는 정렬 가능해야합니다. 트리 항목에서 폴더 항목이 항상 파일 항목 위에 표시되는지 확인하려면 어떻게합니까?QTreeView가 항상 특정 카테고리의 항목을 먼저 정렬하도록하려면 어떻게합니까?

는 아래의 코드는 폴더와 파일 항목 트리 뷰의 예를 제공합니다

from PyQt5.QtCore import * 
from PyQt5.QtWidgets import * 
from PyQt5.QtGui import * 


def _create_item(text, is_folder): 
    item = QStandardItem(text) 
    item.setData(is_folder, Qt.UserRole) 
    return item 


def _folder_row(name, date): 
    return [_create_item(text, True) for text in (name, date)] 


def _file_row(name, date): 
    return [_create_item(text, False) for text in (name, date)] 


class _Window(QMainWindow): 
    def __init__(self): 
     super().__init__() 

     widget = QWidget() 
     self.__view = QTreeView() 
     layout = QVBoxLayout(widget) 
     layout.addWidget(self.__view) 
     self.setCentralWidget(widget) 

     model = QStandardItemModel() 
     model.appendRow(_file_row('File #1', '01.09.2014')) 
     model.appendRow(_folder_row('Folder #1', '01.09.2014')) 
     model.appendRow(_folder_row('Folder #2', '02.09.2014')) 
     model.appendRow(_file_row('File #2', '03.09.2014')) 
     model.setHorizontalHeaderLabels(['Name', 'Date']) 
     self.__view.setModel(model) 
     self.__view.setSortingEnabled(True) 


app = QApplication([]) 
w = _Window() 
w.show() 
app.exec_() 

답변

3

해결책은 QSortFilterProxyModel에서 모델을 포장하고, 해당 폴더 있도록 만들기 위해 프록시의 lessThan 방법을 구현할 것입니다 항목은 항상 파일 항목 앞에 배치됩니다.

from PyQt5.QtCore import * 
from PyQt5.QtWidgets import * 
from PyQt5.QtGui import * 


def _create_item(text, is_folder): 
    item = QStandardItem(text) 
    item.setData(is_folder, Qt.UserRole) 
    return item 


def _folder_row(name, date): 
    return [_create_item(text, True) for text in (name, date)] 


def _file_row(name, date): 
    return [_create_item(text, False) for text in (name, date)] 


class _SortProxyModel(QSortFilterProxyModel): 
    """Sorting proxy model that always places folders on top.""" 
    def __init__(self, model): 
     super().__init__() 
     self.setSourceModel(model) 

    def lessThan(self, left, right): 
     """Perform sorting comparison. 

     Since we know the sort order, we can ensure that folders always come first. 
     """ 
     left_is_folder = left.data(Qt.UserRole) 
     left_data = left.data(Qt.DisplayRole) 
     right_is_folder = right.data(Qt.UserRole) 
     right_data = right.data(Qt.DisplayRole) 
     sort_order = self.sortOrder() 

     if left_is_folder and not right_is_folder: 
      result = sort_order == Qt.AscendingOrder 
     elif not left_is_folder and right_is_folder: 
      result = sort_order != Qt.AscendingOrder 
     else: 
      result = left_data < right_data 
     return result 


class _Window(QMainWindow): 
    def __init__(self): 
     super().__init__() 

     widget = QWidget() 
     self.__view = QTreeView() 
     layout = QVBoxLayout(widget) 
     layout.addWidget(self.__view) 
     self.setCentralWidget(widget) 

     model = QStandardItemModel() 
     model.appendRow(_file_row('File #1', '01.09.2014')) 
     model.appendRow(_folder_row('Folder #1', '01.09.2014')) 
     model.appendRow(_folder_row('Folder #2', '02.09.2014')) 
     model.appendRow(_file_row('File #2', '03.09.2014')) 
     model.setHorizontalHeaderLabels(['Name', 'Date']) 
     proxy_model = _SortProxyModel(model) 
     self.__view.setModel(proxy_model) 
     self.__view.setSortingEnabled(True) 


app = QApplication([]) 
w = _Window() 
w.show() 
app.exec_() 
관련 문제