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. Center a QMainWindow on the current screen
Forum Updated to NodeBB v4.3 + New Features

Center a QMainWindow on the current screen

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 2 Posters 5.5k 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.
  • Jonas KvingeJ Offline
    Jonas KvingeJ Offline
    Jonas Kvinge
    wrote on last edited by
    #1

    Hi
    When starting a second QMainWindow from the main application QMainWindow, it is not centered on the screen, the position of the window is actually randomly placed on the screen.
    Also, In some cases I want to use saveGeometry() and restoreGeometry() to save what screen the window is on, and the size, but I want to center it on the screen.
    Is there a simpler way of centering the window on the current screeen?
    The following code works, but I think it could be done much better.
    The first if checks if the window is not placed on the first screen.
    The else if handles cases where it's on the first screen and the coordinates are not negative.
    The else handles cases for Windows where the coordinates are negative.

    // Make the window center on the current screen.
    
    #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
      QScreen *screen = QWidget::screen();
    #else
      QScreen *screen = (window() && window()->windowHandle() ? window()->windowHandle()->screen() : nullptr);
    #endif
    
    if (screen) {
      int pos_x = 0;
      if (x() > screen->availableGeometry().width()) {
        pos_x = (screen->availableGeometry().width() / 2) - (frameGeometry().width() / 2) + (screen->availableVirtualSize().width() - screen->availableGeometry().width());
      }
      else if (x() >= -100) {
        pos_x = (screen->availableGeometry().width() / 2) - (frameGeometry().width() / 2);
      }
      else {
        pos_x = -((screen->availableGeometry().width() / 2) + (frameGeometry().width() / 2));
      }
      int pos_y = 0;
      if (y() > screen->availableGeometry().height()) {
        pos_y = (screen->availableGeometry().height() / 2) - (frameGeometry().height() / 2) + (screen->availableVirtualSize().height() - screen->availableGeometry().height());
      }
      else if (y() >= -100) {
        pos_y = (screen->availableGeometry().height() / 2) - (frameGeometry().height() / 2);
      }
      else {
        pos_y = -((screen->availableGeometry().height() / 2) + (frameGeometry().height() / 2));
      }
      move(pos_x, pos_y);
    }
    
    1 Reply Last reply
    0
    • Chris KawaC Online
      Chris KawaC Online
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by Chris Kawa
      #2

      I don't think you need to do it case by case and the -100 should rather be calculated half of the window size. You should probably also make sure the window is not larger than the screen.

      Anyway, here's a little function that will do it:

      void center(QWidget& w, const QScreen& s)
      {
          const QRect sr = s.availableGeometry();
          const QRect wr({}, w.frameSize().boundedTo(sr.size()));
      
          w.resize(wr.size());
          w.move(sr.center() - wr.center());
      }
      
      Jonas KvingeJ 1 Reply Last reply
      3
      • Chris KawaC Chris Kawa

        I don't think you need to do it case by case and the -100 should rather be calculated half of the window size. You should probably also make sure the window is not larger than the screen.

        Anyway, here's a little function that will do it:

        void center(QWidget& w, const QScreen& s)
        {
            const QRect sr = s.availableGeometry();
            const QRect wr({}, w.frameSize().boundedTo(sr.size()));
        
            w.resize(wr.size());
            w.move(sr.center() - wr.center());
        }
        
        Jonas KvingeJ Offline
        Jonas KvingeJ Offline
        Jonas Kvinge
        wrote on last edited by
        #3

        @Chris-Kawa
        This centers the window on the primary display instead of the current one.

        Chris KawaC 1 Reply Last reply
        0
        • Jonas KvingeJ Jonas Kvinge

          @Chris-Kawa
          This centers the window on the primary display instead of the current one.

          Chris KawaC Online
          Chris KawaC Online
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by Chris Kawa
          #4

          @Jonas-Kvinge What do you mean by "current" screen? There's no such thing as far as I know.

          This centers it on whichever screen you pass it in the s param.
          You can make it the one where center of the window is, its corner, where the cursor is or whatever you want. You can use the code you already had for choosing a screen or you can use something like QGuiApplication::screenAt() to peek a different one.

          Jonas KvingeJ 1 Reply Last reply
          2
          • Chris KawaC Chris Kawa

            @Jonas-Kvinge What do you mean by "current" screen? There's no such thing as far as I know.

            This centers it on whichever screen you pass it in the s param.
            You can make it the one where center of the window is, its corner, where the cursor is or whatever you want. You can use the code you already had for choosing a screen or you can use something like QGuiApplication::screenAt() to peek a different one.

            Jonas KvingeJ Offline
            Jonas KvingeJ Offline
            Jonas Kvinge
            wrote on last edited by
            #5

            @Chris-Kawa
            By current screen I'm talking about the screen where the program window is.
            For example I have two 1920x1080 monitors.
            move(0, 0) moves the window to the upper left corner of the primary screen.
            move(1920, 0) moves the window to the upper left corner of the second screen.
            Your code finds the center of availableGeometry() which always is the first screen.

            Chris KawaC 1 Reply Last reply
            0
            • Jonas KvingeJ Jonas Kvinge

              @Chris-Kawa
              By current screen I'm talking about the screen where the program window is.
              For example I have two 1920x1080 monitors.
              move(0, 0) moves the window to the upper left corner of the primary screen.
              move(1920, 0) moves the window to the upper left corner of the second screen.
              Your code finds the center of availableGeometry() which always is the first screen.

              Chris KawaC Online
              Chris KawaC Online
              Chris Kawa
              Lifetime Qt Champion
              wrote on last edited by Chris Kawa
              #6

              @Jonas-Kvinge said:

              Your code finds the center of availableGeometry() which always is the first screen.

              It's not. It's the center of available geometry on given screen.
              For example I have two monitors: 1920x1080 and 1920x1200 and what I get is:

              Screen 1:
              Rect:             QRect(0,0 1920x1080)
              Available:        QRect(0,0 1920x1040)
              Available center: QPoint(959,519)
              
              Screen 2:
              Rect:             QRect(1920,0 1920x1200)
              Available:        QRect(1920,0 1920x1160)
              Available center: QPoint(2879,579)
              

              By current screen I'm talking about the screen where the program window is.

              Which point of that window? A window can span multiple screens.

              Jonas KvingeJ 1 Reply Last reply
              0
              • Chris KawaC Chris Kawa

                @Jonas-Kvinge said:

                Your code finds the center of availableGeometry() which always is the first screen.

                It's not. It's the center of available geometry on given screen.
                For example I have two monitors: 1920x1080 and 1920x1200 and what I get is:

                Screen 1:
                Rect:             QRect(0,0 1920x1080)
                Available:        QRect(0,0 1920x1040)
                Available center: QPoint(959,519)
                
                Screen 2:
                Rect:             QRect(1920,0 1920x1200)
                Available:        QRect(1920,0 1920x1160)
                Available center: QPoint(2879,579)
                

                By current screen I'm talking about the screen where the program window is.

                Which point of that window? A window can span multiple screens.

                Jonas KvingeJ Offline
                Jonas KvingeJ Offline
                Jonas Kvinge
                wrote on last edited by Jonas Kvinge
                #7

                @Chris-Kawa
                What I meant to write is when using the calculated availableGeometry() one specific screen and using the center of that in move, it will move to the coordinates of the whole desktop, meaning the primary screen in my case.

                Which point of the window? I guess the middle? If the window is placed partly on one screen and partly on the other it's not really important to me. What is important is that it can be centered on a different screen than the primary if the whole window is placed there.

                Chris KawaC 1 Reply Last reply
                0
                • Jonas KvingeJ Jonas Kvinge

                  @Chris-Kawa
                  What I meant to write is when using the calculated availableGeometry() one specific screen and using the center of that in move, it will move to the coordinates of the whole desktop, meaning the primary screen in my case.

                  Which point of the window? I guess the middle? If the window is placed partly on one screen and partly on the other it's not really important to me. What is important is that it can be centered on a different screen than the primary if the whole window is placed there.

                  Chris KawaC Online
                  Chris KawaC Online
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on last edited by Chris Kawa
                  #8

                  @Jonas-Kvinge said:

                  What I meant to write is when using the calculated availableGeometry() one specific screen and using the center of that in move, it will move to the coordinates of the whole desktop, meaning the primary screen in my case.

                  Take a look at my numbers. availableGeometry() returns a rectangle in coordinates of the virtual desktop (a rectangle containing all screen geometries). If you use the second screen it's center is at (2879,578), which is on the second screen in the global coordinates. Moving a window there with move() will place it on that second screen.

                  If your window is placed always on the primary screen you must be passing the wrong screen to that center() function I posted, because it works for any screen, not just the primary.

                  Jonas KvingeJ 1 Reply Last reply
                  1
                  • Chris KawaC Chris Kawa

                    @Jonas-Kvinge said:

                    What I meant to write is when using the calculated availableGeometry() one specific screen and using the center of that in move, it will move to the coordinates of the whole desktop, meaning the primary screen in my case.

                    Take a look at my numbers. availableGeometry() returns a rectangle in coordinates of the virtual desktop (a rectangle containing all screen geometries). If you use the second screen it's center is at (2879,578), which is on the second screen in the global coordinates. Moving a window there with move() will place it on that second screen.

                    If your window is placed always on the primary screen you must be passing the wrong screen to that center() function I posted, because it works for any screen, not just the primary.

                    Jonas KvingeJ Offline
                    Jonas KvingeJ Offline
                    Jonas Kvinge
                    wrote on last edited by
                    #9

                    @Chris-Kawa Sorry, I see that now, your using QPoint().
                    I see now that my problem is that QWidget::screen() is returning the same screen independent of what screen the QMainWindow is actually placed.

                    1 Reply Last reply
                    0
                    • Jonas KvingeJ Offline
                      Jonas KvingeJ Offline
                      Jonas Kvinge
                      wrote on last edited by
                      #10

                      @Chris-Kawa said in Center a QMainWindow on the current screen:

                      QGuiApplication::screenAt()

                      Using QGuiApplication::screenAt() instead works.
                      Solved now. 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