Results 1 to 13 of 13

Thread: How to do auto show/hide a widget in Qt

  1. #1
    Join Date
    Sep 2011
    Location
    Bangalore
    Posts
    254
    Thanks
    92
    Thanked 16 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default How to do auto show/hide a widget in Qt

    I'm trying to create a widget that has auto show/hide property and the widget has 3 buttons in QVBoxLayout. I need to show the widget the same way Ubuntu unity's menubar is displayed. I need to create that kinda animation. When the cursor is moved to a specified area of the QMainWindow, the widget has to be displayed with some transition time. And when the cursor moves out of the specified area, the widget should be hidden.
    Can someone kindly help me out to get started.

    Should I use QPropertyAnimation or something related to Qt Graphics ?

    Thank you.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to do auto show/hide a widget in Qt

    Yes, you can use QPropertyAnimation.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Sep 2011
    Location
    Bangalore
    Posts
    254
    Thanks
    92
    Thanked 16 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: How to do auto show/hide a widget in Qt

    I tried QGraphicsView & QGraphicsSCene, but I not working as I expected. I'm calling the widget to show after 3 seconds using a singleshot timer. But I see the widget is flashing and disappearing.
    Below is the way how I implemented see how it comes out.

    Qt Code:
    1. #include "ccentralwidget.h"
    2. #include <QGraphicsScene>
    3. #include <QGraphicsView>
    4. #include <QTimer>
    5.  
    6. CMainWidget::CMainWidget(QWidget *parent) :
    7. QWidget(parent)
    8. {
    9. this->setStyleSheet("background-color: lightGray;");
    10. this->setFixedSize(650, 450);
    11. m_widget = new CMenuWidget();
    12.  
    13. QTimer::singleShot(3000, this, SLOT(showMenuWidget()));
    14. }
    15.  
    16. CMainWidget::~CMainWidget()
    17. {
    18. delete m_widget;
    19. }
    20.  
    21. void CMainWidget::showMenuWidget()
    22. {
    23. scene.addWidget(m_widget);
    24. scene.setSceneRect(0, 30, 60, 250);
    25.  
    26. QGraphicsView view(&scene);
    27. view.show();
    28.  
    29. }
    To copy to clipboard, switch view to plain text mode 

    ---------------------------------------------------------------------------------------------

    And I tried it using QPropertyAnimation also, but it's giving some error/warning messages output.
    I'm calling the below slot in singleshot timer the same way as shown in the above code.
    Qt Code:
    1. void CCentralWidget::showMenuWidget()
    2. {
    3. QPropertyAnimation *animation = new QPropertyAnimation(m_widget, "MyMenu");
    4. animation->setDuration(2000);
    5. animation->setStartValue(QRect(0, 0, 100, 30));
    6. animation->setEndValue(QRect(250, 250, 100, 30));
    7.  
    8. animation->start();
    9. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. //Output Message:
    2. QPropertyAnimation: you're trying to animate a non-existing property MyMenu of your QObject
    To copy to clipboard, switch view to plain text mode 

    I need to show/hide the widget the same way how the left app menu widget is shown/hidden on mouse move to the left area in Ubuntu unity and this kind of graphics can be seen a text editor called Scribes.
    So for now I'm trying to achieve the same transition on singleshot timer, later I call it in movemove event.
    Kindly help me. Thank you.
    Last edited by rawfool; 27th May 2013 at 08:05.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to do auto show/hide a widget in Qt

    You are creating the view on the stack so it gets destroyed when the stack unwinds when the flow returns from the function. By the way I don't see the point of using a graphics scene (and view) only to add a widget to it. You can use the widget directly.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How to do auto show/hide a widget in Qt

    Here is one example, hope it helps
    Qt Code:
    1. #include <QtGui>
    2. #include <QtWidgets>
    3. #include <QApplication>
    4.  
    5. class Widget : public QWidget
    6. {
    7. public:
    8. explicit Widget(QWidget * parent = 0)
    9. : QWidget(parent)
    10. , mAnimation(new QPropertyAnimation(this, "geometry"))
    11. {
    12. parent->setMouseTracking(true);
    13. parent->installEventFilter(this);
    14. mAnimation->setDuration(250);
    15. }
    16.  
    17. protected:
    18. bool eventFilter(QObject * object, QEvent * event)
    19. {
    20. if((parent() == object) and (event->type() == QEvent::MouseMove))
    21. {
    22. QMouseEvent * mouseEvent = static_cast<QMouseEvent *>(event);
    23. if(mouseEvent->pos().x() < 10)
    24. {
    25. if(isHidden() and (mAnimation->state() != mAnimation->Running))
    26. {
    27. mAnimation->setStartValue(QRect(0, 0, 0, sizeHint().height()));
    28. mAnimation->setEndValue(QRect(0, 0, sizeHint().width(), sizeHint().height()));
    29. disconnect(mAnimation, SIGNAL(finished()), this, SLOT(hide()));
    30. mAnimation->start();
    31. show();
    32. }
    33. }
    34. else if(mAnimation->state() != mAnimation->Running)
    35. {
    36. if(!isHidden())
    37. {
    38. mAnimation->setEndValue(QRect(0, 0, 0, sizeHint().height()));
    39. mAnimation->setStartValue(QRect(0, 0, sizeHint().width(), sizeHint().height()));
    40. connect(mAnimation, SIGNAL(finished()), this, SLOT(hide()));
    41. mAnimation->start();
    42. }
    43. }
    44. }
    45. return QWidget::eventFilter(object, event);
    46. }
    47.  
    48. private:
    49. QPropertyAnimation * mAnimation;
    50. };
    51.  
    52. int main(int argc, char *argv[])
    53. {
    54. QApplication app(argc, argv);
    55.  
    56. QLabel label("Main Widget");
    57. label.showMaximized();
    58.  
    59. Widget widget(&label);
    60. QVBoxLayout * layout = new QVBoxLayout(&widget);
    61.  
    62. for(int i = 0 ; i < 10; i++)
    63. layout->addWidget(new QPushButton(QString("PushButton %1").arg(100 + i)));
    64.  
    65. return app.exec();
    66. }
    To copy to clipboard, switch view to plain text mode 
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  6. The following user says thank you to Santosh Reddy for this useful post:

    rawfool (27th May 2013)

  7. #6
    Join Date
    Sep 2011
    Location
    Bangalore
    Posts
    254
    Thanks
    92
    Thanked 16 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: How to do auto show/hide a widget in Qt

    Thank you very much Santosh Reddy. Your code was very helpful in understanding QAnimationProperty. After understanding your code, I implemented it, but a bit different in approach.
    Instead of adding event filter in menu_widget(child widget), I did it in Parent widget. And everything worked fine.
    The transition is sharp and final thing now I'm looking for is some smooth transition. And if I give more value in setDuration(), it's affecting in hiding, but not in showing the widget. However for the setDuration(), even after the specified duration, the transition is sharp, whereas smooth would be more eye-pleasing.
    I tried using mAnimation->setEasingCurve(QEasingCurve::InOutElastic) and other QEasingCurve properties, but couldn't achieve the smoothness in transition.

    But again, thank you for your kind help.

    My Code (Implemented similarly based on your's in the previous post):
    Qt Code:
    1. // This is mainWidget, where in I'll show the menu
    2. #include "cmainwidget.h"
    3.  
    4. CMainWidget::CMainWidget(QWidget *parent)
    5. : QWidget(parent)
    6. {
    7. this->setMouseTracking(true);
    8. this->setFixedSize(650, 400);
    9. menuWidget = new CMenuWidget(this);
    10. menuWidget->hide();
    11. mAnimation = new QPropertyAnimation(menuWidget, "geometry");
    12. mAnimation->setDuration(250); // Increasing this isn't helping in smooth transition, instead it's affecting hide when the mouse is > 80 in "else if" in mouseMoveEvent
    13. mAnimation->setEasingCurve(QEasingCurve::InOutElastic);
    14. }
    15.  
    16. CMainWidget::~CMainWidget()
    17. {
    18. delete mAnimation;
    19. delete menuWidget;
    20. }
    21.  
    22. void CMainWidget::mouseMoveEvent(QMouseEvent *mmEvent)
    23. {
    24. if(mmEvent->pos().x() <= 80)
    25. {
    26. qDebug("Mouse X-Position - %d", mmEvent->pos().x());
    27. mAnimation->setStartValue(QRect(0, 40, 0, 40));
    28. mAnimation->setEndValue(QRect(0, 40, menuWidget->sizeHint().width(), 40));
    29. disconnect(mAnimation, SIGNAL(finished()), this, SLOT(hideMenuWid()));
    30. mAnimation->start();
    31. menuWidget->show();
    32. }
    33. else if(mmEvent->pos().x() > 80)
    34. {
    35. qDebug("Mouse X-Position - %d", mmEvent->pos().x());
    36. mAnimation->setEndValue(QRect(0, 40, 0, 40));
    37. mAnimation->setStartValue(QRect(0, 40, menuWidget->sizeHint().width(), 40));
    38. connect(mAnimation, SIGNAL(finished()), this, SLOT(hideMenuWid()));
    39. mAnimation->start();
    40. }
    41. }
    42.  
    43. void CMainWidget::hideMenuWid()
    44. {
    45. menuWidget->hide();
    46. }
    To copy to clipboard, switch view to plain text mode 

  8. #7
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How to do auto show/hide a widget in Qt

    Try using QEasingCurve::InOutQuint, and you can use different setDuration() while showing and while hiding(), this will ensure a slow smotth show, and quick hide.
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  9. The following user says thank you to Santosh Reddy for this useful post:

    rawfool (27th May 2013)

  10. #8
    Join Date
    Sep 2011
    Location
    Bangalore
    Posts
    254
    Thanks
    92
    Thanked 16 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: How to do auto show/hide a widget in Qt

    Now a small hiccup, after adding this auto-hide menu, if there is any widget that's overlapping the menu widget's region, then it's not responding and also the menu widget is shown under it.
    So if there is any other widget, and when the menu widget is shown, it's moving under visible widget.
    Is there anything like bring-to-front, etc, for bringing the menu widget to front. I tried setFocus(); but didn't solve the issue.

    How do I bring the menu widget to top-most visible area and mouse hover on the other widgets in that page should be relative ?

    I tried, but didn't work as expected:
    Qt Code:
    1. menuWidget->setWindowFlags(Qt::WindowStaysOnTopHint); // menu widget is child of mainwidget(central Widget of main window) and is not in layout
    2. menuWidget->raise();
    3. frmWidget->setWindowFlags(Qt::WindowStaysOnBottomHint);
    To copy to clipboard, switch view to plain text mode 

    EDIT: I'm able to bring it on top by adding the menubar at last. But the mouse move on the bottom widget isn't giving response to this to hide the menu widget, when out of the specified region.

    Thank you.
    Last edited by rawfool; 29th May 2013 at 13:40.

  11. #9
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How to do auto show/hide a widget in Qt

    EDIT: I'm able to bring it on top by adding the menubar at last. But the mouse move on the bottom widget isn't giving response to this to hide the menu widget, when out of the specified region.
    Then hide() the menu widget when the menu widget reveices QEevnt::Leave event, which indicated that mouse has left the menu widget
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  12. The following user says thank you to Santosh Reddy for this useful post:

    rawfool (30th May 2013)

  13. #10
    Join Date
    Sep 2011
    Location
    Bangalore
    Posts
    254
    Thanks
    92
    Thanked 16 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: How to do auto show/hide a widget in Qt

    This is how I did that, but now the menu widget is not hiding,

    Qt Code:
    1. bool eventFilter(QObject * object, QEvent * event)
    2. {
    3. if((parent() == object) & (event->type() == QEvent::MouseMove))
    4. {
    5. QMouseEvent * mouseEvent = static_cast<QMouseEvent *>(event);
    6. if(mouseEvent->pos().x() < 80)
    7. {
    8. if(isHidden() && (mAnimation->state() != mAnimation->Running))
    9. {
    10. mAnimation->setStartValue(QRect(-3, 80, 0, 250));
    11. mAnimation->setEndValue(QRect(0, 80, 70, 250));
    12. disconnect(mAnimation, SIGNAL(finished()), this, SLOT(hide()));
    13. mAnimation->start();
    14. show();
    15. }
    16. }
    17. else if((mouseEvent->type() == QEvent::Leave) && (mAnimation->state() != mAnimation->Running))
    18. {
    19. qDebug("Inside QEvent::Leave"); // This message is not getting printed
    20. if(!isHidden())
    21. {
    22. mAnimation->setEndValue(QRect(-3, 80, 0, 250));
    23. mAnimation->setStartValue(QRect(0, 80, 70, 250));
    24. connect(mAnimation, SIGNAL(finished()), this, SLOT(hide()));
    25. mAnimation->start();
    26. }
    27. }
    28. }
    29. return QWidget::eventFilter(object, event);
    30. }
    To copy to clipboard, switch view to plain text mode 
    I think my else if is wrong. Kindly help me correct this. Thank you

  14. #11
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How to do auto show/hide a widget in Qt

    QEvent::MouseMove event is received for parent widget, and QEvent::Leave should be received for self widget, so move the else if out of if(parent() ==...., and also make suere to install the event filter on self. (this->installEventFilter(this);
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  15. The following user says thank you to Santosh Reddy for this useful post:

    rawfool (30th May 2013)

  16. #12
    Join Date
    Sep 2011
    Location
    Bangalore
    Posts
    254
    Thanks
    92
    Thanked 16 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: How to do auto show/hide a widget in Qt

    Thanks a lot. All the issues related to this are solved for now.

  17. #13
    Join Date
    Sep 2011
    Location
    Bangalore
    Posts
    254
    Thanks
    92
    Thanked 16 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: How to do auto show/hide a widget in Qt

    Just a small note, as this may help someone who do this. After doing this -
    Quote Originally Posted by Santosh Reddy View Post
    QEvent::Leave should be received for self widget ..
    it hides the widget.
    A small problem persisted and it was - if there's a layout and widgets in the mouse-hover area, then the trigger didn't reach the menu widget. I solved it by making the layout and widgets as children to the same parent to which menu widget was and enabled mouse tracking true for the widget(s) on the way and this solved my problem.
    Thank you.

Similar Threads

  1. Replies: 10
    Last Post: 20th April 2015, 23:24
  2. Replies: 1
    Last Post: 9th December 2011, 04:42
  3. Replies: 4
    Last Post: 2nd October 2011, 01:20
  4. Replies: 2
    Last Post: 8th February 2011, 19:07
  5. MAC: Getting Dock widget show/hide events
    By jay in forum Qt Programming
    Replies: 3
    Last Post: 31st May 2010, 09:07

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.