inflearn logo
강의

講義

知識共有

[Level 1] Qtを使ったPythonプログラミング:入門編

カスタムモデルクラスの実装例 Part 1

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

242

TaeJoon Park

投稿した質問数 5

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로 선언된 함수는 어느 시점에 실행이 되는 건가요?

 

python gui qt qml pyside6

回答 2

0

qtdev

안녕하세요. 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 내부에서 필요한 정보를 얻기 위해 자동으로 호출됩니다.

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

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

1

padohy

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

1

qtdev

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

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

0

communityai8509

안녕하세요, 인프런 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 )

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

6-6

0

4

0

작업형 1 유형 부분

0

9

1

수강평 이벤트

0

16

2

작업형 1 (삭제예정, 구 버전)

0

28

2

강의노트는 어디있나요?

0

17

1

노션 학습 자료 권한 요청

0

16

1

수강기간 연장 문의드립니다.

0

21

1

2유형 레이블 인코딩 VS 원핫 인코딩

0

22

3

part2강의 문의사항입니다.

0

19

2

수강기간 연장 문의드립니다.

0

26

1

인덱스 슬라이싱

0

27

2

코드를 첨부해야하는 이유가 있나요?

0

20

2

QT와 QT Designer에 대한 질문 사항

1

167

2

mutex, incNumber는 global 안붙여도 되는건가요?

1

115

2

Qt Resource를 사용하는 예제 구현 10:15 구간 질의

1

140

2

데코레이터 @Slot을 꼭 써줘야 하는 건가요?

1

150

2

self가 있는 거와 없는 버튼

1

119

2

선호하는 GUI 개발 방법이 있으신가요

1

304

2

가장 큰 위젯의 너비와 같은 너비를 차지하는 2열 짜리 컬럼

1

228

2

exe 배포 시 .ui 파일 처리하는 권장하는 방법이 있나요?

1

306

1

클래스 __init__(self) 설정에서 이해가 안 되는 부분이 있습니다.

2

300

2

pyqt? pysie6? 차이점이 있을까요?

1

1316

2

자주 사용하는 Layout 살펴보기

1

151

2

강의 pdf파일 올려 주시면 안될까요?

2

236

2