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. QGuiApplication::primaryScreen() not telling me what I need to know
Forum Updated to NodeBB v4.3 + New Features

QGuiApplication::primaryScreen() not telling me what I need to know

Scheduled Pinned Locked Moved Unsolved General and Desktop
16 Posts 6 Posters 3.8k 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.
  • Z Offline
    Z Offline
    zsd-
    wrote on last edited by
    #1

    I'm using Qt 5.14.2 on Linux. I have two screens, my "laptop screen" and my "external monitor". My program wants to get information about the screen ("monitor") on which the window is actually displayed, because it wants to find out the (physical) DPI for that screen. The documentation says

    primaryScreen : QScreen* const

    This property holds the primary (or default) screen of the application.

    This will be the screen where QWindows are initially shown, unless otherwise specified.

    The primaryScreenChanged signal was introduced in Qt 5.6.

    Notwithstanding the above, it always returns the laptop screen, even when the window is initially opened on the external monitor or if I move it from the laptop to the external monitor and try that function again. And the two screens have different physical DPIs, so finding out about the laptop screen is only good sometimes.

    I have also tried
    QScreen * canvas_screen = QGuiApplication::screenAt(canvas_pos);
    but that also gives me the same thing as the laptop screen, even when the window is completely on the external monitor.

    I don't know whether there is a bug in the documentation, a bug in the implementation, or (more likely?) a misunderstanding of these functions on my part. But, in any case, is anyone able to enlighten me on way to find the physical DPI of the screen on which a particular window resides?

    Thanks

    Z 1 Reply Last reply
    0
    • JoeCFDJ Offline
      JoeCFDJ Offline
      JoeCFD
      wrote on last edited by JoeCFD
      #2

      QList<QScreen *> QGuiApplication::screens() to find the list of screens and you will know which one is your external screen?
      compare with the pointer address of your primary screen: no==>external screen

      Z 1 Reply Last reply
      0
      • B Offline
        B Offline
        Bonnie
        wrote on last edited by
        #3

        How do you get canvas_pos?
        Are you sure it is the right global position?

        Z 1 Reply Last reply
        1
        • JoeCFDJ JoeCFD

          QList<QScreen *> QGuiApplication::screens() to find the list of screens and you will know which one is your external screen?
          compare with the pointer address of your primary screen: no==>external screen

          Z Offline
          Z Offline
          zsd-
          wrote on last edited by
          #4

          @JoeCFD Joe, thanks for the answer. I'm not sure what you meant by your first sentence, given that it ends with a '?'. Iterating through the list of screens I see both screens; here is some output:
          There are 2 screens
          The next screen info:
          serial number //
          available size: wd 2880 * ht 1800
          logical DPI is 163.16
          physical DPI is 219.69
          The next screen info:
          serial number /20206/
          available size: wd 3840 * ht 2160
          logical DPI is 163.16
          physical DPI is 161.96
          But I am not sure what you are suggesting about looking at the pointer address of my primary screen. Can you clarify that a bit?

          1 Reply Last reply
          0
          • B Bonnie

            How do you get canvas_pos?
            Are you sure it is the right global position?

            Z Offline
            Z Offline
            zsd-
            wrote on last edited by
            #5

            @Bonnie Here is the code I used to get canvas_pos. (And no, I'm not sure it is right. I'm certainly open to being corrected.)
            QWidget * wind = ui->canvas->window();
            QPoint canvas_pos = wind->pos();

            (Is that enough info to answer your question?)
            Thanks.

            B 1 Reply Last reply
            0
            • Z zsd-

              @Bonnie Here is the code I used to get canvas_pos. (And no, I'm not sure it is right. I'm certainly open to being corrected.)
              QWidget * wind = ui->canvas->window();
              QPoint canvas_pos = wind->pos();

              (Is that enough info to answer your question?)
              Thanks.

              B Offline
              B Offline
              Bonnie
              wrote on last edited by Bonnie
              #6

              @zsd Your result may be not accurate, but should work if "the window is completely on the external monitor".
              How about these approaches?

              QPoint canvas_pos = ui->canvas->window()->mapToGlobal(QPoint(0, 0));
              QScreen * canvas_screen = QGuiApplication::screenAt(canvas_pos);
              
              QPoint canvas_pos = ui->canvas->mapToGlobal(QPoint(0, 0));
              QScreen * canvas_screen = QGuiApplication::screenAt(canvas_pos);
              
              if(QWindow * wind = ui->canvas->window()->windowHandle()) {
                  QScreen * canvas_screen = wind->screen();
              }
              
              Z 1 Reply Last reply
              0
              • B Bonnie

                @zsd Your result may be not accurate, but should work if "the window is completely on the external monitor".
                How about these approaches?

                QPoint canvas_pos = ui->canvas->window()->mapToGlobal(QPoint(0, 0));
                QScreen * canvas_screen = QGuiApplication::screenAt(canvas_pos);
                
                QPoint canvas_pos = ui->canvas->mapToGlobal(QPoint(0, 0));
                QScreen * canvas_screen = QGuiApplication::screenAt(canvas_pos);
                
                if(QWindow * wind = ui->canvas->window()->windowHandle()) {
                    QScreen * canvas_screen = wind->screen();
                }
                
                Z Offline
                Z Offline
                zsd-
                wrote on last edited by
                #7

                @Bonnie ,
                thanks very much. I now see that there is another issue involved.

                I am looking for this information after the following code (in main()):
                QApplication a(argc, argv);
                MainWindow w;
                w.show();
                At that point (after calling w.show()) all three versions of your code are still returning the laptop screen information, even when the window opens completely on the external monitor.

                On the good side, all three give the correct screen if I call a function to print things out when a menu item is chosen (nothing magic about a menu item, it just seemed a quick way to test things out).

                So perhaps my question should be modified to the following:
                How can I get the correct screen information after w.show() but before I call
                a.exec()
                In other words (possibly!), how can I get Qt to really look and see which monitor the window is on before calling a.exec() ?

                Thanks to anyone who can provide enlightenment!

                Christian EhrlicherC 1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Hi,

                  Here is the trick: show has no effect until exec runs. The show method schedules an event to bring the widget to screen. Hence you might want to move some logic in the showEvent method.

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

                  Z 1 Reply Last reply
                  2
                  • SGaistS SGaist

                    Hi,

                    Here is the trick: show has no effect until exec runs. The show method schedules an event to bring the widget to screen. Hence you might want to move some logic in the showEvent method.

                    Z Offline
                    Z Offline
                    zsd-
                    wrote on last edited by zsd-
                    #9

                    @SGaist
                    Thanks for the information. I had previously tried a sleep(5) after show() before exec() and a window (albeit empty) showed up on the monitor before exec() was called, and so I thought (ha!) that Qt would know which monitor it was on.

                    I tried putting a showEvent() in my main window class and that was called when w.show() was called (and thus before a.exec()), so it still has the wrong answer.

                    I've hunted around on the net, but I haven't found any enlightenment suitable for my level of Qt n00bness. Are you able to either elaborate a bit further or point me in the direction of a "how to use showEvent() at just the right place and just the right time for n00bs" document?

                    Thanks.

                    Z 1 Reply Last reply
                    0
                    • Z zsd-

                      @SGaist
                      Thanks for the information. I had previously tried a sleep(5) after show() before exec() and a window (albeit empty) showed up on the monitor before exec() was called, and so I thought (ha!) that Qt would know which monitor it was on.

                      I tried putting a showEvent() in my main window class and that was called when w.show() was called (and thus before a.exec()), so it still has the wrong answer.

                      I've hunted around on the net, but I haven't found any enlightenment suitable for my level of Qt n00bness. Are you able to either elaborate a bit further or point me in the direction of a "how to use showEvent() at just the right place and just the right time for n00bs" document?

                      Thanks.

                      Z Offline
                      Z Offline
                      zsd-
                      wrote on last edited by
                      #10
                      This post is deleted!
                      1 Reply Last reply
                      0
                      • Z zsd-

                        I'm using Qt 5.14.2 on Linux. I have two screens, my "laptop screen" and my "external monitor". My program wants to get information about the screen ("monitor") on which the window is actually displayed, because it wants to find out the (physical) DPI for that screen. The documentation says

                        primaryScreen : QScreen* const

                        This property holds the primary (or default) screen of the application.

                        This will be the screen where QWindows are initially shown, unless otherwise specified.

                        The primaryScreenChanged signal was introduced in Qt 5.6.

                        Notwithstanding the above, it always returns the laptop screen, even when the window is initially opened on the external monitor or if I move it from the laptop to the external monitor and try that function again. And the two screens have different physical DPIs, so finding out about the laptop screen is only good sometimes.

                        I have also tried
                        QScreen * canvas_screen = QGuiApplication::screenAt(canvas_pos);
                        but that also gives me the same thing as the laptop screen, even when the window is completely on the external monitor.

                        I don't know whether there is a bug in the documentation, a bug in the implementation, or (more likely?) a misunderstanding of these functions on my part. But, in any case, is anyone able to enlighten me on way to find the physical DPI of the screen on which a particular window resides?

                        Thanks

                        Z Offline
                        Z Offline
                        zsd-
                        wrote on last edited by
                        #11

                        @zsd In case anyone is still watching and interested, the problem persists in 5.15.0.
                        If anyone has any more thoughts to share, I'd be happy to hear them.

                        1 Reply Last reply
                        0
                        • Z zsd-

                          @Bonnie ,
                          thanks very much. I now see that there is another issue involved.

                          I am looking for this information after the following code (in main()):
                          QApplication a(argc, argv);
                          MainWindow w;
                          w.show();
                          At that point (after calling w.show()) all three versions of your code are still returning the laptop screen information, even when the window opens completely on the external monitor.

                          On the good side, all three give the correct screen if I call a function to print things out when a menu item is chosen (nothing magic about a menu item, it just seemed a quick way to test things out).

                          So perhaps my question should be modified to the following:
                          How can I get the correct screen information after w.show() but before I call
                          a.exec()
                          In other words (possibly!), how can I get Qt to really look and see which monitor the window is on before calling a.exec() ?

                          Thanks to anyone who can provide enlightenment!

                          Christian EhrlicherC Offline
                          Christian EhrlicherC Offline
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @zsd said in QGuiApplication::primaryScreen() not telling me what I need to know:

                          In other words (possibly!), how can I get Qt to really look and see which monitor the window is on before calling a.exec() ?

                          You can't since even Qt does not know this.

                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                          Visit the Qt Academy at https://academy.qt.io/catalog

                          Z 2 Replies Last reply
                          1
                          • Christian EhrlicherC Christian Ehrlicher

                            @zsd said in QGuiApplication::primaryScreen() not telling me what I need to know:

                            In other words (possibly!), how can I get Qt to really look and see which monitor the window is on before calling a.exec() ?

                            You can't since even Qt does not know this.

                            Z Offline
                            Z Offline
                            zsd-
                            wrote on last edited by
                            #13

                            @Christian-Ehrlicher Thanks for the answer. I find this surprising, given that the w.show() causes an empty window frame to pop up on the monitor.

                            However, I still need the info. The program could ask for it each and every time a user does something which needs the information, or the program could wait for such an event and cache the information, but are you able to recommend a Qt-approved way of doing something once when a.exec() is called?

                            Thanks.

                            jsulmJ 1 Reply Last reply
                            0
                            • Z zsd-

                              @Christian-Ehrlicher Thanks for the answer. I find this surprising, given that the w.show() causes an empty window frame to pop up on the monitor.

                              However, I still need the info. The program could ask for it each and every time a user does something which needs the information, or the program could wait for such an event and cache the information, but are you able to recommend a Qt-approved way of doing something once when a.exec() is called?

                              Thanks.

                              jsulmJ Offline
                              jsulmJ Offline
                              jsulm
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              @zsd said in QGuiApplication::primaryScreen() not telling me what I need to know:

                              Qt-approved way of doing something once when a.exec() is called?

                              Not sure what exactly your use case is, but what about QTimer?

                              https://forum.qt.io/topic/113070/qt-code-of-conduct

                              Z 1 Reply Last reply
                              0
                              • jsulmJ jsulm

                                @zsd said in QGuiApplication::primaryScreen() not telling me what I need to know:

                                Qt-approved way of doing something once when a.exec() is called?

                                Not sure what exactly your use case is, but what about QTimer?

                                Z Offline
                                Z Offline
                                zsd-
                                wrote on last edited by
                                #15

                                @jsulm Hmmm... that might work, although it strikes me as a bit kludgy (no offense intended). My "use case" is explained in my original message. Is that insufficient in some way? I can supply more information, but I'm not sure what would be relevant.

                                1 Reply Last reply
                                0
                                • Christian EhrlicherC Christian Ehrlicher

                                  @zsd said in QGuiApplication::primaryScreen() not telling me what I need to know:

                                  In other words (possibly!), how can I get Qt to really look and see which monitor the window is on before calling a.exec() ?

                                  You can't since even Qt does not know this.

                                  Z Offline
                                  Z Offline
                                  zsd-
                                  wrote on last edited by
                                  #16

                                  @Christian-Ehrlicher By the way... given that a.show() causes the window manager to open a window on the display, can you explain why you say that Qt doesn't know whicih monitor its window in on before a.exec() is called?
                                  Thanks.

                                  1 Reply Last reply
                                  0

                                  • Login

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