PyQt개발강좌, QSortFilterProxyModel로 필터링 및 정렬

안녕하세요! 이번 강좌에서는 PyQt에서 데이터를 필터링 및 정렬하기 위한 매우 유용한 도구인 QSortFilterProxyModel에 대해 깊이 있게 살펴보겠습니다. QSortFilterProxyModel은 Qt의 모델-뷰-컨트롤러(MVC) 패턴을 따른 데이터 모델입니다. 이 모델은 원본 데이터 모델에 대한 필터링과 정렬을 지원하여, 사용자에게 더욱 효율적인 데이터 관리를 제공합니다.

QSortFilterProxyModel 개요

QSortFilterProxyModel은 QAbstractProxyModel의 하위 클래스입니다. 이것은 다른 모델(예: QStandardItemModel)을 바탕으로 데이터를 표시할 수 있게 해줍니다. QSortFilterProxyModel을 사용하면 데이터의 탐색과 조작을 위한 인터페이스를 단순화할 수 있으며, 사용자 인터페이스(UI)에서 데이터를 필터링하고 정렬하는 작업을 손쉽게 수행할 수 있습니다.

QSortFilterProxyModel의 사용법

QSortFilterProxyModel을 사용하기 위해서는 먼저 원본 모델과 프록시 모델을 생성해야 합니다. 원본 모델은 데이터의 실제 내용을 담고 있으며, 프록시 모델은 이런 데이터를 필터링하거나 정렬하는 방법을 정의합니다.

예제 코드: QSortFilterProxyModel 사용하기

# 필요한 라이브러리 임포트
import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QTableView, QLineEdit, QWidget
from PyQt5.QtCore import Qt, QSortFilterProxyModel, QStringListModel

# 메인 윈도우 클래스 정의
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        
        # 데이터 모델 생성
        self.model = QStringListModel()
        self.model.setStringList(["Python", "Java", "C++", "JavaScript", "HTML", "CSS", "Ruby"])
        
        # QSortFilterProxyModel 생성
        self.proxy_model = QSortFilterProxyModel()
        self.proxy_model.setSourceModel(self.model)
        
        # 필터 입력창 생성
        self.filter_input = QLineEdit()
        self.filter_input.setPlaceholderText("언어 필터링...")
        self.filter_input.textChanged.connect(self.on_filter_changed)
        
        # 테이블 뷰 생성
        self.table_view = QTableView()
        self.table_view.setModel(self.proxy_model)
        
        # 레이아웃 설정
        layout = QVBoxLayout()
        layout.addWidget(self.filter_input)
        layout.addWidget(self.table_view)
        self.setLayout(layout)
        
        # 윈도우 설정
        self.setWindowTitle("QSortFilterProxyModel 예제")
        self.resize(400, 300)

    def on_filter_changed(self, text):
        # 텍스트에 대한 필터 설정
        self.proxy_model.setFilterFixedString(text)

# 애플리케이션 실행
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

QSortFilterProxyModel의 주요 메서드

QSortFilterProxyModel에서는 다음과 같은 주요 메서드를 활용하여 필터링 및 정렬할 수 있습니다.

  • setFilterFixedString(self, filterString): 주어진 문자열로 데이터의 필터링을 설정합니다. 이 메서드는 사용자가 입력한 텍스트 필터를 기준으로 결과를 한정하는 데 유용합니다.
  • setSortRole(self, sortRole): 정렬할 때 사용할 데이터 역할을 설정합니다. 이는 복잡한 데이터 구조를 갖는 모델에서 유용합니다.
  • sort(self, column, order=Qt.AscendingOrder): 특정 열을 기준으로 데이터를 정렬합니다.
  • filterAcceptsRow(self, sourceRow, sourceParent): 프록시에서 반환할 데이터의 각 행에 대해 필터링 로직을 정의합니다. 이를 통해 더 복잡한 필터링 논리를 구현할 수 있습니다.

고급 예제: 사용자 정의 필터링

이번에는 필터링을 사용자 정의하기 위한 방법을 살펴보겠습니다. 예를 들어, 특정 글자의 수를 기준으로 필터링할 수 있습니다. 이를 위해 filterAcceptsRow 메서드를 오버라이드하여 구현합니다.

class CustomProxyModel(QSortFilterProxyModel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.min_length = 0

    def setMinLength(self, length):
        self.min_length = length
        self.invalidateFilter()  # 필터 새로 고침

    def filterAcceptsRow(self, source_row, source_parent):
        index = self.sourceModel().index(source_row, 0, source_parent)
        value = self.sourceModel().data(index, Qt.DisplayRole)
        return len(value) >= self.min_length  # 문자열 길이 기준 필터링

# 예제 카스 생성 및 사용
class LengthFilterWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.model = QStringListModel()
        self.model.setStringList(["Short", "Average", "Extraordinary", "Long", "Tiny"])
        
        # 사용자 정의 프록시 모델
        self.proxy_model = CustomProxyModel(self)
        self.proxy_model.setSourceModel(self.model)
        
        # QTableView와 UI 설정 (생략)

QSortFilterProxyModel과 QTableView의 통합

QSortFilterProxyModel을 QTableView와 결합하여 강력한 테이블 기반 UI를 구성할 수 있습니다. 각 행이나 열을 기준으로 정렬 및 필터링 기능을 제공함으로써 사용자 경험을 향상시킬 수 있습니다. 다음은 테이블 정렬 및 필터링 기능을 가진 파이프라인을 구현하는 예제입니다.

class SortableTableView(QTableView):
    def __init__(self, model):
        super().__init__()
        self.setModel(model)
        
        # 열 헤더 스트레칭
        self.horizontalHeader().setStretchLastSection(True)
        self.setSortingEnabled(True)  # 테이블 정렬 기능 활성화

# 예제 사용
if __name__ == "__main__":
    app = QApplication(sys.argv)
    model = QStringListModel(["Python", "Java", "C++", "JavaScript", "HTML"])
    proxy = CustomProxyModel()
    proxy.setSourceModel(model)

    table_view = SortableTableView(proxy)
    table_view.show()
    sys.exit(app.exec_())

QSortFilterProxyModel의 성능

QSortFilterProxyModel은 대량의 데이터 및 복잡한 데이터 구조에서 훌륭한 성능을 보여줍니다. 필터링 및 정렬 로직은 메모리에서 원본 모델 데이터를 기반으로 이루어지기 때문에, 애플리케이션의 성능을 저하시키지 않으며 사용자 친화적인 UI를 제공합니다.

결론

이번 강좌를 통해 QSortFilterProxyModel의 기본 개념과 다양한 활용법에 대해 알아보았습니다. 데이터 모델을 효과적으로 필터링하고 정렬할 수 있는 능력은 PyQt 프로그램에서 중요한 요소이며, 이를 통해 사용자 경험을 획기적으로 개선할 수 있습니다. QSortFilterProxyModel의 사용법을 익히고, 여러분의 애플리케이션에서 훌륭한 데이터 관리 기능을 구현해 보세요!

감사합니다!