Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Switching to `QWidget::activateWindow()` from the deprecated `QApplication::setActiveWindow` yields null widget for `QApplication::activeWindow`
Forum Updated to NodeBB v4.3 + New Features

Switching to `QWidget::activateWindow()` from the deprecated `QApplication::setActiveWindow` yields null widget for `QApplication::activeWindow`

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 351 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Sankhesh Jhaveri
    wrote on 16 Jan 2025, 17:32 last edited by
    #1

    When switching away from the deprecated API: QApplication::setActiveWindow to the recommended QWidget::activateWindow, the widget/window never gets set as the active window. QApplication::activeWindow returns a nullptr.

    Is there an alternate API for fetching the active widget as set by QWidget::activateWindow?

    Here's a small representative example:

    #include <QApplication>
    #include <QDebug>
    #include <QMainWindow>
    
    int main(int argc, char* argv[])
    {
      QApplication app(argc, argv);
    
      Q_ASSERT(QApplication::activeWindow() == nullptr);
      QMainWindow w;
      w.show();
      w.raise();
      w.activateWindow();
      // QApplication::setActiveWindow(&w); Deprecated API
      qDebug() << QApplication::activeWindow() << w.isActiveWindow();
      Q_ASSERT(QApplication::activeWindow() != nullptr);
      if (!QApplication::activeWindow())
      {
        // in case if this is not a debug build
        qCritical() << "Couldn't activate window.";
      }
    
      return app.exec();
    }
    

    The output is

    $ ./QtActiveWindow
    QWidget(0x0) false
    ASSERT: "QApplication::activeWindow() != nullptr" in file /home/sankhesh/Projects/TestProjects/QtActiveWindow/QtActiveWindow/QtActiveWindow.cxx, line 16
    [1]    256514 IOT instruction (core dumped)  ./QtActiveWindow
    
    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 16 Jan 2025, 17:38 last edited by
      #2

      Hi and welcome to devnet,

      You are calling that function way too early.

      Check it's documentation again. The key word is: visible. Calling show on a widget does not make it instantly visible. It schedules its appearance at the earliest possible time when the event loop is running.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • S Offline
        S Offline
        Sankhesh Jhaveri
        wrote on 16 Jan 2025, 18:08 last edited by
        #3

        Thank you for the quick response, @SGaist. Your answer helped me understand the issue.

        It appears that QApplication::setActiveWindow updates the internal cached active_window pointer to the specified widget here: https://codebrowser.dev/qt6/qtbase/src/widgets/kernel/qapplication.cpp.html#1848. This enables subsequent code to call QApplication::activeWindow immediately afterward, successfully.

        However, QWidget::activateWindow schedules this action on the platform window (https://codebrowser.dev/qt6/qtbase/src/gui/kernel/qwindow.cpp.html#1292), which means that the activeWindow will not be available until the underlying windowing event system has processed that request.

        So, in my case, I could do something like:

          w.show();
          QTimer::singleShot(100, [&w](){w.activateWindow(); qDebug() << QApplication::activeWindow();});
        

        which gives the native windowing system a chance to process the event. And it works indeed.

        J 1 Reply Last reply 16 Jan 2025, 18:27
        0
        • S Sankhesh Jhaveri
          16 Jan 2025, 18:08

          Thank you for the quick response, @SGaist. Your answer helped me understand the issue.

          It appears that QApplication::setActiveWindow updates the internal cached active_window pointer to the specified widget here: https://codebrowser.dev/qt6/qtbase/src/widgets/kernel/qapplication.cpp.html#1848. This enables subsequent code to call QApplication::activeWindow immediately afterward, successfully.

          However, QWidget::activateWindow schedules this action on the platform window (https://codebrowser.dev/qt6/qtbase/src/gui/kernel/qwindow.cpp.html#1292), which means that the activeWindow will not be available until the underlying windowing event system has processed that request.

          So, in my case, I could do something like:

            w.show();
            QTimer::singleShot(100, [&w](){w.activateWindow(); qDebug() << QApplication::activeWindow();});
          

          which gives the native windowing system a chance to process the event. And it works indeed.

          J Offline
          J Offline
          JonB
          wrote on 16 Jan 2025, 18:27 last edited by JonB
          #4

          @Sankhesh-Jhaveri
          I have not tested but you may find the activation first takes place (rather than waiting on a timer), and activeWindow() becomes valid, if you subclass your widget and override the showEvent()

          1 Reply Last reply
          0
          • S Offline
            S Offline
            Sankhesh Jhaveri
            wrote on 16 Jan 2025, 18:34 last edited by Sankhesh Jhaveri
            #5

            Thanks @JonB. Is there a signal I can connect to, for when the window is actually activated?

            FWIW, this issue is for the ParaView client where the window is already visible but not the active one. The showEvent override wouldn't help there.

            J 1 Reply Last reply 16 Jan 2025, 18:50
            0
            • S Sankhesh Jhaveri
              16 Jan 2025, 18:34

              Thanks @JonB. Is there a signal I can connect to, for when the window is actually activated?

              FWIW, this issue is for the ParaView client where the window is already visible but not the active one. The showEvent override wouldn't help there.

              J Offline
              J Offline
              JonB
              wrote on 16 Jan 2025, 18:50 last edited by
              #6

              @Sankhesh-Jhaveri
              Heave a read through https://stackoverflow.com/questions/16721557/how-to-detect-if-a-window-has-been-activated from 11 years ago :) Does anything there like QEvent::WindowActivate help your situation?

              1 Reply Last reply
              0
              • S Offline
                S Offline
                Sankhesh Jhaveri
                wrote on 16 Jan 2025, 19:52 last edited by
                #7

                The QWindow::activeChanged signal allows me to call the delegate function when the window is actually activated.

                1 Reply Last reply
                0
                • S Sankhesh Jhaveri has marked this topic as solved on 17 Jan 2025, 14:12

                1/7

                16 Jan 2025, 17:32

                • Login

                • Login or register to search.
                1 out of 7
                • First post
                  1/7
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved