使用自定义 HeaderView 时列排序不起作用
Column sorting not working when using custom HeaderView
我正在尝试创建具有排序功能的 TableView
。如果我设置 TableView
obj 我的自定义 HeaderView
,单击 header 将不会排序,即使我的自定义 HeaderView
re-implements 什么也没有。
如果我改用 TableView
的 header (hh=tv.horizontalHeader()
) 它会排序。我做错了什么?
代码如下:
import sys
import operator
from PyQt5 import QtWidgets
from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant
class TableModel(QAbstractTableModel):
def __init__(self, parent, datain, headerdata):
super(TableModel,self).__init__(parent)
self.arraydata=datain
self.headerdata=headerdata
def rowCount(self,p):
return len(self.arraydata)
def columnCount(self,p):
if len(self.arraydata)>0:
return len(self.arraydata[0])
return 0
def data(self, index, role):
if not index.isValid():
return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
return QVariant(self.arraydata[index.row()][index.column()])
def headerData(self, col, orientation, role):
if orientation==Qt.Horizontal and role==Qt.DisplayRole:
return self.headerdata[col]
return None
def sort(self,col,order):
self.layoutAboutToBeChanged.emit()
self.arraydata=sorted(self.arraydata,key=operator.itemgetter(col))
if order==Qt.DescendingOrder:
self.arraydata.reverse()
self.layoutChanged.emit()
class MyHeaderView(QtWidgets.QHeaderView):
def __init__(self,parent):
super(MyHeaderView,self).__init__(Qt.Horizontal,parent)
class MainFrame(QtWidgets.QWidget):
def __init__(self):
super(MainFrame,self).__init__()
self.initUI()
def initUI(self):
self.doc_table=self.createTable()
dummy_box=QtWidgets.QLineEdit()
hlayout=QtWidgets.QHBoxLayout()
h_split=QtWidgets.QSplitter(Qt.Horizontal)
h_split.addWidget(self.doc_table)
h_split.addWidget(dummy_box)
hlayout.addWidget(h_split)
self.setLayout(hlayout)
self.show()
def createTable(self):
# create some dummy data
self.tabledata=[['aaa' ,' title1', True, 1999],
['bbb' ,' title2', True, 2000],
['ccc' ,' title3', False, 2001]
]
header=['author', 'title', 'read', 'year']
tablemodel=TableModel(self,self.tabledata,header)
tv=QtWidgets.QTableView(self)
tv.setModel(tablemodel)
# Optional 1: use custom headerview, sorting not working
#hh=MyHeaderView(tv)
#tv.setHorizontalHeader(hh)
# Optional 2: get tableview's header, sorting works
hh=tv.horizontalHeader()
tv.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
tv.setShowGrid(True)
hh.setSectionsMovable(True)
hh.setStretchLastSection(False)
hh.setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
tv.setSortingEnabled(True)
return tv
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow,self).__init__()
self.main_frame=MainFrame()
self.setCentralWidget(self.main_frame)
self.setGeometry(100,100,800,600)
self.show()
if __name__=='__main__':
app=QtWidgets.QApplication(sys.argv)
mainwindow=MainWindow()
sys.exit(app.exec_())
我的 PyQt 是 5.9.2,通过 conda 安装
如果您检查创建 xxxHeaderView 的 source code,您会看到以下内容:
...
QHeaderView *vertical = new QHeaderView(Qt::Vertical, q);
vertical->setSectionsClickable(true);
vertical->setHighlightSections(true);
q->setVerticalHeader(vertical);
QHeaderView *horizontal = new QHeaderView(Qt::Horizontal, q);
horizontal->setSectionsClickable(true);
horizontal->setHighlightSections(true);
q->setHorizontalHeader(horizontal);
...
所以缺少的是启用setSectionsClickable()
,您还可以添加setHighlightSections(True)
。
def createTable(self):
...
# Optional 1: use custom headerview, sorting not working
hh =MyHeaderView(tv)
tv.setHorizontalHeader(hh)
# solution
hh.setSectionsClickable(True) # <--- +++
hh.setHighlightSections(True) # <--- +++
# Optional 2: get tableview's header, sorting works
# hh = tv.horizontalHeader()
tv.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
tv.setShowGrid(True)
hh.setSectionsMovable(True)
hh.setStretchLastSection(False)
hh.setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
tv.setSortingEnabled(True)
return tv
我正在尝试创建具有排序功能的 TableView
。如果我设置 TableView
obj 我的自定义 HeaderView
,单击 header 将不会排序,即使我的自定义 HeaderView
re-implements 什么也没有。
如果我改用 TableView
的 header (hh=tv.horizontalHeader()
) 它会排序。我做错了什么?
代码如下:
import sys
import operator
from PyQt5 import QtWidgets
from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant
class TableModel(QAbstractTableModel):
def __init__(self, parent, datain, headerdata):
super(TableModel,self).__init__(parent)
self.arraydata=datain
self.headerdata=headerdata
def rowCount(self,p):
return len(self.arraydata)
def columnCount(self,p):
if len(self.arraydata)>0:
return len(self.arraydata[0])
return 0
def data(self, index, role):
if not index.isValid():
return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
return QVariant(self.arraydata[index.row()][index.column()])
def headerData(self, col, orientation, role):
if orientation==Qt.Horizontal and role==Qt.DisplayRole:
return self.headerdata[col]
return None
def sort(self,col,order):
self.layoutAboutToBeChanged.emit()
self.arraydata=sorted(self.arraydata,key=operator.itemgetter(col))
if order==Qt.DescendingOrder:
self.arraydata.reverse()
self.layoutChanged.emit()
class MyHeaderView(QtWidgets.QHeaderView):
def __init__(self,parent):
super(MyHeaderView,self).__init__(Qt.Horizontal,parent)
class MainFrame(QtWidgets.QWidget):
def __init__(self):
super(MainFrame,self).__init__()
self.initUI()
def initUI(self):
self.doc_table=self.createTable()
dummy_box=QtWidgets.QLineEdit()
hlayout=QtWidgets.QHBoxLayout()
h_split=QtWidgets.QSplitter(Qt.Horizontal)
h_split.addWidget(self.doc_table)
h_split.addWidget(dummy_box)
hlayout.addWidget(h_split)
self.setLayout(hlayout)
self.show()
def createTable(self):
# create some dummy data
self.tabledata=[['aaa' ,' title1', True, 1999],
['bbb' ,' title2', True, 2000],
['ccc' ,' title3', False, 2001]
]
header=['author', 'title', 'read', 'year']
tablemodel=TableModel(self,self.tabledata,header)
tv=QtWidgets.QTableView(self)
tv.setModel(tablemodel)
# Optional 1: use custom headerview, sorting not working
#hh=MyHeaderView(tv)
#tv.setHorizontalHeader(hh)
# Optional 2: get tableview's header, sorting works
hh=tv.horizontalHeader()
tv.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
tv.setShowGrid(True)
hh.setSectionsMovable(True)
hh.setStretchLastSection(False)
hh.setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
tv.setSortingEnabled(True)
return tv
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow,self).__init__()
self.main_frame=MainFrame()
self.setCentralWidget(self.main_frame)
self.setGeometry(100,100,800,600)
self.show()
if __name__=='__main__':
app=QtWidgets.QApplication(sys.argv)
mainwindow=MainWindow()
sys.exit(app.exec_())
我的 PyQt 是 5.9.2,通过 conda 安装
如果您检查创建 xxxHeaderView 的 source code,您会看到以下内容:
...
QHeaderView *vertical = new QHeaderView(Qt::Vertical, q);
vertical->setSectionsClickable(true);
vertical->setHighlightSections(true);
q->setVerticalHeader(vertical);
QHeaderView *horizontal = new QHeaderView(Qt::Horizontal, q);
horizontal->setSectionsClickable(true);
horizontal->setHighlightSections(true);
q->setHorizontalHeader(horizontal);
...
所以缺少的是启用setSectionsClickable()
,您还可以添加setHighlightSections(True)
。
def createTable(self):
...
# Optional 1: use custom headerview, sorting not working
hh =MyHeaderView(tv)
tv.setHorizontalHeader(hh)
# solution
hh.setSectionsClickable(True) # <--- +++
hh.setHighlightSections(True) # <--- +++
# Optional 2: get tableview's header, sorting works
# hh = tv.horizontalHeader()
tv.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
tv.setShowGrid(True)
hh.setSectionsMovable(True)
hh.setStretchLastSection(False)
hh.setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
tv.setSortingEnabled(True)
return tv