So, I have a QTableView, and I want to enable sorting of columns in column 1, but not in column2.
Naturally, I tried installEventFilteron QHeaderViewor QTableView, but the event is MouseButtonPressnot transmitted if you are not installEventFilteronQApplication
Now, if called eventFilter, the target is objectalways a top-level widget, although it event.pos()actually refers to the header or table, depending on where you click.
Therefore, we can’t use QHeaderView.rect().contains(event.pos())it to find out if the user clicks the header because you get a false positive when you click on the top edge of the very first cell of the table.
However, you can calculate this using globalPos, but then your eventFilter logic should change when you change the layout or add more widgets above the table view.
I believe that this is an error that event.pos () returns relative pos, even the argument objectalways refers to the same top-level view.
A more logical API would be that there is an event.target () method to return the target, where it computes the relative pos.
But I do not see the target () method or the way to find the target in this event filter.
Maybe something is missing for me?
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:
print 'MouseButtonPress target :' + repr(object)
print repr(event.pos())
print repr(event.globalPos())
print repr(app.activeWindow().geometry())
print repr(tableHeader.rect())
print repr(event.globalPos().y() - app.activeWindow().geometry().y())
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()
app.installEventFilter(ef)
w.show()
sys.exit(app.exec_())