인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

TaeJoon Park님의 프로필 이미지

작성한 질문수

[Level 1] Qt를 이용한 Python 프로그래밍: 입문편

Custom Model 클래스 예제 구현 Part 1

TableModel(QAbstractTableModel) 에서 질문입니다.

작성

·

90

1

    def data(self, index, role):
        if role == Qt.DisplayRole:
            return self._data[index.row()][index.column()]
        
    def rowCount(self, index):
        return len(self._data)
    
    def columnCount(self, index):
        return len(self._data[0])
    
    def headerData(self, section, orientation, role):
        if role == Qt.DisplayRole:
            if orientation == Qt.Horizontal:
                headers = self._headerColumn
                return headers[section]
            if orientation == Qt.Vertical:
                rows = self._headerRow
                return rows[section]

안녕하세요.

class Widget(QWidget)에서 호출하는 소스가 없는데 실행이 되는거 같습니다.

위 소스에서 def로 선언된 함수는 어느 시점에 실행이 되는 건가요?

 

답변 2

0

김대진님의 프로필 이미지
김대진
지식공유자

안녕하세요. TaeJoon Park 님,

PySide6의 Model/View 프레임워크에서는 QTableView가 QAbstractTableModel의 데이터를 표시하기 위해 자동으로 해당 함수들을 호출합니다. 따라서 Widget 클래스에서 data, rowCount, columnCount, headerData 등을 명시적으로 호출하지 않아도, QTableView가 모델을 설정하는 과정에서 이 함수들을 내부적으로 호출합니다.


실제 호출 시점 분석

1. rowCount(None), columnCount(None) 호출

QTableView가 QAbstractTableModel의 데이터를 불러올 때 가장 먼저 호출됩니다.

rowCount()는 행의 개수를 반환하며, columnCount()는 열의 개수를 반환합니다.

즉, QTableView가 데이터의 크기를 알아야 테이블을 렌더링할 수 있기 때문에 가장 먼저 실행됩니다.

2. headerData(section, orientation, role) 호출

테이블의 헤더를 표시할 때 호출됩니다.

orientation == Qt.Horizontal인 경우 컬럼 헤더를 가져오고, orientation == Qt.Vertical인 경우 행 헤더를 가져옵니다.


3. data(index, role) 호출

각 셀에 데이터를 표시할 때 호출됩니다.

index.row()와 index.column() 값을 기반으로 해당 데이터를 self._data에서 가져옵니다.


디버깅을 위한 print문 추가

함수들이 언제 호출되는지 확인하려면 print()를 추가해서 실행해보면 호출 순서를 확인할 수 있습니다.

class TableModel(QAbstractTableModel):
    def __init__(self, data):
        super(TableModel, self).__init__()
        self._data = data
        self._headerColumn = []
        self._headerRow = []

    def data(self, index, role):
        if role == Qt.DisplayRole:
            print(f"data() called: row={index.row()}, column={index.column()}")
            return self._data[index.row()][index.column()]

    def rowCount(self, index):
        print("rowCount() called")
        return len(self._data)

    def columnCount(self, index):
        print("columnCount() called")
        return len(self._data[0])
    
    def setTitleColumn(self, list):
        self._headerColumn = list

    def setTitleRow(self, list):
        self._headerRow = list

    def headerData(self, section, orientation, role):
        if role == Qt.DisplayRole:
            if orientation == Qt.Horizontal:
                print(f"headerData() called for column={section}")
                return self._headerColumn[section]
            if orientation == Qt.Vertical:
                print(f"headerData() called for row={section}")
                return self._headerRow[section]

이 코드를 실행하면 콘솔에서 함수 호출 순서를 확인할 수 있습니다.

  • rowCount(), columnCount() → headerData() → data() 순으로 호출됩니다.

  • QTableView가 setModel()을 호출하는 순간 TableModel의 함수들이 자동으로 실행됩니다.

  • 따라서 Widget 클래스에서 직접 호출하지 않아도 QTableView 내부에서 필요한 정보를 얻기 위해 자동으로 호출됩니다.

혹시 더 궁금한게 있으면 언제든 질문해 주세요.

감사합니다. 김대진 드림.

padohy님의 프로필 이미지

그럼 rowCount(), columnCount(), headerData(), data() 함수들이
QAbstractTableModel의 오버라이드 함수인건가요?

김대진님의 프로필 이미지
김대진
지식공유자

네, 맞습니다. rowCount(), columnCount(), headerData(), data() 함수들은 QAbstractTableModel에서 제공하는 virtual method(가상 함수)이며, 필요에 따라 오버라이드(재정의)해서 사용하는 함수들입니다.

PySide6 (또는 Qt)에서의 Model/View 프레임워크는 QAbstractItemModel → QAbstractTableModel 같은 추상 클래스들을 기반으로 구성되어 있으며, 아래 함수들은 QAbstractTableModel을 상속받은 클래스에서 반드시(또는 자주) 오버라이드해야 하는 핵심 함수들입니다.

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다. TaeJoon Park님, 질문 주셔서 감사합니다.

Qt에서 QAbstractTableModel을 상속받아 만든 데이터 모델은 일반적으로 Qt의 View 클래스(예: QTableView)와 연결됩니다. 질문하신 메서드들, 즉 data, rowCount, columnCount, headerData는 모두 모델-뷰 패턴에서 사용됩니다. 이렇게 패턴이 구성되면, View가 모델과 연결될 때 자동으로 필요한 메서드를 호출합니다.

  1. data(self, index, role): View가 특정 셀에 표시할 데이터를 요청할 때 호출됩니다. index는 특정 셀의 행과 열 정보를 가지고 있으며, role은 데이터의 종류를 나타냅니다.

  2. rowCount(self, index)columnCount(self, index): View가 테이블의 크기를 결정할 때 호출됩니다. 즉, 몇 행과 열을 그려야 할지를 알기 위해 사용됩니다.

  3. headerData(self, section, orientation, role): View가 헤더의 내용을 표시할 필요가 있을 때 호출됩니다. orientation이 수평이면 열 헤더, 수직이면 행 헤더 정보를 요청하는 것입니다.

이 메서드들은 Qt의 탁월한 신호(Signal) 및 슬롯(Slot) 메커니즘을 통해 연결이 되며, QTableView나 다른 Viwer에 모델이 할당될 때 자동으로 호출됩니다.

아래의 링크에서 QAbstractTableModel에 대한 구체적인 예제와 설명을 확인하실 수 있습니다:
- Qt위젯과 모델-뷰( Model-View )

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.