반응형
Notice
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 네트워크보안
- 자료구조
- 프로그래밍언어
- 컴퓨터과학
- 딥러닝
- 클라우드컴퓨팅
- 컴퓨터비전
- 인공지능
- 사이버보안
- 데이터구조
- 데이터과학
- 파이썬
- 보안
- 2
- 웹개발
- 소프트웨어
- I'm Sorry
- Yes
- 네트워크
- 자바스크립트
- 컴퓨터공학
- 코딩
- 프로그래밍
- 버전관리
- 빅데이터
- 데이터분석
- 데이터베이스
- 머신러닝
- 알고리즘
- 소프트웨어공학
Archives
- Today
- Total
스택큐힙리스트
PyQt5: 팬더 테이블 모델에 대한 removeRows 구현 본문
반응형
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt,QDate,QThread
from net_comm_ui import Ui_MainWindow
from PyQt5.QtWidgets import QApplication, QMainWindow
from pathlib import Path
import multiprocessing
from TableModel import TableModel
from CheckableComboBox import CheckableComboBox
import copy
import datetime
import re
import json
from pathlib import Path
import pandas as pd
import os
from net_comm_worker import Worker
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtCore import pyqtSlot
dept_list = ['A','B','C','D','E','F','G','H']
combo_type=['METHOD','LOB','DEPT','CHANNEL']
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.tableView = QtWidgets.QTableView()
import pandas as pd
mydict = [{'a': 1, 'b': 2, 'c': 3, 'd': 4},
{'a': 100, 'b': 200, 'c': 300, 'd': 400},
{'a': 1000, 'b': 2000, 'c': 3000, 'd': 4000 }]
self.data=pd.DataFrame(mydict)
print('initial self.data')
print(self.data)
self.data['Allocation Method'] = ''
self.data['Allocation Method Selected']=''
self.data['Allocation LOB'] = ''
self.data['Allocation LOB Selected']=''
self.data['Allocation DEPT'] = ''
self.data['Allocation DEPT Selected']=''
self.data['Allocation CHANNEL'] = ''
self.data['Allocation CHANNEL Selected']=''
self.model = TableModel(self.data)
self.tableView.setModel(self.model)
self.setCentralWidget(self.tableView)
self.setGeometry(600, 200, 500, 300)
count=len(combo_type)
# Set ComboBox to cells
for type in combo_type:
for row_num in range(self.model._data.shape[0]):
# print(i)
combo = CheckableComboBox(dept_list,self.model._data,row_num,type,count)
self.tableView.setIndexWidget(self.model.index(row_num, self.model._data.shape[1] - 2*count), combo)
count=count-1
button = QPushButton('행 삭제', self)
button.move(100,200)
button.clicked.connect(self.delete_row)
def delete_row(self):
index = self.tableView.currentIndex()
if index.row()<self.model._data.shape[0]:
self.model.removeRows(index.row(), 1, index)
print('self.model._data')
print(self.model._data)
print('self.data')
print(self.data)
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
한 행을 추가하는 메소드를 추가합니다. TableView를 업데이트하기 위해 self.layoutChanged.emit()는 필수인가요? 아니면 더 효율적인 방법이 있을까요?:
def insertRows(self, position, rows, QModelIndex, parent):
self.beginInsertRows(QModelIndex, position, position+rows-1)
default_row=[[None] for _ in range(self._data.shape[1])]
new_df=pd.DataFrame(dict(zip(list(self._data.columns),default_row)))
self._data=pd.concat([self._data,new_df])
self._data.reset_index(drop=True, inplace=True)
self.endInsertRows()
self.layoutChanged.emit() # ==> 이것은 필수인가요?
return True
답변 1
예제는 removeRows
에 잘못된 인덱스를 전달하고, 시작과 끝 값을 올바르게 계산하지 않습니다. 이를 다음과 같이 수정할 수 있습니다:
class MainWindow(QtWidgets.QMainWindow):
...
def delete_row(self):
index = self.tableView.currentIndex()
self.model.removeRows(index.row(), 1)
def insert_row(self):
self.model.insertRows(self.model.rowCount(), 1)
class TableModel(QtCore.QAbstractTableModel):
...
def rowCount(self, parent=QModelIndex()):
...
def columnCount(self, parent=QModelIndex()):
...
def insertRows(self, position, rows, parent=QModelIndex()):
start, end = position, position + rows - 1
if 0 <= start <= end:
self.beginInsertRows(parent, start, end)
for index in range(start, end + 1):
default_row = [[None] for _ in range(self._data.shape[1])]
new_df = pd.DataFrame(dict(zip(list(self._data.columns), default_row)))
self._data = pd.concat([self._data, new_df])
self._data = self._data.reset_index(drop=True)
self.endInsertRows()
return True
return False
def removeRows(self, position, rows, parent=QModelIndex()):
start, end = position, position + rows - 1
if 0 <= start <= end and end < self.rowCount(parent):
self.beginRemoveRows(parent, start, end)
for index in range(start, end + 1):
self._data.drop(index, inplace=True)
self._data.reset_index(drop=True, inplace=True)
self.endRemoveRows()
return True
return False
클래스 TableModel(QtCore.QAbstractTableModel):...
def rowCount(self, parent=QModelIndex()):...
def columnCount(self, parent=QModelIndex()):...
def insertRows(self, position, rows, parent=QModelIndex()):...
start, end = position, position + rows - 1
if 0 <= start <= end:
self.beginInsertRows(parent, start, end)
for index in range(start, end + 1):
default_row = [[None] for _ in range(self._data.shape[1])]
new_df = pd.DataFrame(dict(zip(list(self._data.columns), default_row)))
self._data = pd.concat([self._data, new_df])
self._data = self._data.reset_index(drop=True)
self.endInsertRows()
return True
return False
def removeRows(self, position, rows, parent=QModelIndex()):...
start, end = position, position + rows - 1
if 0 <= start <= end and end < self.rowCount(parent):
self.beginRemoveRows(parent, start, end)
for index in range(start, end + 1):
self._data.drop(index, inplace=True)
self._data.reset_index(drop=True, inplace=True)
self.endRemoveRows()
return True
return False
답변 2
PyQt5: Pandas 테이블 모델에 대한 removeRows 구현PyQt5는 Python 프로그래밍 언어를 위한 강력한 GUI 프레임워크입니다. Pandas는 데이터 조작과 분석을 위한 많은 기능을 제공하는 Python 라이브러리입니다. 이 두 가지를 함께 사용하여 테이블 모델을 구현하고, 특히 removeRows 메서드를 구현하는 방법에 대해 알아보겠습니다.
Pandas는 테이블 형태의 데이터를 다룰 때 매우 편리한 기능을 제공합니다. 이 기능을 PyQt5의 QAbstractTableModel을 확장하여 사용할 수 있습니다. 먼저, pandas 모델 클래스를 작성해야 합니다.
```python
from PyQt5.QtCore import Qt, QAbstractTableModel
class PandasTableModel(QAbstractTableModel):
def __init__(self, df):
super().__init__()
self.df = df
def rowCount(self, parent):
return len(self.df)
def columnCount(self, parent):
return len(self.df.columns)
def data(self, index, role):
if role == Qt.DisplayRole:
return str(self.df.iloc[index.row(), index.column()])
def headerData(self, section, orientation, role):
if role == Qt.DisplayRole:
if orientation == Qt.Horizontal:
return str(self.df.columns[section])
if orientation == Qt.Vertical:
return str(self.df.index[section])
def removeRows(self, row, count, parent):
self.beginRemoveRows(parent, row, row + count - 1)
self.df.drop(self.df.index[row:row + count], inplace=True)
self.endRemoveRows()
return True
```
이 코드에서 PandasTableModel 클래스는 QAbstractTableModel을 상속받아 필요한 메서드를 오버라이딩합니다. rowCount 및 columnCount 메서드는 데이터 프레임의 행과 열 개수를 반환합니다. data 메서드에서는 특정 인덱스에 대한 데이터 값을 반환합니다. headerData 메서드는 테이블의 헤더 데이터를 반환합니다.
그리고 removeRows 메서드는 특정 범위의 행을 삭제하는 로직을 구현합니다. 이 메서드는 QAbstractItemModel의 추상 메서드를 오버라이딩하고 있으며, 특정 행의 인덱스와 개수를 받아 해당 행을 데이터 프레임에서 삭제합니다.
이렇게 구현된 PandasTableModel은 PyQt5의 QTableView와 함께 사용할 수 있습니다.
```python
from PyQt5.QtWidgets import QApplication, QTableView
import pandas as pd
# 예시 데이터프레임
data = {'Name': ['John', 'Peter', 'Amy', 'Megan'],
'Age': [25, 32, 18, 40],
'City': ['Seoul', 'Busan', 'Daegu', 'Suwon']}
df = pd.DataFrame(data)
app = QApplication([])
view = QTableView()
model = PandasTableModel(df)
view.setModel(model)
view.show()
app.exec_()
```
이 예시 코드에서는 Pandas 데이터프레임으로부터 모델을 생성하고, QTableView 위에 모델을 설정하여 테이블을 표시합니다.
removeRows 메서드를 호출하여 데이터프레임에서 특정 범위의 행을 삭제하면 테이블에서도 자동으로 해당 행이 삭제됩니다.
PyQt5와 Pandas를 함께 사용하여 테이블 모델을 구현하는 방법에 대해 알아보았습니다. 이 방법은 데이터 조작 및 분석에 유용하게 사용될 수 있으며, SEO에 공감하면서 더 많은 관심과 방문자를 유도할 수 있는 문서를 작성할 수 있습니다.
반응형
Comments