pyqt qt4 QTableView como desativar a classificação para determinadas colunas?

Então, eu tenho um QTableView e só quero permitir a classificação de colunas na coluna 1, mas não na coluna2.

Naturalmente eu tenteiinstallEventFilter emQHeaderView ouQTableView, masMouseButtonPress evento não está sendo passado, a menos que vocêinstallEventFilter emQApplication

Agora se quandoeventFilter é chamado, o alvoobject é sempre o widget de nível superior, emboraevent.pos() é na verdade relativo ao cabeçalho ou tablecell, dependendo de onde você clica.

Então não podemos usarQHeaderView.rect().contains(event.pos()) para descobrir se o usuário clica no cabeçalho porque você é falso positivo ao clicar na borda superior da primeira célula da tabela.

No entanto, você ainda pode calcular isso usando globalPos, mas a lógica do eventFilter precisa mudar quando você altera o layout ou adiciona mais widgets acima da visualização da tabela.

Eu acredito que é um bug que event.pos () retorna a posição relativa, mesmo aobject O argumento sempre se refere ao mesmo widget de nível superior.

Uma API mais lógica seria a existência de um método event.target () para retornar o destino onde calcula a posição relativa.

Mas não vejo um método target () ou uma maneira de encontrar o alvo nesse filtro de eventos.

Talvez esteja faltando alguma coisa?

# -*- coding: utf-8 -*-
# pyqt windows 4.10.3
# python 2.7.5 32 bits
from PyQt4.QtCore import *
from PyQt4.QtGui import *

app = None
tableHeader = None

class MyModel(QAbstractTableModel):
    def rowCount(self, QModelIndex_parent=None, *args, **kwargs):
        return 2

    def columnCount(self, QModelIndex_parent=None, *args, **kwargs):
        return 2

    def data(self, modelIndex, role=None):
        if modelIndex.isValid():
            row = modelIndex.row()
            col = modelIndex.column()
            if role == Qt.DisplayRole:
                return "%02d,%02d" % (row, col)

    def flags(self, index):
        if index.isValid():
            return Qt.ItemIsEnabled

    def headerData(self, section, Qt_Orientation, role=None):
        if role == Qt.DisplayRole and Qt_Orientation == Qt.Horizontal:
            return "Column " + str(section+1)

class MyEventFilter(QObject):
    def eventFilter(self, object, event):
        if event.type() == QEvent.MouseButtonPress:
            # object is always app/top level widget
            print 'MouseButtonPress target :' + repr(object)
            # even though event.pos() gives pos relative to the header when you click on header,
            # and pos relative to table cells when you click on table cell
            print repr(event.pos())
            # however we can get the mouse's global position
            print repr(event.globalPos())
            # given the top level widget's geometry
            print repr(app.activeWindow().geometry())
            # and the table header's left, top and height
            print repr(tableHeader.rect())
            # we can find out whether mouse click is targeted at the header
            print repr(event.globalPos().y() - app.activeWindow().geometry().y())
            # BUT WHAT IF THE LAYOUT CHANGE OR WE ADD MORE WIDGETS ABOVE THE TABLEVIEW?
            # WE HAVE TO ADJUST THE CALCULATION ABOVE!
        return False


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    w = QMainWindow()
    t = QTableView()
    tableHeader = t.horizontalHeader()
    t.setModel(MyModel())
    w.setCentralWidget(t)
    ef = MyEventFilter()
    # installing in QMainWindow or QTableView won't catch MouseButtonPress
    # https://qt-project.org/forums/viewthread/9347
    #w.installEventFilter(ef)
    #t.installEventFilter(ef)
    app.installEventFilter(ef)
    w.show()
    sys.exit(app.exec_())

questionAnswers(1)

yourAnswerToTheQuestion