PDA

View Full Version : Change cursor when pointer moving through QTableView's header



Seishin
16th July 2012, 21:50
Hi everyone,

I'm using QTableView in a QWidget to show data from database. Users can click any cell in column 3 to play the music in that cell. Therefore I change the cursor to pointing hand when pointer entered the column and change it back to arrow when left.

Here is some related code:

m_view->setMouseTracking(true);
connect(m_view, SIGNAL(clicked(QModelIndex)), this, SLOT(playAudio(QModelIndex)));
connect(m_view, SIGNAL(entered(QModelIndex)), this, SLOT(changeCursor(QModelIndex)));
connect(m_view, SIGNAL(viewportEntered()), this, SLOT(changeCursor()));

void Tab::changeCursor(QModelIndex index){
if(index.column() == 3)
setCursor(Qt::PointingHandCursor);
else
setCursor(Qt::ArrowCursor);
}
void Tab::changeCursor(){
setCursor(Qt::ArrowCursor);
}

Everything works well except when I move pointer from column 3 to its header and leave the QTableView, the viewportEntered signal is not emitted and the cursor is keeping pointing hand but not arrow.

Could anyone help me with is issue? I'm using Qt 4.7.
Thanks in advance.

wysota
17th July 2012, 01:38
Remove all your code and use this:

m_view->horizontalHeader()->setCursor(Qt::PointingHandCursor);

Edit: Ah.. sorry, I didn't read your post carefully enough. Anyway, you can intercept QWidget::leaveEvent() to detect when the mouse pointer is leaving the widget. You can reset the cursor then.

And by the way, use QApplication::setOverrideCursor() and QApplication::restoreOverrideCursor() instead of setCursor().

Another approach would be to enable hover events for your view and intercept that. They you'd have total control over what happens where regarding the pointer position.

Seishin
17th July 2012, 16:17
Thanks a lot for replying.

The leaveEvent works well but after trying different signals and events, I found actually I can just set the cursor for QTableView instead of its parent.
(i.e. use
m_view->setCursor(Qt::ArrowCursor); //for viewportEntered signal instead of
setCursor(Qt::ArrowCursor);)
The only problem now is when I move pointer from column 3 to horizontal header BUT NOT leave the QTableView, the pointer is still the pointing hand while it stay in the header area.
I think this is because neither QTableView::entered(QModelIndex) singal nor QWidget::leaveEvent can detect the pointer moving from cells to headers?
It should be much easier if I can get the column 3 as a separated object or a list of cell objects. Is their a way to get it in QTableView?

And what's the reason to use QApplication::setOverrideCursor() and QApplication::restoreOverrideCursor() instead of setCursor()?
Thanks again.

wysota
17th July 2012, 17:00
And what's the reason to use QApplication::setOverrideCursor() and QApplication::restoreOverrideCursor() instead of setCursor()?
If you use setCursor() then that's an absolute way of telling the desktop what cursor to show. If you use an override cursor, there is an internal stack kept that lets you revert to the last set cursor instead of having to set a particular shape hoping that nobody changed the cursor in the meantime.

Seishin
17th July 2012, 17:53
I see.
Do you know is there a way to set events for just one column of cells instead of dealing with the whole tableView? The header is really annoying. Thanks.

wysota
17th July 2012, 18:51
No, the event system has no notion of columns.

Seishin
17th July 2012, 19:11
Sorry I think I used the wrong reply button.
Just to repeat what I typed before,
I see event cannot help me in this case, but is there a way to restore the cursor when the pointer moves to the header area?
Thanks.

wysota
17th July 2012, 19:34
If the pointer moves on the header, the header will get an enterEvent. If you intercept such event, you can react on it.

Seishin
17th July 2012, 20:20
I think enterEvent should work, but before that I've tried the signal entered like


m_view->horizontalHeader()->setMouseTracking(true);
connect(m_view->horizontalHeader(), SIGNAL(entered(QModelIndex)), this, SLOT(changeCursor(QModelIndex)));

And it does not work at all.
I saw the link http://www.qtcentre.org/threads/44057-QHeaderView-in-QTableView-not-sending-quot-entered-quot-or-quot-enteredViewport-quot-signals
which says it's a bug.

Anyway thanks a lot for your help.