Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Additional windows not opening on correct monitor
Qt 6.11 is out! See what's new in the release blog

Additional windows not opening on correct monitor

Scheduled Pinned Locked Moved Solved Qt for Python
22 Posts 5 Posters 17.0k 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #2

    Hi,

    The way you use QDesktopWidget is wrong. You should be using the QApplication instance to retrieve it.

    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
    0
    • F Offline
      F Offline
      fvez_demtroys
      wrote on last edited by
      #3

      Hi SGaist,

      Thanks for the precision and the quick reply. Mine will be a bit slower since I seem to have a 600 second limitation on my posts.
      I changed the function to :

      def initialPosition(self):
              geometry = self.frameGeometry()
              centerPoint = QApplication.desktop().availableGeometry().center()
              centerPoint.setY(self.mainWindow.pos().y())
              geometry.moveCenter(centerPoint)
              self.move(geometry.topLeft())
      

      This did not solve my issue, the additional windows are still opening on the wrong monitor.
      They are opening on the same monitor as PyCharm. It is as if the position obtained from the multiple different methods I posted all base themselves on the IDE rather than the actual MainWindow. Even when I get the actual MainWindow position.

      FVez

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

        Something is off. You should pass your widget to the availableGeometry call so that you get the geometry of the screen where the widget it located.

        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
        • F Offline
          F Offline
          fvez_demtroys
          wrote on last edited by
          #5

          Hi SGaist,

          We're getting there!
          With this function :

          def initialPosition(self):
              geometry = self.frameGeometry()
              centerPoint = QApplication.desktop().availableGeometry(self.mainWindow).center()
              centerPoint.setY(self.mainWindow.pos().y())
              geometry.moveCenter(centerPoint)
              self.move(geometry.topRight())
          

          The window now opens on the correct monitor!
          However, it doesn't if I don't use .topRight. I would prefer it to open top center.
          if I use the following line instead of the .topRight call shown above, it opens on the wrong monitor again.

          self.move(geometry.center().x(), geometry.top())
          

          Any idea why trying to center it changes the screen?

          Thanks!
          FVez

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

            I would check the values you get and the one you create to ensure you stay within the correct screen.

            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
            0
            • F Offline
              F Offline
              fvez_demtroys
              wrote on last edited by
              #7

              So for the function :

              def initialPosition(self):
                  geometry = self.frameGeometry()
                  centerPoint = QApplication.desktop().availableGeometry(self.mainWindow).center()
                  centerPoint.setY(self.mainWindow.pos().y())
                  geometry.moveCenter(centerPoint)
                  self.move(...)
              

              On geometry = self.frameGeometry(), geometry is QRect(0, 0, 900, 700)
              On centerPoint = QApplication.desktop().availableGeometry(self.mainWindow).center(), centerpoint is QPoint(408, -529)
              On centerPoint.setY(self.mainWindow.pos().y()), centerpoint is now QPoint(408, 0)
              On geometry.moveCenter(centerPoint), geometry is now QRect(-41, -349, 900, 700)

              With these two different approaches for the move action :

              self.move(geometry.center().x(), geometry.top())
              

              After this line, geometry is still QRect(-41, -349, 900, 700)
              geometry.center().x() returns 408
              geometry.top() returns -349

              self.move(geometry.topRight())
              

              After this line geometry is still QRect(-41, -349, 900, 700)
              geometry.topRight() returns QPoint(858, -349)

              From what I understand, in both lines the geometry object is the same, no? Why would the behaviour change?
              The Y value is the same in both instances, wouldn't this mean they should pop in the same screen?

              I am having a hard time understanding this issue, it really isn't behaving the way I am expecting.
              I would think they would appear on the same screen in both cases since the Y value is the same.

              Is there some hidden property with QRect that dictates on which screen the window is shown?

              Thanks,
              FVez

              1 Reply Last reply
              0
              • F Offline
                F Offline
                fvez_demtroys
                wrote on last edited by
                #8

                Overall it seems really inconsistent.
                I've been playing around changing screens and reopening the windows, the position is always a bit different.

                All I want is for the additional window to always open on top on my MainWindow.
                I want it to be centered on the X axis with the MainWindow and on the Y axis I want it to be at the same height as the MainWindow.
                This is desired for any type of screen, OS, etc. In all cases I always want them at the same relative position.

                Any idea how this can be achieved? I feel like the current solution is not quite what I'm looking for.

                Thanks,
                FVez

                1 Reply Last reply
                0
                • F Offline
                  F Offline
                  friedemannkleint
                  wrote on last edited by
                  #9

                  Please use QWidget.saveGeometry/restoreGeometry() to save geometries to QSettings. This will store the screen correctly.

                  Also, please use the QScreen class added in Qt 5 to retrieve the geometries. QWidget.screen() gives you the screen the widget is on. The windows should then be parented on the main window using the Qt.Window flag.

                  1 Reply Last reply
                  0
                  • F Offline
                    F Offline
                    fvez_demtroys
                    wrote on last edited by
                    #10

                    Hi Friedemannkleint,

                    I find using saveGeometry and restoreGeometry to cause some weird visual glitches on startup.
                    When the settings are restored the screen visibly shrinks to the right size and moves to the correct position.

                    Using move does not do this, the transition is instant, as I think it should be.

                    As for QWidget.screen(), I saw that this exists, however, there seems to be no way for me to set the screen once I have it.
                    I did not find any setScreen function.

                    Thanks,
                    FVez

                    1 Reply Last reply
                    0
                    • F Offline
                      F Offline
                      fvez_demtroys
                      wrote on last edited by
                      #11

                      Seems I have spoken too fast.
                      QWidget does have a setScreen function.

                      However this function is not present for QMainWindow.

                      JonBJ 1 Reply Last reply
                      0
                      • F fvez_demtroys

                        Seems I have spoken too fast.
                        QWidget does have a setScreen function.

                        However this function is not present for QMainWindow.

                        JonBJ Online
                        JonBJ Online
                        JonB
                        wrote on last edited by
                        #12

                        @fvez_demtroys
                        QMainWindow is derived from QWidget, so it must have all its methods....

                        jsulmJ 1 Reply Last reply
                        0
                        • F Offline
                          F Offline
                          fvez_demtroys
                          wrote on last edited by
                          #13

                          Hi JonB,

                          Here is my additional window.

                          class HelperWindow(QMainWindow):
                              def __init__(self, mainWindow):
                                  super().__init__()
                                  self.mainWindow = mainWindow
                                  self.setMinimumSize(900, 700)
                                  self.setWindowTitle('Helper')
                                  self.initialPosition()
                          
                              def initialPosition(self):
                                  geometry = self.frameGeometry()
                                  centerPoint = QApplication.desktop().availableGeometry(self.mainPage.mainWindow).center()
                                  centerPoint.setY(self.mainPage.tabWidget.y())
                                  geometry.moveCenter(centerPoint)
                                  self.move(geometry.topRight())
                                  self.setScreen(self.mainPage.mainWindow.screen())
                          

                          I get :
                          AttributeError: 'HelperWindow' object has no attribute 'setScreen'

                          Any idea if I have an error in my code?
                          It should inherit all methods from QMainWindow...

                          FVez

                          1 Reply Last reply
                          0
                          • JonBJ JonB

                            @fvez_demtroys
                            QMainWindow is derived from QWidget, so it must have all its methods....

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

                            @JonB I think setScreen is not present in Qt5 but in in Qt6

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

                            JonBJ 1 Reply Last reply
                            0
                            • F Offline
                              F Offline
                              fvez_demtroys
                              wrote on last edited by
                              #15

                              Is there no simple way to align both windows?
                              I want the top of the second window to be aligned with the top of the main window. Nothing more.

                              Thanks!
                              FVez

                              1 Reply Last reply
                              0
                              • F Offline
                                F Offline
                                fvez_demtroys
                                wrote on last edited by
                                #16

                                When I try to simply self.move(self.mainWindow.pos())
                                I get the following error.
                                qt.qpa.window: Window position QRect(0,-22 900x700) outside any known screen, using primary screen

                                Not sure why self.mainWindow.pos() returns a position outside the screen, I've been using only one monitor today to simplify the issue.

                                1 Reply Last reply
                                0
                                • jsulmJ jsulm

                                  @JonB I think setScreen is not present in Qt5 but in in Qt6

                                  JonBJ Online
                                  JonBJ Online
                                  JonB
                                  wrote on last edited by
                                  #17

                                  @jsulm said in Additional windows not opening on correct monitor:

                                  @JonB I think setScreen is not present in Qt5 but in in Qt6

                                  All I know is @fvez_demtroys wrote

                                  QWidget does have a setScreen function.

                                  However this function is not present for QMainWindow.

                                  I don't know whether Qt 5 or 6, I just don't see how QWidget can have a method which QMainWindow does not.

                                  1 Reply Last reply
                                  0
                                  • F Offline
                                    F Offline
                                    fvez_demtroys
                                    wrote on last edited by
                                    #18

                                    Hi JonB,

                                    As I mentioned in my original post, I am using PyQt5 5.15.4.
                                    PyQt5 documentation does not mention a setScreen function for the QWidget class.
                                    https://doc.qt.io/qt-5/qwidget.html

                                    FVez

                                    JonBJ 1 Reply Last reply
                                    0
                                    • F fvez_demtroys

                                      Hi JonB,

                                      As I mentioned in my original post, I am using PyQt5 5.15.4.
                                      PyQt5 documentation does not mention a setScreen function for the QWidget class.
                                      https://doc.qt.io/qt-5/qwidget.html

                                      FVez

                                      JonBJ Online
                                      JonBJ Online
                                      JonB
                                      wrote on last edited by
                                      #19

                                      @fvez_demtroys
                                      Earlier you wrote

                                      QWidget does have a setScreen function.

                                      but now you agree it does not. I was confused. Anyway @jsulm has explained it's only Qt6.

                                      1 Reply Last reply
                                      0
                                      • F Offline
                                        F Offline
                                        fvez_demtroys
                                        wrote on last edited by
                                        #20

                                        Hi JonB,

                                        Yes my error, I was looking at the PyQt6 Doc!
                                        Sorry for the confusion.

                                        I'm still having no luck in achieving what I want though.

                                        Is there no way to tell the new window to open at the same Y position as the main window and be centered on the main window?
                                        Could this issue be caused by the OSX environment?

                                        I don't understand why I can't use mainWindow.pos().y() and mainWindow.geometry().center().x() to properly display my new window where I want it to be...

                                        Thanks,
                                        FVez

                                        1 Reply Last reply
                                        0
                                        • F Offline
                                          F Offline
                                          fvez_demtroys
                                          wrote on last edited by
                                          #21

                                          For those interested, I got it to work.

                                          The main issue was that I was trying to set the position in the __init__ method of my widget.
                                          I changed my approach and decided to override the show() method of the widget.

                                          I think the initial position of my mainWindow wasn't correct when the __init__ method was called and thus my widget couldn't center properly.
                                          Here is the code for anyone interested in my solution.

                                              def show(self):
                                                  geo = self.frameGeometry()
                                                  geo.moveCenter(self.mainWindow.geometry().center())
                                                  geo.moveTop(self.mainWindow.geometry().top())
                                                  self.move(geo.topLeft())
                                                  super().show()
                                          

                                          Had to take a break to figure out what I was doing wrong.
                                          Thanks for the help!

                                          FVez

                                          1 Reply Last reply
                                          2

                                          • Login

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