PDA

View Full Version : Capture mouse event on QHeaderView



squidge
12th November 2009, 19:02
I wish to capture mouse events on the QHeaderView part of a QTreeview. header()->installEventFilter(this); captures some events but even if the only statement in the function is "return true" (ie, filter the event), the QHeaderView still gets the mouse message.

Any ideas? I don't want to block the events, just analyse them as well.

spirit
12th November 2009, 19:08
show us code.

squidge
12th November 2009, 19:33
class FLView : public QTreeView
{
...
}

FLView::FLView(QWidget *parent) : QTreeView(parent) ,
{
header()->installEventFilter(this);
}

bool FLView::eventFilter(QObject *obj, QEvent *event)
{
return true;
}

spirit
12th November 2009, 19:35
try this


bool FLView::eventFilter(QObject *obj, QEvent *event)
{
return QTreeView::eventFilter(obj, event);
}

squidge
12th November 2009, 20:04
Yes, but events I'm interested in don't get to my event filter. I can prove this by just using "return true" to attempt to block the event.

spirit
12th November 2009, 20:23
I didn't get: do you need to block a header's events or don't block them?

squidge
12th November 2009, 21:13
I wish to analyse all events passed to an object.

To see if my method of doing so worked, I attempted to ignore all the events that get passed to me so they never reach there destination. However, the control still acted as normal, handling all mouse events.

Therefore my event filter failed. Its not much of an event filter if it allows all of them through regardless.

Also, If I change the event filter code so that it pops up a messagebox when it filters an event of type "MouseButtonPress", the message box never shows up.

squidge
12th November 2009, 22:38
Fixed.

QHeaderView doesn't process the events directly, it gets passed from another object. Bottom line is you need to hook into the headers viewport, not the header itself.

JoZCaVaLLo
20th April 2011, 13:00
Hello squidge!!!

1 year and a half later somebody can still fall in this difficulty... it annoyed me during the last 2 days... it was not really obvious to find it out. Unfortunately google doesn't really look inside qtcentre.org

This is the solution that worked for me...



class MouseReleaser : public QObject
{
Q_OBJECT
public:
MouseReleaser(QObject * parent) : QObject(parent){;}
protected:
bool eventFilter(QObject *obj, QEvent *ev)
{
if (ev->type()==QEvent::MouseButtonRelease)
return true;
else
return QObject::eventFilter(obj, ev);
}
};

...

MyTableView::MyTableView(QWidget *parent)
:QTableView(parent)
{
MouseReleaser *mr = new MouseReleaser(this);
horizontalHeader()->viewport()->installEventFilter(mr);
verticalHeader()->viewport()->installEventFilter(mr);
}



Thank you for the great job!

squidge
20th April 2011, 13:23
Hello squidge!!!

1 year and a half later somebody can still fall in this difficulty... it annoyed me during the last 2 days... it was not really obvious to find it out. Unfortunately google doesn't really look inside qtcentre.org
It does if you ask it :), eg: "site:qtcentre.org QHeaderView capture" brings you to this thread as first hit :)

riarioriu3
10th August 2012, 11:54
There is no direct API for this at the moment, so for the time being, you need to reimplement the mousePressEvent() [doc.qt.nokia.com] and mouseReleaseEvent() [doc.qt.nokia.com] for the headerview and check which section is being pressed on, then if it is one you want to allow to be movable, or clickable, you turn it on before calling the base implementation. In the mouseReleaseEvent() you would turn off the movable/clickable properties.

When it comes to setSortIndicatorShown() [doc.qt.nokia.com], then it is expected that the indicator will be shown until the user clicks on another section. So in mousePressEvent() we hide the indicator if the section clicked is not the one that should show the indicator. Alternatively the sort indicator can simply stay on the section clicked previously.

The example below demonstrates how this can be done.


#include <QtGui>
class HeaderView : public QHeaderView
{
Q_OBJECT
public:
HeaderView(QWidget *parent = 0) : QHeaderView(Qt::Horizontal, parent)
{
connect(this, SIGNAL(sectionClicked(int)), this, SLOT(clickedSection(int)));
}
void mousePressEvent(QMouseEvent *event)
{
if(visualIndexAt(event->pos().x()) == 1) {
setClickable(true);
setSortIndicator(1, sortIndicatorOrder());
setSortIndicatorShown(true);
} else {
setSortIndicatorShown(false);
resizeSection(1, sectionSize(1) - 1);
resizeSection(1, sectionSize(1) + 1);
}
QHeaderView::mousePressEvent(event);
}
void mouseReleaseEvent(QMouseEvent *event)
{
QHeaderView::mouseReleaseEvent(event);
setClickable(false);
}
public slots:
void clickedSection(int s)
{
qDebug() << "Section " << s << " clicked";
}
};

class TreeWidget : public QTreeWidget
{
public:
TreeWidget()
{
setColumnCount(3);
QStringList list;
list << "a" << "b" << "c";
QStringList list2;
list2 << "d" << "e" << "f";
QTreeWidgetItem *item1 = new QTreeWidgetItem(this, list);
QTreeWidgetItem *item2 = new QTreeWidgetItem(this, list2);
addTopLevelItem(item1);
addTopLevelItem(item2);
setHeader(new HeaderView(this));
}
};

#include "main.moc"

int main(int argc, char** argv)
{
QApplication app(argc, argv);
TreeWidget tree;
tree.show();
return app.exec();
}