-
Hover and Highlight QTable and QTree Items
I was curious, is Qt Stylesheets the only way to get the hover: property?
I wanted to somehow highlight like a whole row in a TableWidget when you hover your mouse over a row. I also wanted to highlight the QTreeWidgetItem when someone hovers their mouse over it, so the background color changes on that item. I figured it out using QPalette for Highlight by clicking, but not my mouseover...
Any ideas? Thanks.
-
Re: Hover and Highlight QTable and QTree Items
U can use itemAt() function of QTableWidget to get the table widget item under the mouse... then set its background brush....
same u can do with qtreewidgetitems i guess...
and yah... capture the mouse movements on mouseMoveEvent() ....
you have to set setMouseTracking(true) to receive the mouse move events....
hope this will help you.. :)
-
Re: Hover and Highlight QTable and QTree Items
It kind of helps, I like your itemAt idea, I could do like
itemAt(QCursor::pos()); but then I would need to put this in a loop and multithread right? Where else could I put this? How could I code this so it works?
I think perhaps the best way is to use mouseMoveEvent() and subclass TableWidget and TreeWidget.
-
Re: Hover and Highlight QTable and QTree Items
So subclassing is only way I take it? I couldn't figure out the itemAt thing.
-
Re: Hover and Highlight QTable and QTree Items
Enable mouse tracking on the viewport and catch mouse move events either by subclassing and reimplementing the event handler or alternatively with an event filter. The latter approach does not require subclassing.
-
Re: Hover and Highlight QTable and QTree Items
Where can I learn about "event filters". The subclassing seems time consuming :O.
-
Re: Hover and Highlight QTable and QTree Items
-
Re: Hover and Highlight QTable and QTree Items
Ok I got the code, I'm at the part where I do
event->type() == QEvent::MouseMove){
so in here, do I just somehow get an instance of my original class of QTreeWidget and just do:
QTreeWidgetItem* bla = Widget->itemAt(QCursor::pos());
bla->setBackground(0, QBrush(QColor(255,0,0)));
Is that how I am suppose to do it? Or wait do I cast the QObject as a QTreeWidget perhaps?
-
Re: Hover and Highlight QTable and QTree Items
The position passed within the event might be a bit more reliable:
Code:
// QTreeWidgetItem* prev;
if (event
->type
() == QEvent::MouseMove) {
QMouseEvent* mouseEvent
= static_cast<QMouseEvent
*>
(event
);
if (current && current != prev)
{
if (prev)
prev->setBackground(0, palette().base()); // reset previous
current->setBackground(0, Qt::red); // highlight current
prev = current;
}
}
-
Re: Hover and Highlight QTable and QTree Items
I think that's exactly what I was looking for thank you. I think I was close.
-
Re: Hover and Highlight QTable and QTree Items
I made a Filter class,
I used Q_OBJECT.
I used the obj and event as you said.
I even fixed your code, but it seems it works but very slowly. Like I have to whirl my mouse all over USerList and outside of UserList in order to get it to work properly. I mean it works, it even deletes old highlights, but it doesn't highlight the new spot when i move my mouse.
-
Re: Hover and Highlight QTable and QTree Items
Have you enabled mouse tracking on the viewport and also installed the event filter on the viewport?
Code:
treeWidget->viewport()->setMouseTracking(true);
treeWidget->viewport()->installEventFilter(this);
Edit: is the tree massive, containing huge amount of items in a complex hierarchy? :)
-
Re: Hover and Highlight QTable and QTree Items
Just stumbled upon this thread, so I decided to include my own 5 cents...
There is another possibility - you can use a custom delegate and reimplement editorEvent() and act upon one (or more) of QEvent::HoverEnter, QEvent::HoverLeave or QEvent::HoverMove. If I remember correctly you have to enable mouse tracking for these events to be delivered, although I'm not sure of that.
-
Re: Hover and Highlight QTable and QTree Items
wysota, I don't think I wanna delve into making something too complex.
jpn, I was doing:
TreeWidg->setMouseTracking(true);
TreeWidg->installEventFilter(mhf); // mhf = new MouseHoverFilter;
When I changed it to:
TreeWidg->viewport()->setMouseTracking(true);
TreeWidg->viewport()->installEventFilter(mhf); // mhf = new MouseHoverFilter;
Now If I hover over treewidget it crashes the program.
-
1 Attachment(s)
Re: Hover and Highlight QTable and QTree Items
Quote:
Originally Posted by
VireX
Now If I hover over treewidget it crashes the program.
Improper cast? Insufficient checks? ...see the attached example.
-
Re: Hover and Highlight QTable and QTree Items
No I did exactly what you posted, except that I didn't subclass my treeWidget.
I made a class called MouseHoverFilter which has the event filter. Then I installed the event filter and setmousetracking on the TreeWidget. It only crashes if i add viewport().
-
Re: Hover and Highlight QTable and QTree Items
Heres the exact code I used, just try it:
In my main file:
MouseHoverFilter* mhf;
MyList->setMouseTracking(true);
mhf = new MouseHoverFilter;
MyList->installEventFilter(mhf);
Filters.h :
class MouseHoverFilter : public QObject {
Q_OBJECT
public:
MouseHoverFilter(QObject* parent);
QTreeWidgetItem* prev;
protected:
bool eventFilter(QObject *obj, QEvent *event);
};
MouseHoverFilter::MouseHoverFilter(QObject* parent = 0) : QObject(parent) {
prev = 0;
}
bool MouseHoverFilter::eventFilter(QObject *obj, QEvent *event){
if(event->type() == QEvent::MouseMove){
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
QTreeWidget* qtw = static_cast<QTreeWidget*>(obj);
QTreeWidgetItem* current = qtw->itemAt(mouseEvent->pos());
if(current && current != prev && current->childCount() == 0){
if(prev)prev->setBackground(0, qtw->palette().base());
if(prev)prev->setBackground(1, qtw->palette().base());
if(prev)prev->setBackground(2, qtw->palette().base());
current->setBackground(0, QColor(193, 235, 255));
current->setBackground(1, QColor(193, 235, 255));
current->setBackground(2, QColor(193, 235, 255));
prev = current;
}
return true;
} else {
QObject::eventFilter(obj, event);
}
return false;
}
#include "Filters.moc"
-
1 Attachment(s)
Re: Hover and Highlight QTable and QTree Items
Quote:
Originally Posted by
VireX
wysota, I don't think I wanna delve into making something too complex.
Doesn't seem very complex...
-
Re: Hover and Highlight QTable and QTree Items
This is the improper cast:
The receiver object is the viewport widget, not the tree widget.
-
Re: Hover and Highlight QTable and QTree Items
I've tried setting a QTreeWidget inside the Mouse class and delivering the original QTreeWidget to the Mouse Class constructor, but that made no difference, so that isn't the problem, it works this way too.
-
1 Attachment(s)
Re: Hover and Highlight QTable and QTree Items
-
Re: Hover and Highlight QTable and QTree Items
Quote:
Originally Posted by
VireX
Here's my Filters.h
Works for me. Does this still crash for you? Could you paste backtrace from debugger?
-
Re: Hover and Highlight QTable and QTree Items
No it doesn't crash after I removed your code of "bla->viewport()->setMouseTracking" back to the correct form: "bla->setMouseTracking()".
Thats not the problem, it's slow, I could take a video, and what you will see is, me spinning and making my mouse go crazy on the treewidget list, and after several seconds it finally highlights one item, and when my mouse is not even on the list, it's still highlighted. Like as if, the treewidget picks randomly when it wants to highlight something. Then I spin my mouse all over the screen again and again, then finally some other random TreeItem highlights itself.
-
Re: Hover and Highlight QTable and QTree Items
Why don't you try my solution? :)
-
Re: Hover and Highlight QTable and QTree Items
Quote:
Originally Posted by
VireX
No it doesn't crash after I removed your code of "bla->viewport()->setMouseTracking" back to the correct form: "bla->setMouseTracking()".
I'm sorry to say but it's not correct at all. It's the viewport widget which receives mouse move events.
Quote:
Thats not the problem, it's slow, I could take a video, and what you will see is, me spinning and making my mouse go crazy on the treewidget list, and after several seconds it finally highlights one item, and when my mouse is not even on the list, it's still highlighted. Like as if, the treewidget picks randomly when it wants to highlight something. Then I spin my mouse all over the screen again and again, then finally some other random TreeItem highlights itself.
That's most likely because you're not receiving those mouse move events but some other event causes an update every now and then, depending on if you enter and leave the widget or change the focus or something like that. Is the compilable example in post #15 that "slow"? Or did you even bother checking out out?
-
Re: Hover and Highlight QTable and QTree Items
1. Well doing bla->viewport()-> causes crash, that's 100% for sure, therefore it is not correct.
2. Maybe so, but of course why would I bother checking it out when I have the same code you showed me earlier in a different style?
@wysota: Your solution works great. Still trying to find out what went wrong with jpn's solution.
-
Re: Hover and Highlight QTable and QTree Items
Quote:
Originally Posted by
VireX
1. Well doing bla->viewport()-> causes crash, that's 100% for sure, therefore it is not correct.
Again, the example works for fine. You must have a quirk of some kind in your code.
- Use a debugger
- examine the backtrace
- find a reason why does it crash
Quote:
2. Maybe so, but of course why would I bother checking it out when I have the same code you showed me earlier in a different style?
Because it would convince you that the approach works after all.
-
Re: Hover and Highlight QTable and QTree Items
Both your solutions work fine, in their isolated situations.
I just don't understand why it doesn't work with my MouseFilter class which is almost EXACTLY like jpn's program.
Why would Qt put setMouseTracking and installEventFilter in the QAbstracts if it was suppose to be used inside a class with viewport().
When I do TreeWidget->viewport()->setMouseTracking(true); it crashes, that's the SOLE reason. I think jpn doesn't realize i'm not talking about his program.
-
Re: Hover and Highlight QTable and QTree Items
"Almost" sometimes makes a big difference. I have to agree with JP - you have to install the filter on the viewport and not the list itself. Event filters don't propagate - if the list installs a filter on its viewport and you install a fillter on the list, you won't get events for the viewport. You're having obvious errors in your code which JP already pointed out. You'll be receiving mouse move events only for that parts of the view which are not occupied by other widgets (viewport and scrollbars) and I doubt that's what you want.
-
Re: Hover and Highlight QTable and QTree Items
Maybe so.
One question why doesnt using QPalette::Background or Window make the background become red? I tried different color roles in your code.
Also your code highlights each item in each column. Is there a way to highlight background of the whole row? (I have selection mode in selectRow).
-
Re: Hover and Highlight QTable and QTree Items
No, you have to do it through editorEvent as I suggested earlier. But it's simpler to adjust the selection using an event filter. Here is a combined approach:
Code:
if(event
->type
()==QEvent::MouseMove){ // view is the parent
if(view){
return true;
}
}
}
// view is the parent
if(view
&& e
->type
()==QEvent::Leave){ view->selectionModel()->clearSelection();
}
}
-
Re: Hover and Highlight QTable and QTree Items
I added that to delegate class but it made no difference.
-
Re: Hover and Highlight QTable and QTree Items
Did you remember about enabling mouse tracking?
-
Re: Hover and Highlight QTable and QTree Items
Here's my code, and mouse tracking does not change anything (I put mousetracking on list List->setMouseTracking(true); I even tried List->viewport()->setMouseTracking(true); nothing works):
Code:
public:
protected:
if(option.
state & QStyle::State_MouseOver){ opt.
palette.
setColor(QPalette::Text, Qt
::red);
//opt.font.setBold(true);
}
}
if(event
->type
()==QEvent::MouseMove){ // view is the parent
if(view){
return true;
}
}
}
// view is the parent
if(view
&& e
->type
()==QEvent::Leave){ view->selectionModel()->clearSelection();
}
}
};
#include "Filters.moc"
-
Re: Hover and Highlight QTable and QTree Items
"view is the parent" - is it true for you? Did you set the view as the parent of the delegate? Because if you didn't then it doesn't have a chance to work :) And remember to install the event filter on the viewport of the view, otherwise selection won't be cleared when you leave the view.
-
Re: Hover and Highlight QTable and QTree Items
Why would I install the eventfilter, we dont use that for this. We dont use installEventFilter for this function. It would be easier if you showed me the exact code you used in like your main.cpp.
I did:
UserList->viewport()->setMouseTracking(true);
UserList->setItemDelegate(new Delegate(UserList->viewport()));
UserList->viewport()->setAttribute(Qt::WA_Hover, true);
Which is all you told me to do.
-
Re: Hover and Highlight QTable and QTree Items
I think wysota meant more or less something like this:
Code:
Delegate* delegate = new Delegate(UserList); // view as parent, not viewport
UserList->viewport()->installEventFilter(delegate); // install event filter on the viewport
UserList->setItemDelegate(delegate);
-
Re: Hover and Highlight QTable and QTree Items
Well all that did is take away the red bold hover on mouse over. Didn't fix the problem.
-
1 Attachment(s)
Re: Hover and Highlight QTable and QTree Items
Quote:
Originally Posted by
VireX
Why would I install the eventfilter, we dont use that for this. We dont use installEventFilter for this function.
So why do you paste me the code that uses it? :eek:
Quote:
It would be easier if you showed me the exact code you used in like your main.cpp.
My main.cpp doesn't exist for a few days anymore, so this is not an option.
Quote:
I did:
UserList->viewport()->setMouseTracking(true);
UserList->setItemDelegate(new Delegate(UserList->viewport()));
UserList->viewport()->setAttribute(Qt::WA_Hover, true);
Which is all you told me to do.
No, I didn't. Hover attribute shouldn't be necessary and the viewport shouldn't be the parent of the delegate. Please verify that the if block in the editorEvent gets entered at all.
Here, I implemented the thing again.
-
Re: Hover and Highlight QTable and QTree Items
Nice it worked finally, I guess since I was using your old stuff and new stuff together it was conflicting and not showing up. And perhaps wrong parents etc.
Anyway I'm still wondering, how come selectionMode being SelectRow, yet the hover only highlights EACH column. Is it possible to code a way to highlight the WHOLE ROW, instead of a single column of the row?
-
Re: Hover and Highlight QTable and QTree Items
If you change the code that does the selection then yes. I only selected a single index.
-
Re: Hover and Highlight QTable and QTree Items
/*Hmm I almost have it working but I have to use
view->selectionModel()->select(index.sibling(index.row(), 0), QItemSelectionModel::Select);
view->selectionModel()->select(index.sibling(index.row(), 1), QItemSelectionModel::Select);
view->selectionModel()->select(index.sibling(index.row(), 2), QItemSelectionModel::Select);*/
Nvm, I think I got it to work now. Thanks for your help :D :D.