2016-10-17 14 views
1

QHeaderView의 헤더를 클릭하면 QTableView를 정렬하고 싶습니다. 나는이 같은 인터넷에서 여러 코드 샘플을 발견했습니다 : Sort QTableView in pyqt5 하지만 그것은 나를 위해 작동하지 않습니다. 나는 또한 서머 필드 (Summerfield)의 Rapid Gui 프로그래밍 북을보고 있지만, 나는 작동하고있는 것을 발견 할 수 있었다.PyQt5 : QHeaderView의 헤더를 클릭하면 QTableView를 정렬하는 방법은 무엇입니까?

빠른 예제에서 이름이나 나이별로 테이블을 정렬하는 방법은 무엇입니까? 나는 시도는 몇 가지를 수정했습니다

from PyQt5.QtGui import * 
from PyQt5.QtWidgets import * 
from PyQt5.QtCore import * 
import pandas as pd 
import operator 

# This class was generated from the Qt Creator 
class Ui_tableView_ex(object): 
    def setupUi(self, tableView_ex): 
     tableView_ex.setObjectName("tableView_ex") 
     tableView_ex.resize(800, 600) 
     self.centralwidget = QWidget(tableView_ex) 
     self.centralwidget.setObjectName("centralwidget") 
     self.gridLayout = QGridLayout(self.centralwidget) 
     self.gridLayout.setObjectName("gridLayout") 
     self.myTable = QTableView(self.centralwidget) 
     self.myTable.setObjectName("monTablo") 
     self.gridLayout.addWidget(self.myTable, 0, 0, 1, 1) 
     tableView_ex.setCentralWidget(self.centralwidget) 

     self.retranslateUi(tableView_ex) 
     QMetaObject.connectSlotsByName(tableView_ex) 

    def retranslateUi(self, tableView_ex): 
     _translate = QCoreApplication.translate 
     tableView_ex.setWindowTitle(_translate("tableView_ex", "MainWindow")) 


class TableTest(QMainWindow, Ui_tableView_ex): 
    def __init__(self, parent=None): 
     super(TableTest, self).__init__(parent) 
     self.setupUi(self) 

     self.model = TableModel() 
     self.myTable.setModel(self.model) 
     self.myTable.setShowGrid(False) 

     self.hView = HeaderView(self.myTable) 
     self.myTable.setHorizontalHeader(self.hView) 
     self.myTable.verticalHeader().hide() 

     # adding alternate colours 
     self.myTable.setAlternatingRowColors(True) 
     self.myTable.setStyleSheet("alternate-background-color: rgb(209, 209, 209)" 
            "; background-color: rgb(244, 244, 244);") 

     # self.myTable.setSortingEnabled(True) 
     # self.myTable.sortByColumn(1, Qt.AscendingOrder) 


class HeaderView(QHeaderView): 
    def __init__(self, parent): 
     QHeaderView.__init__(self, Qt.Horizontal, parent) 
     self.model = TableModel() 
     self.setModel(self.model) 

     # Setting font for headers only 
     self.font = QFont("Helvetica", 12) 
     self.setFont(self.font) 

     # Changing section backgroud color. font color and font weight 
     self.setStyleSheet("::section{background-color: pink; color: green; font-weight: bold}") 

     self.setSectionResizeMode(1) 
     self.setSectionsClickable(True) 


class TableModel(QAbstractTableModel): 

    def __init__(self): 
     QAbstractTableModel.__init__(self) 
     super(TableModel, self).__init__() 

     self.headers = ["Name", "Age", "Grades"] 
     self.stocks = [["George", "26", "80%"], 
         ["Bob", "16", "95%"], 
         ["Martha", "22", "98%"]] 
     self.data = pd.DataFrame(self.stocks, columns=self.headers) 

    def update(self, in_data): 
     self.data = in_data 

    def rowCount(self, parent=None): 
     return len(self.data.index) 

    def columnCount(self, parent=None): 
     return len(self.data.columns.values) 

    def setData(self, index, value, role=None): 
     if role == Qt.EditRole: 
      row = index.row() 
      col = index.column() 
      column = self.data.columns.values[col] 
      self.data.set_value(row, column, value) 
      self.update(self.data) 
      return True 

    def data(self, index, role=None): 
     if role == Qt.DisplayRole: 
      row = index.row() 
      col = index.column() 
      value = self.data.iloc[row, col] 
      return value 

    def headerData(self, section, orientation, role=None): 
     if role == Qt.DisplayRole: 
      if orientation == Qt.Horizontal: 
       return self.data.columns.values[section] 

# -----------------NOT WORKING!!!--------------- 
# ================================================= 

    def sort(self, Ncol, order): 
     """Sort table by given column number. 
     """ 
     self.layoutAboutToBeChanged.emit() 
     self.data = sorted(self.data, key=operator.itemgetter(Ncol)) 
     if order == Qt.DescendingOrder: 
      self.data.reverse() 
     self.layoutChanged.emit() 
# ================================================= 


if __name__ == '__main__': 
    import sys 
    app = QApplication(sys.argv) 
    app.setStyle(QStyleFactory.create("Fusion")) 
    main_window = TableTest() 
    main_window.show() 
    app.exec_() 
    sys.exit() 

, 아무것도 밖으로 일하지 않고 나는 setSortingEnabled (true)를 주석을 해제 할 때 창이조차 열리지 않습니다 라인 :

여기 내 코드입니다. 솔루션에 더 가깝거나 그렇지 않은 경우 알 수있는 방법이 없습니다. 학년에 따라 텍스트 색상을 변경하고 싶습니다 (50 미만의 빨간색은 예를 들어 50 이상의 녹색). 그것을 위해, 나는 그렇게 많이 검색하지 않고있다. 그래서 나는 질문을하기 전에 혼자서 그것을 시도 할 것이다. 그러나 당신은 어떤 힌트라도 가지고있다. 그것은 매우 감사 할 것이다!

도움 주셔서 감사합니다.

답변

2

정렬 기능이 문제가되고 팬더 DataFrame 정렬 기능을 사용하지 않고 self.data이 파이썬 list이되면 다른 기능이 실패하고 프로그램이 중단됩니다.

올바르게 DataFrame이 같은 sort_values 기능을 사용하여 정렬하려면 :

def sort(self, Ncol, order): 
    """Sort table by given column number.""" 
    self.layoutAboutToBeChanged.emit() 
    self.data = self.data.sort_values(self.headers[Ncol], 
             ascending=order == Qt.AscendingOrder) 
    self.layoutChanged.emit() 
+0

감사합니다, 그것은 완벽하게 작동하고! QtableView로 작업 할 때 모든 사람들이 자신의 모델 목록에있는 목록을 사용하는 것으로 나타났습니다. 모델의 목록 목록 대신 DataFrame을 사용하면 어떤 장점이 있습니까? – BillyBoom

+1

'DataFrame' 기능이 필요하지 않다면'list of list'는 조작하기가 더 쉽고 (다른 곳에서는 사용되지 않는 한) 팬더와의 의존성을 피할 수 있습니다. – Ceppo93