QToolBox change cursor on hover
-
After googling around I decided to ask the experts about my issue.
I`m trying to change the cursor when you hover the "pages" of the toolbox (showing a pointing hand for example) because if I set the cursor "globally" in QT Designer it will show the same cursor for everything between the "pages".
From what I understand this is (best) achieved using eventFilter() so I installed an application-wide event filter:
bool eventFilter(QObject* obj, QEvent* e) { if (e->type() == QEvent::HoverEnter) { } else if (e->type() == QEvent::Enter) { } else if (e->type() == QEvent::Leave) { } return QMainWindow::eventFilter(obj, e); }
Unfortunately I am stuck because I don't know how to check for the toolbox page object.
I have tried this foolish way (without luck):
if (obj->parent() == ui.page) { setCursor(Qt::WaitCursor); }
Any help is much appreciated :)
-
Hi,
If you only set the filter on the widgets that are the items of your QToolBox, you should not need to check the object itself since you know which widget it is.
Or do you have an issue when your cursor moves on top of other widgets within your "page" ?
-
Hi,
If you only set the filter on the widgets that are the items of your QToolBox, you should not need to check the object itself since you know which widget it is.
Or do you have an issue when your cursor moves on top of other widgets within your "page" ?
@SGaist said in QToolBox change cursor on hover:
Hi,
If you only set the filter on the widgets that are the items of your QToolBox, you should not need to check the object itself since you know which widget it is.
Or do you have an issue when your cursor moves on top of other widgets within your "page" ?
Thank you for your reply. I have set the filter on the "centralWidget". I'm not sure if it's the right place, I'm quite new to QT.
ui.centralWidget->installEventFilter(this);
All I want to achieve is change the cursor when you hover a page in the toolbox.
-
You should rather install the filter on each of the page directly, it would be simpler to manage.
-
You should rather install the filter on each of the page directly, it would be simpler to manage.
-
I suppose you have created the whole QToolBox in Designer, correct ?
If so, in the constructor use the QToolBox::widget method to get each of your page and install the filter on them.
-
I suppose you have created the whole QToolBox in Designer, correct ?
If so, in the constructor use the QToolBox::widget method to get each of your page and install the filter on them.
@SGaist said in QToolBox change cursor on hover:
I suppose you have created the whole QToolBox in Designer, correct ?
If so, in the constructor use the QToolBox::widget method to get each of your page and install the filter on them.
Thank you, this suggestion is quite helpful. I learned a lot now on how these filters work. However, after trying this and other methods found none of them work accordinly (at least to my expectation).
What happens is that the QEvent::HoverEnter/Enter are called when your mouse is inside the "page" area, no on the "page" item/name itself.
Maybe I explained myself wrong on what I want to achieve, so I will try again.
For example:
- File
button 1
button 2 - Settings
button 1
button 2 - Etc
button 1
button 2
There is some CSS added to the toolbox which will change colour and background when you hover over the items (pages, call them whatever) which is File, Settings, Etc.
I want to change the cursor as well when you hover over these items/pages. Unfortunately at the moment it will change the cursor over the item/page area and not for the item/page name itself (for example instead of changing the cursor on File, it will change the cursor for everything inside it).
- File
-
@SGaist said in QToolBox change cursor on hover:
I suppose you have created the whole QToolBox in Designer, correct ?
If so, in the constructor use the QToolBox::widget method to get each of your page and install the filter on them.
Thank you, this suggestion is quite helpful. I learned a lot now on how these filters work. However, after trying this and other methods found none of them work accordinly (at least to my expectation).
What happens is that the QEvent::HoverEnter/Enter are called when your mouse is inside the "page" area, no on the "page" item/name itself.
Maybe I explained myself wrong on what I want to achieve, so I will try again.
For example:
- File
button 1
button 2 - Settings
button 1
button 2 - Etc
button 1
button 2
There is some CSS added to the toolbox which will change colour and background when you hover over the items (pages, call them whatever) which is File, Settings, Etc.
I want to change the cursor as well when you hover over these items/pages. Unfortunately at the moment it will change the cursor over the item/page area and not for the item/page name itself (for example instead of changing the cursor on File, it will change the cursor for everything inside it).
- File
-
-
@mrjj said in QToolBox change cursor on hover:
Hi
Sounds like you should also put a filter on the actual toolbox then?Sorry, but I don't know how to do this. I`m just learning the QT framework, and this is the reason I came here asking.
well just like before but instead of the pointer you get from QToolBox::widget
then just use
ui->toolbox instead. (if toolbox is made in the designer )If it still dont work over the title, we need to find out which object that is then :)
-
well just like before but instead of the pointer you get from QToolBox::widget
then just use
ui->toolbox instead. (if toolbox is made in the designer )If it still dont work over the title, we need to find out which object that is then :)
@mrjj said in QToolBox change cursor on hover:
well just like before but instead of the pointer you get from QToolBox::widget
then just use
ui->toolbox instead. (if toolbox is made in the designer )If it still dont work over the title, we need to find out which object that is then :)
Thanks, I have already tried this. I even tried this method: https://stackoverflow.com/questions/411823/how-do-i-implement-qhoverevent-in-qt#answer-26392025
No success...
-
@mrjj said in QToolBox change cursor on hover:
well just like before but instead of the pointer you get from QToolBox::widget
then just use
ui->toolbox instead. (if toolbox is made in the designer )If it still dont work over the title, we need to find out which object that is then :)
Thanks, I have already tried this. I even tried this method: https://stackoverflow.com/questions/411823/how-do-i-implement-qhoverevent-in-qt#answer-26392025
No success...
Well, the main issue with such hover is that events are delivered to the widget under the mouse.
So we must put the filter on the right widget to be able to catch it.if we do
ui->toolBox->dumpObjectTree();
we get how its made up
QToolBox::toolBox
QVBoxLayout::
QToolBoxButton::qt_toolbox_toolboxbutton
QScrollArea::
QWidget::qt_scrollarea_viewport
QWidget::page
QWidget::qt_scrollarea_hcontainer
QScrollBar::
QBoxLayout::
QWidget::qt_scrollarea_vcontainer
QScrollBar::
QBoxLayout::
QToolBoxButton::qt_toolbox_toolboxbutton
QScrollArea::
QWidget::qt_scrollarea_viewport
QWidget::page_2
QWidget::qt_scrollarea_hcontainer
QScrollBar::
QBoxLayout::
QWidget::qt_scrollarea_vcontainer
QScrollBar::
QBoxLayout::
**so it seems the title is the QToolBoxButton called qt_toolbox_toolboxbutton
so we can do
// find all childred with the name auto list = ui->toolBox->findChildren<QWidget*>("qt_toolbox_toolboxbutton"); for (QWidget *title : list) { title->hide(); // this was just to test :) Remove you should install filter here }
-
Well, the main issue with such hover is that events are delivered to the widget under the mouse.
So we must put the filter on the right widget to be able to catch it.if we do
ui->toolBox->dumpObjectTree();
we get how its made up
QToolBox::toolBox
QVBoxLayout::
QToolBoxButton::qt_toolbox_toolboxbutton
QScrollArea::
QWidget::qt_scrollarea_viewport
QWidget::page
QWidget::qt_scrollarea_hcontainer
QScrollBar::
QBoxLayout::
QWidget::qt_scrollarea_vcontainer
QScrollBar::
QBoxLayout::
QToolBoxButton::qt_toolbox_toolboxbutton
QScrollArea::
QWidget::qt_scrollarea_viewport
QWidget::page_2
QWidget::qt_scrollarea_hcontainer
QScrollBar::
QBoxLayout::
QWidget::qt_scrollarea_vcontainer
QScrollBar::
QBoxLayout::
**so it seems the title is the QToolBoxButton called qt_toolbox_toolboxbutton
so we can do
// find all childred with the name auto list = ui->toolBox->findChildren<QWidget*>("qt_toolbox_toolboxbutton"); for (QWidget *title : list) { title->hide(); // this was just to test :) Remove you should install filter here }
@mrjj said in QToolBox change cursor on hover:
Well, the main issue with such hover is that events are delivered to the widget under the mouse.
So we must put the filter on the right widget to be able to catch it.if we do
ui->toolBox->dumpObjectTree();
we get how its made up
QToolBox::toolBox
QVBoxLayout::
QToolBoxButton::qt_toolbox_toolboxbutton
QScrollArea::
QWidget::qt_scrollarea_viewport
QWidget::page
QWidget::qt_scrollarea_hcontainer
QScrollBar::
QBoxLayout::
QWidget::qt_scrollarea_vcontainer
QScrollBar::
QBoxLayout::
QToolBoxButton::qt_toolbox_toolboxbutton
QScrollArea::
QWidget::qt_scrollarea_viewport
QWidget::page_2
QWidget::qt_scrollarea_hcontainer
QScrollBar::
QBoxLayout::
QWidget::qt_scrollarea_vcontainer
QScrollBar::
QBoxLayout::
**so it seems the title is the QToolBoxButton called qt_toolbox_toolboxbutton
so we can do
// find all childred with the name auto list = ui->toolBox->findChildren<QWidget*>("qt_toolbox_toolboxbutton"); for (QWidget *title : list) { title->hide(); // this was just to test :) Remove you should install filter here }
Thank you, this is VERY helpful. I`m still being a bit dumb, please see what I did:
auto list = ui.MenuToolBox->findChildren<QWidget*>("qt_toolbox_toolboxbutton"); for (QWidget* title : list) { title->installEventFilter(this); }
bool app::eventFilter(QObject* obj, QEvent* e) { qDebug() << Q_FUNC_INFO << obj->objectName(); qDebug() << Q_FUNC_INFO << e->type(); if (e->type() == QEvent::HoverEnter) { setCursor(Qt::PointingHandCursor); } }
I suppose setCursor is called wrong here? Please advise.
There is also the question of sub classing this "eventFilter"? Just because in the main app most likely I will need the evenFilter for something else :/
-
@mrjj said in QToolBox change cursor on hover:
Well, the main issue with such hover is that events are delivered to the widget under the mouse.
So we must put the filter on the right widget to be able to catch it.if we do
ui->toolBox->dumpObjectTree();
we get how its made up
QToolBox::toolBox
QVBoxLayout::
QToolBoxButton::qt_toolbox_toolboxbutton
QScrollArea::
QWidget::qt_scrollarea_viewport
QWidget::page
QWidget::qt_scrollarea_hcontainer
QScrollBar::
QBoxLayout::
QWidget::qt_scrollarea_vcontainer
QScrollBar::
QBoxLayout::
QToolBoxButton::qt_toolbox_toolboxbutton
QScrollArea::
QWidget::qt_scrollarea_viewport
QWidget::page_2
QWidget::qt_scrollarea_hcontainer
QScrollBar::
QBoxLayout::
QWidget::qt_scrollarea_vcontainer
QScrollBar::
QBoxLayout::
**so it seems the title is the QToolBoxButton called qt_toolbox_toolboxbutton
so we can do
// find all childred with the name auto list = ui->toolBox->findChildren<QWidget*>("qt_toolbox_toolboxbutton"); for (QWidget *title : list) { title->hide(); // this was just to test :) Remove you should install filter here }
Thank you, this is VERY helpful. I`m still being a bit dumb, please see what I did:
auto list = ui.MenuToolBox->findChildren<QWidget*>("qt_toolbox_toolboxbutton"); for (QWidget* title : list) { title->installEventFilter(this); }
bool app::eventFilter(QObject* obj, QEvent* e) { qDebug() << Q_FUNC_INFO << obj->objectName(); qDebug() << Q_FUNC_INFO << e->type(); if (e->type() == QEvent::HoverEnter) { setCursor(Qt::PointingHandCursor); } }
I suppose setCursor is called wrong here? Please advise.
There is also the question of sub classing this "eventFilter"? Just because in the main app most likely I will need the evenFilter for something else :/
Hi
It looks ok but does it change the Cursor ?Also, this way it will be set and never reset again, is that what you want ?
- There is also the question of sub classing this "eventFilter"?
Well you can just use a QObject based handler and not tie it to MainWindow.
the ui.xxx->installEventFilter(this);
The "this" part is the object that has the event filter method /the handler.so you can do like
#include <QObject> #include <QMouseEvent> #include <QDebug> #include <QCursor> class myEventFilter: public QObject { Q_OBJECT public: myEventFilter() {} ~myEventFilter() { } protected: bool eventFilter(QObject* object, QEvent* event) { if(event->type() == QEvent::MouseMove) { int x = QCursor::pos().x(); int y = QCursor::pos().y(); qDebug() << "MP -> (" + QString::number(x) + "," + QString::number(y) + ")"; return false; // make it unhandled and sent to other filters. } else return false; } };
https://forum.qt.io/topic/83995/eventfilter-anywhere-in-the-program/2
To have a standalone class to handle it. If that is what you mean by subclassing ?
thewatched->installEventFilter(new myEventFilter());
-
Hi
It looks ok but does it change the Cursor ?Also, this way it will be set and never reset again, is that what you want ?
- There is also the question of sub classing this "eventFilter"?
Well you can just use a QObject based handler and not tie it to MainWindow.
the ui.xxx->installEventFilter(this);
The "this" part is the object that has the event filter method /the handler.so you can do like
#include <QObject> #include <QMouseEvent> #include <QDebug> #include <QCursor> class myEventFilter: public QObject { Q_OBJECT public: myEventFilter() {} ~myEventFilter() { } protected: bool eventFilter(QObject* object, QEvent* event) { if(event->type() == QEvent::MouseMove) { int x = QCursor::pos().x(); int y = QCursor::pos().y(); qDebug() << "MP -> (" + QString::number(x) + "," + QString::number(y) + ")"; return false; // make it unhandled and sent to other filters. } else return false; } };
https://forum.qt.io/topic/83995/eventfilter-anywhere-in-the-program/2
To have a standalone class to handle it. If that is what you mean by subclassing ?
thewatched->installEventFilter(new myEventFilter());
@mrjj said in QToolBox change cursor on hover:
Hi
It looks ok but does it change the Cursor ?Also, this way it will be set and never reset again, is that what you want ?
- There is also the question of sub classing this "eventFilter"?
Well you can just use a QObject based handler and not tie it to MainWindow.
the ui.xxx->installEventFilter(this);
The "this" part is the object that has the event filter method /the handler.so you can do like
#include <QObject> #include <QMouseEvent> #include <QDebug> #include <QCursor> class myEventFilter: public QObject { Q_OBJECT public: myEventFilter() {} ~myEventFilter() { } protected: bool eventFilter(QObject* object, QEvent* event) { if(event->type() == QEvent::MouseMove) { int x = QCursor::pos().x(); int y = QCursor::pos().y(); qDebug() << "MP -> (" + QString::number(x) + "," + QString::number(y) + ")"; return false; // make it unhandled and sent to other filters. } else return false; } };
https://forum.qt.io/topic/83995/eventfilter-anywhere-in-the-program/2
To have a standalone class to handle it. If that is what you mean by subclassing ?
thewatched->installEventFilter(new myEventFilter());
It changes the cursor for the whole main window, but not the items on the toolbox.
Thank you for the myEventFilter example, that's exactly what I meant.
-
@mrjj said in QToolBox change cursor on hover:
Hi
It looks ok but does it change the Cursor ?Also, this way it will be set and never reset again, is that what you want ?
- There is also the question of sub classing this "eventFilter"?
Well you can just use a QObject based handler and not tie it to MainWindow.
the ui.xxx->installEventFilter(this);
The "this" part is the object that has the event filter method /the handler.so you can do like
#include <QObject> #include <QMouseEvent> #include <QDebug> #include <QCursor> class myEventFilter: public QObject { Q_OBJECT public: myEventFilter() {} ~myEventFilter() { } protected: bool eventFilter(QObject* object, QEvent* event) { if(event->type() == QEvent::MouseMove) { int x = QCursor::pos().x(); int y = QCursor::pos().y(); qDebug() << "MP -> (" + QString::number(x) + "," + QString::number(y) + ")"; return false; // make it unhandled and sent to other filters. } else return false; } };
https://forum.qt.io/topic/83995/eventfilter-anywhere-in-the-program/2
To have a standalone class to handle it. If that is what you mean by subclassing ?
thewatched->installEventFilter(new myEventFilter());
It changes the cursor for the whole main window, but not the items on the toolbox.
Thank you for the myEventFilter example, that's exactly what I meant.
@Mecanik said in QToolBox change cursor on hover:
It changes the cursor for the whole main window, but not the items on the toolbox.
Ah. i though that was the goal sorry.
So you mean
obj->setCursor(Qt::PointingHandCursor);Do note setCursor is from QWidget, I think, so It might complain
and you have to cast obj to qwidget via q_objectcast -
@Mecanik said in QToolBox change cursor on hover:
It changes the cursor for the whole main window, but not the items on the toolbox.
Ah. i though that was the goal sorry.
So you mean
obj->setCursor(Qt::PointingHandCursor);Do note setCursor is from QWidget, I think, so It might complain
and you have to cast obj to qwidget via q_objectcast@mrjj said in QToolBox change cursor on hover:
@Mecanik said in QToolBox change cursor on hover:
It changes the cursor for the whole main window, but not the items on the toolbox.
Ah. i though that was the goal sorry.
So you mean
obj->setCursor(Qt::PointingHandCursor);Do note setCursor is from QWidget, I think, so It might complain
and you have to cast obj to qwidget via q_objectcastJob done... I cannot thank you enough. This was really frustrating. With WinApi it was hard as well, but at least I knew what I was looking for / doing. There is much to learn about QT.
I managed to create a separate class for this purpose and a proper even filter:
bool windoweventfilter::eventFilter(QObject* object, QEvent* event) { if (event->type() == QEvent::HoverEnter) { QWidget* qObj = qobject_cast<QWidget*>(object); if (qObj) { qObj->setCursor(Qt::PointingHandCursor); } } return QObject::eventFilter(object, event); }
Thanks again :)
-
@mrjj said in QToolBox change cursor on hover:
@Mecanik said in QToolBox change cursor on hover:
It changes the cursor for the whole main window, but not the items on the toolbox.
Ah. i though that was the goal sorry.
So you mean
obj->setCursor(Qt::PointingHandCursor);Do note setCursor is from QWidget, I think, so It might complain
and you have to cast obj to qwidget via q_objectcastJob done... I cannot thank you enough. This was really frustrating. With WinApi it was hard as well, but at least I knew what I was looking for / doing. There is much to learn about QT.
I managed to create a separate class for this purpose and a proper even filter:
bool windoweventfilter::eventFilter(QObject* object, QEvent* event) { if (event->type() == QEvent::HoverEnter) { QWidget* qObj = qobject_cast<QWidget*>(object); if (qObj) { qObj->setCursor(Qt::PointingHandCursor); } } return QObject::eventFilter(object, event); }
Thanks again :)
+10 for checking the cast before use :)
Yes Qt is quite huge. I actually learned alot of the classed by helping people do stuff
here . It sticks better when used for something and not just reading the docs.However, good questions here often give good answers so you can always return
and ask if you get stuck.