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

Opening a window behind main window



  • Hello.

    I have a function where I'm trying to open a window to view a camera feed. I want this window to be shown in the top left of the screen, while moving the main GUI to the bottom right. The main GUI functions as a control panel of sorts, therefore I want it to stay above the camera feed, even if it blocks a tiny portion of it. I have the following code snippet:

    void MainWindow::display_cam(const QString& title, QRect geometry)
    {
        viewer->show();
        // Move the main GUI in front to retain control
        this->raise();
        viewer->setWindowTitle(title);
        QRect rect = central->window()->windowHandle()
                     ->screen()->availableGeometry();
        if (geometry.width() > (0.9*rect.width()) ||
            geometry.height() > (0.9*rect.height())) {
            viewer->showMaximized();
        } else {
            viewer->resize(geometry.width(), geometry.height());
            viewer->move(rect.topLeft());
        }
        this->move(rect.right() - this->frameGeometry().width(),
                   rect.bottom() - this->frameGeometry().height());
    }
    

    This works, but the problem with this is there is a noticeable delay between the viewer opening and the main window regaining focus. Is there any way to either open the window behind the main window from the get go, or a function which moves the main window to the front so fast it's unnoticeable?


  • Lifetime Qt Champion

    Hi,

    Would the WindowStaysOnBottomHint be what you are looking for. ?

    Hope it help



  • @SGaist Not quite it. That makes the Window stay at the very bottom, behind all other windows, and be forced to stay there. I don't want that, all I want is for it to spawn behind my other window, but not behind any other ones, while also being able to bring it in front of the other window if it's set to be the active window by clicking or tabbing to it.



  • @hodahle
    Unless/until you get a better "integrated" answer: the first thing I would do is put all your lines after

        viewer->show();
        // Move the main GUI in front to retain control
        this->raise();
    

    into a QTimer. This allows the minimal to happen on start up. Even if that does not behave as you'd like yet, it at least narrows down where the "delay" is....



  • @JonB To do that, I need a slot which takes no arguments, no? I use both the arguments title and geometry below those. Even if I just remove everything in that function besides

    viewer->show();
    raise();
    

    there's still a noticeable delay to actually raising it. What's interesting is if I include the other functions that move and resize the windows, those are executed much sooner than raise() even though they come after it. I suspect this might have something to do with Qt's implementation of it, or maybe even Windows itself, but I'm not sure what to do about it.



  • @hodahle
    Briefly.

    Yes, you would need another slot for QTimer. To get it to have access to title & geometryfrom your function you could conveniently use a C++ lambda. That is a whole other topic, which one day you should look up. However, for now it's not relevant, as you have said you can delete all those extra lines and it's still "delayed".

    I don't know why you get such a "delay". (Is your viewer "big" with "lots of" widgets?) One thing you could try, don't know if it would help/how it would behave, is to move the MainWindow::raise() call into the the viewers QWidget::showEvent slot (for now, while you test, just hack in access to your mainWindow instance because you're not sure how to pass that around).. If that works, it might run earlier, I don't know. Or, if you have to, you could look at the Qt source code (e.g. via woboq) to see what just the raise() has to do.



  • @JonB Not a big viewer at all. viewer is a simple QGraphicsView containing a QPixmapItem which is continually updated through another slot taking a signal from the camera thread every time it has a new frame, at 60fps.

    Part of the issue seems to be with the debug build, which is obviously a fair bit slower than release. In release it doesn't really seem noticeable, though I imagine it might be on a slow system. Still, I do find the asynchronous behaviour of raise() interesting. I tried looking a bit at the source code, but didn't really get anywhere. Because it's not a problem in release, I guess I'll just leave it be for now. Thanks for the help, though, much appreciated.