Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to force QDialogue to be on top/not on top of MainWindow



  • Hi,

    I have a QDialoge which I created that uses qwt for plotting graphs. When I launch the dialogue I want to give users the choice of making the dialogue always stay on top or not. I setup a signal/slot with a check box to force the dialogue to change its flags but for some reason it doesn't work. Ideally what I would really prefer is to have the dialogue have a pin which is much nicer but without being part of a dock since the dialogue is not designed to dock to the main window.

    If someone can show me how to create a pin even with docking but ignore the docking feature just enable the pin, that would be great but if not here is the code for forcing the dialogue to change its flags when the user checks and unchecks the checkbox to force the dialogue always on top or not. Perhaps you can't do it on the fly. The signal/slot works so I'm only showing the slot code.

    void MainWindow::getAlwaysOnTopFlag(int widgetID, bool alwaysOnTopFlag)
    {
    if(alwaysOnTopFlag == true)
    {
    dialogue->setWindowFlags(windowFlags() & ~Qt::CustomizeWindowHint); //clear the past flags (not sure if correct)
    dialogue->setWindowFlags(windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
    dialogue->setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); //add a minimize button
    dialogue->setWindowFlags(windowFlags() & Qt::WindowStaysOnTopHint); //always on top
    }
    else //not on top
    {
    dialogue->setWindowFlags(windowFlags() & ~Qt::CustomizeWindowHint); //clear past flags
    dialogue->setWindowFlags(windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
    dialogue->setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); //add a minimize button
    dialogue->setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); //not on top
    }
    }

    Any help would be greatly appreciated!
    Thanks.



  • @leinad said in How to force QDialogue to be on top/not on top of MainWindow:

    dialogue->setWindowFlags(windowFlags() & Qt::WindowStaysOnTopHint); //always on top

    The & looks wrong, you're not setting it. In fact, you're (probably) undoing the previous two | lines....?

    dialogue->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); //always on top
    

    Like the other flags you set. | to set, & ~ to clear.

    In newer Qt versions there is QWidget::setWindowFlag(Qt::WindowType flag, bool on = true) which makes manipulating one flag easier if you prefer.



  • When I set to always on top, the dialogue disappears. Seems Qt does not the flags to change.



  • @leinad
    I can only say that if you have not changed your shown code to what I wrote I don't know what you are actually setting its flags to when alwaysOnTopFlag == true (you are clearing all its flags). Have you altered your code?



  • void MainWindow::getAlwaysOnTopFlag(int widgetID, bool alwaysOnTopFlag)
    {
    if(alwaysOnTopFlag == true)
    {
    dialogue->setWindowFlags(windowFlags() & ~Qt::CustomizeWindowHint);
    dialogue->setWindowFlags(windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
    dialogue->setParent(NULL); //allow the plotWidget not to go behind the main window
    dialogue->setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); //add a minimize button
    dialogue->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); //always on top
    }
    else
    {
    dialogue->setWindowFlags(windowFlags() & ~Qt::CustomizeWindowHint);
    dialogue->setWindowFlags(windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
    dialogue->setParent(NULL); //allow the plotWidget to go behind the main window
    dialogue->setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); //add a minimize button
    dialogue->setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); //not on top
    }
    }

    No matter what part of the if statement, the dialogue closes. Going to the any flag statement closes the dialogue. I commented one by one. So I have two issues. The dialogue closing and have the capability I want. Basically Qt does not like any of the flag statements whether it is for alwaysOnTop == true or false.



  • @leinad
    Is the following relevant:
    https://doc.qt.io/qt-5/qwidget.html#windowFlags-prop

    Note: This function [i.e. setWindowFlags()] calls setParent() when changing the flags for a window, causing the widget to be hidden. You must call show() to make the widget visible again..



  • Yes, I just figured that out. So this works for those interested.

    //Slot to force a plot widget to always be on top or not - alwaysOnTopFlag = true means always on top
    void MainWindow::getAlwaysOnTopFlag(int widgetID, bool alwaysOnTopFlag)
    {
    if(alwaysOnTopFlag == true)
    {
    dialogue->setWindowFlags(windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
    dialogue->setParent(NULL); //allow the plotWidget not to go behind the main window
    dialogue->setWindowFlags(windowFlags() & ~Qt::CustomizeWindowHint);
    dialogue->setWindowFlags(windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
    dialogue->setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); //add a minimize button
    dialogue->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); //always on top
    dialogue->show();
    }
    else
    {
    dialogue->setWindowFlags(windowFlags() & ~Qt::CustomizeWindowHint);
    dialogue->setWindowFlags(windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
    dialogue->setParent(NULL); //allow the plotWidget to go behind the main window
    dialogue->setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); //add a minimize button
    dialogue->setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); //not on top
    dialogue->show();
    }
    }

    Would a pin be easier or better? If so is there an easy way to implement?


Log in to reply