如何重新排列QTableView的列Ord

2024-10-01 11:23:23 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的代码创建了一个由模型/代理框架驱动的QTableView。在

source-model中声明的self.headerNameslist变量存储标头列的名称。同一个source modelcolumnCount()方法使用此列表中的名称数返回视图中的列数:

def columnCount(self, parent=QModelIndex()):
    return len(self.headerNames)

Proxy模型的headerData()通过source model访问这个self.headerNames变量:

^{pr2}$

if role==Qt.DisplayRole上,代理检索列的名称并将其返回给QTableView:

return QVariant( sourceModel.headerNames[column] )

在标题列右键单击上有一个右键单击菜单。 那部分工作正常。但由于我找不到任何其他人如何做的例子,我不得不自己设计它的工作方式。如果您能改进一下,我将不胜感激。在

接下来我要实现的是以任意顺序重新排列列的能力。但我不知道从哪里开始。在

enter image description here

请忽略QTableView中显示的项目名称。 我想让代码尽可能简单,只关注头/列主题。在

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys

class Model(QAbstractTableModel):
    def __init__(self, parent=None, *args):
        QAbstractTableModel.__init__(self, parent, *args)
        self.items = ['Item_A_001','Item_A_002','Item_B_001','Item_B_002']
        self.headerNames=['Column 0','Column 1','Column 2','Column 3','Column 4','Column 5','Column 6','Column 7']

    def rowCount(self, parent=QModelIndex()):
        return len(self.items)       
    def columnCount(self, parent=QModelIndex()):
        return len(self.headerNames)

    def data(self, index, role):
        if not index.isValid(): return QVariant()
        elif role != Qt.DisplayRole:
            return QVariant()

        row=index.row()
        if row<len(self.items):
            return QVariant(self.items[row])
        else:
            return QVariant()

class Proxy(QSortFilterProxyModel):
    def __init__(self):
        super(Proxy, self).__init__()

    def filterAcceptsRow(self, row, parent):
        return True

    def headerData(self, column, orientation, role=Qt.DisplayRole):
        sourceModel=self.sourceModel()

        if role==Qt.TextAlignmentRole:
            if orientation==Qt.Horizontal:
                return QVariant(int(Qt.AlignHCenter|Qt.AlignVCenter))
            return QVariant(int(Qt.AlignHCenter|Qt.AlignVCenter))

        if role==Qt.DisplayRole:
            if orientation==Qt.Horizontal:
                return QVariant( sourceModel.headerNames[column] )
            else:
                return QVariant()
        else:
            return QVariant()

        return QVariant(int(column+1))


class MyWindow(QWidget):
    def __init__(self, *args):
        QWidget.__init__(self, *args)

        tableModel=Model(self)               

        proxyModel=Proxy()
        proxyModel.setSourceModel(tableModel)

        self.tableview=QTableView(self) 
        self.tableview.setModel(proxyModel)
        self.tableview.horizontalHeader().setStretchLastSection(True)
        self.tableview.setSelectionMode(QAbstractItemView.MultiSelection)

        header=self.tableview.horizontalHeader()
        header.setContextMenuPolicy(Qt.CustomContextMenu)
        header.connect(header, SIGNAL("customContextMenuRequested(QPoint)" ), self.headerRightClicked)

        self.resHeaderMenu=QMenu(self)

        for column in range(proxyModel.columnCount()):
            columnName=proxyModel.headerData(column, Qt.Horizontal).toPyObject()
            actn=QAction('%s'%columnName, self.resHeaderMenu, checkable=True)
            actn.setChecked(True)
            actn.triggered.connect(self.resHeaderMenuTriggered)
            self.resHeaderMenu.addAction(actn)

        layout = QVBoxLayout(self)
        layout.addWidget(self.tableview)
        self.setLayout(layout)

    def headerRightClicked(self, QPos):
        parentPosition=self.tableview.mapToGlobal(QPoint(0, 0))        
        menuPosition=parentPosition + QPos
        self.resHeaderMenu.move(menuPosition)
        self.resHeaderMenu.show()        

    def resHeaderMenuTriggered(self, arg):
        print 'resHeaderMenuTriggered', arg
        for i, actn in enumerate(self.resHeaderMenu.actions()):
            if not actn.isChecked():
                self.tableview.setColumnHidden(i, True) 

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

Tags: selfreturnifinitdefcolumnqtrole
1条回答
网友
1楼 · 发布于 2024-10-01 11:23:23

如果您真的想自己重新排列这些列:

您可以通过horizontalHeadermoveSectionswapSections方法移动或交换节。在

headerView.moveSection(x, y)

将移动列x,使其随后成为列y,而

^{pr2}$

很明显,会交换两列的位置。在

相关问题 更多 >