Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Get incorrect widget size by window handle
Qt 6.11 is out! See what's new in the release blog

Get incorrect widget size by window handle

Scheduled Pinned Locked Moved Unsolved Qt for Python
13 Posts 3 Posters 4.9k 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.
  • Axel SpoerlA Offline
    Axel SpoerlA Offline
    Axel Spoerl
    Moderators
    wrote on last edited by
    #2

    Hi,

    without seeing any relevant code, this answer is based on two assumptions:

    • the window system is Wayland (because xwininfo is used)
    • by "window handle", you mean QWidget::windowHandle() (not QWindow::handle(), which returns a QPlatformWindow * )

    FramlessWindowHintproduces a borderless window, if supported by the window manager. There's no guarantee, however. QWindow::geometry()returns the window geometry exclusive of its frame (both in Qt 5 and Qt 6). The handling of window decorations has changed in the Qt Wayland implementation from Qt 5 to Qt 6. Without having any information about the Wayland configuration at hand, I can only suspect that a native window decoration is rendered regardless of the FramelessWindowHint. Probably because it would not be possible to close/resize the window otherwise. The difference of 13/8 pixels represents the window decoration.
    You can figure that out by calling QPlatformWindow::frameMargins().

    Cheers
    Axel

    Software Engineer
    The Qt Company, Oslo

    T 1 Reply Last reply
    2
    • Axel SpoerlA Axel Spoerl

      Hi,

      without seeing any relevant code, this answer is based on two assumptions:

      • the window system is Wayland (because xwininfo is used)
      • by "window handle", you mean QWidget::windowHandle() (not QWindow::handle(), which returns a QPlatformWindow * )

      FramlessWindowHintproduces a borderless window, if supported by the window manager. There's no guarantee, however. QWindow::geometry()returns the window geometry exclusive of its frame (both in Qt 5 and Qt 6). The handling of window decorations has changed in the Qt Wayland implementation from Qt 5 to Qt 6. Without having any information about the Wayland configuration at hand, I can only suspect that a native window decoration is rendered regardless of the FramelessWindowHint. Probably because it would not be possible to close/resize the window otherwise. The difference of 13/8 pixels represents the window decoration.
      You can figure that out by calling QPlatformWindow::frameMargins().

      Cheers
      Axel

      T Offline
      T Offline
      Tim Tu
      wrote on last edited by
      #3

      Thanks for your reply.
      I think I should give you a specific example.

      import os
      import sys
      from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox
      
      from PySide6.QtWidgets import (
          QApplication,
          QMainWindow
      )
      
      from OCC.Display.backend import load_backend
      
      load_backend("qt-pyside6")
      import OCC.Display.qtDisplay as qtDisplay
      
      
      class App(QMainWindow):
          def __init__(self):
              super().__init__()
              self.title = "PyQt5 / pythonOCC"
              self.left = 300
              self.top = 300
              self.width = 800
              self.height = 300
              self.initUI()
      
          def initUI(self):
              self.setWindowTitle(self.title)
              self.setGeometry(self.left, self.top, self.width, self.height)
              self.canvas = qtDisplay.qtViewer3d(self)
              self.setCentralWidget(self.canvas)
              self.canvas.InitDriver()
              self.display = self.canvas._display
              a_box = BRepPrimAPI_MakeBox(10.0, 20.0, 30.0).Shape()
              self.ais_box = self.display.DisplayShape(a_box)[0]
              self.display.FitAll()
              self.show()
              self.canvas.InitDriver()
              print(self.size())
              
      
      if __name__ == "__main__":
          app = QApplication(sys.argv)
          ex = App()
          sys.exit(app.exec_())
      

      (If you want to try this example, please install pythonocc-core conda install pythonocc-core)
      PythonOCC depends on window handle to display in qt window.
      547c3575-5e85-45d8-b958-9e20ddb1d59f-图片.png
      It causes so issues.

      Axel SpoerlA 1 Reply Last reply
      0
      • T Tim Tu

        Thanks for your reply.
        I think I should give you a specific example.

        import os
        import sys
        from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox
        
        from PySide6.QtWidgets import (
            QApplication,
            QMainWindow
        )
        
        from OCC.Display.backend import load_backend
        
        load_backend("qt-pyside6")
        import OCC.Display.qtDisplay as qtDisplay
        
        
        class App(QMainWindow):
            def __init__(self):
                super().__init__()
                self.title = "PyQt5 / pythonOCC"
                self.left = 300
                self.top = 300
                self.width = 800
                self.height = 300
                self.initUI()
        
            def initUI(self):
                self.setWindowTitle(self.title)
                self.setGeometry(self.left, self.top, self.width, self.height)
                self.canvas = qtDisplay.qtViewer3d(self)
                self.setCentralWidget(self.canvas)
                self.canvas.InitDriver()
                self.display = self.canvas._display
                a_box = BRepPrimAPI_MakeBox(10.0, 20.0, 30.0).Shape()
                self.ais_box = self.display.DisplayShape(a_box)[0]
                self.display.FitAll()
                self.show()
                self.canvas.InitDriver()
                print(self.size())
                
        
        if __name__ == "__main__":
            app = QApplication(sys.argv)
            ex = App()
            sys.exit(app.exec_())
        

        (If you want to try this example, please install pythonocc-core conda install pythonocc-core)
        PythonOCC depends on window handle to display in qt window.
        547c3575-5e85-45d8-b958-9e20ddb1d59f-图片.png
        It causes so issues.

        Axel SpoerlA Offline
        Axel SpoerlA Offline
        Axel Spoerl
        Moderators
        wrote on last edited by
        #4

        @Tim-Tu
        What's is returned by yourWidget->windowHandle()->handle()->frameMargins()?

        Software Engineer
        The Qt Company, Oslo

        T 1 Reply Last reply
        0
        • Axel SpoerlA Axel Spoerl

          @Tim-Tu
          What's is returned by yourWidget->windowHandle()->handle()->frameMargins()?

          T Offline
          T Offline
          Tim Tu
          wrote on last edited by
          #5

          @Axel-Spoerl

          @Axel-Spoerl said in Get incorrect widget size by window handle:

          What's is returned by yourWidget->windowHandle()->handle()->frameMargins()?

          There is some thing wrong:

              print(self.windowHandle().Handle())
          AttributeError: 'PySide6.QtGui.QWindow' object has no attribute 'Handle'
          

          Did you means contentsMargins?
          I have changed the test code:

          ##Author github user @Tanneguydv, 2021
          
          import os
          import sys
          from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox
          
          from PySide6.QtWidgets import (
              QApplication,
              QWidget,
              QVBoxLayout
          )
          
          from OCC.Display.backend import load_backend
          
          load_backend("qt-pyside6")
          import OCC.Display.qtDisplay as qtDisplay
          
          
          class App(QWidget):
              def __init__(self):
                  super().__init__()
                  self.title = "PyQt5 / pythonOCC"
                  self.left = 300
                  self.top = 300
                  self.width = 800
                  self.height = 300
                  self.initUI()
          
              def initUI(self):
                  self.setWindowTitle(self.title)
                  self.setGeometry(self.left, self.top, self.width, self.height)
                  self.lay = QVBoxLayout()
                  self.setLayout(self.lay)
          
                  self.canvas = qtDisplay.qtViewer3d(self)
                  self.lay.addWidget(self.canvas)
                  self.canvas.InitDriver()
                  self.display = self.canvas._display
          
                  a_box = BRepPrimAPI_MakeBox(10.0, 20.0, 30.0).Shape()
                  self.ais_box = self.display.DisplayShape(a_box)[0]
                  self.display.FitAll()
                  
                  self.show()
                  self.canvas.InitDriver()
          
                  print(self.size())
                  print(self.canvas.size())
                  print(self.contentsMargins())
                  print(self.canvas.contentsMargins())
          
          if __name__ == "__main__":
              app = QApplication(sys.argv)
              ex = App()
              sys.exit(app.exec_())
          

          The result:

          Xw_Window created.
          Display3d class successfully initialized.
          #########################################
          OpenGl information:
            GLvendor: AMD
            GLdevice: AMD Radeon Graphics (rembrandt, LLVM 15.0.7, DRM 3.52, 6.4.8-arch1-1)
            GLversion: 4.6 (Compatibility Profile) Mesa 23.1.5
            GLSLversion: 4.60
            Max texture size: 16384
            Max FBO dump size: 16384x16384
            Max combined texture units: 192
            Max MSAA samples: 8
            Viewport: 810x290
            Window buffer: RGB8 ALPHA8 DEPTH24 STENCIL8
            ResolutionRatio: 1
            FBO buffer: GL_SRGB8_ALPHA8 GL_DEPTH24_STENCIL8
          PySide6.QtCore.QSize(800, 300)
          PySide6.QtCore.QSize(778, 278)
          <PySide6.QtCore.QMargins(0, 0, 0, 0) at 0x7f5581c95ec0>
          <PySide6.QtCore.QMargins(0, 0, 0, 0) at 0x7f5581c95ec0>
          
          Axel SpoerlA 1 Reply Last reply
          0
          • T Tim Tu

            @Axel-Spoerl

            @Axel-Spoerl said in Get incorrect widget size by window handle:

            What's is returned by yourWidget->windowHandle()->handle()->frameMargins()?

            There is some thing wrong:

                print(self.windowHandle().Handle())
            AttributeError: 'PySide6.QtGui.QWindow' object has no attribute 'Handle'
            

            Did you means contentsMargins?
            I have changed the test code:

            ##Author github user @Tanneguydv, 2021
            
            import os
            import sys
            from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox
            
            from PySide6.QtWidgets import (
                QApplication,
                QWidget,
                QVBoxLayout
            )
            
            from OCC.Display.backend import load_backend
            
            load_backend("qt-pyside6")
            import OCC.Display.qtDisplay as qtDisplay
            
            
            class App(QWidget):
                def __init__(self):
                    super().__init__()
                    self.title = "PyQt5 / pythonOCC"
                    self.left = 300
                    self.top = 300
                    self.width = 800
                    self.height = 300
                    self.initUI()
            
                def initUI(self):
                    self.setWindowTitle(self.title)
                    self.setGeometry(self.left, self.top, self.width, self.height)
                    self.lay = QVBoxLayout()
                    self.setLayout(self.lay)
            
                    self.canvas = qtDisplay.qtViewer3d(self)
                    self.lay.addWidget(self.canvas)
                    self.canvas.InitDriver()
                    self.display = self.canvas._display
            
                    a_box = BRepPrimAPI_MakeBox(10.0, 20.0, 30.0).Shape()
                    self.ais_box = self.display.DisplayShape(a_box)[0]
                    self.display.FitAll()
                    
                    self.show()
                    self.canvas.InitDriver()
            
                    print(self.size())
                    print(self.canvas.size())
                    print(self.contentsMargins())
                    print(self.canvas.contentsMargins())
            
            if __name__ == "__main__":
                app = QApplication(sys.argv)
                ex = App()
                sys.exit(app.exec_())
            

            The result:

            Xw_Window created.
            Display3d class successfully initialized.
            #########################################
            OpenGl information:
              GLvendor: AMD
              GLdevice: AMD Radeon Graphics (rembrandt, LLVM 15.0.7, DRM 3.52, 6.4.8-arch1-1)
              GLversion: 4.6 (Compatibility Profile) Mesa 23.1.5
              GLSLversion: 4.60
              Max texture size: 16384
              Max FBO dump size: 16384x16384
              Max combined texture units: 192
              Max MSAA samples: 8
              Viewport: 810x290
              Window buffer: RGB8 ALPHA8 DEPTH24 STENCIL8
              ResolutionRatio: 1
              FBO buffer: GL_SRGB8_ALPHA8 GL_DEPTH24_STENCIL8
            PySide6.QtCore.QSize(800, 300)
            PySide6.QtCore.QSize(778, 278)
            <PySide6.QtCore.QMargins(0, 0, 0, 0) at 0x7f5581c95ec0>
            <PySide6.QtCore.QMargins(0, 0, 0, 0) at 0x7f5581c95ec0>
            
            Axel SpoerlA Offline
            Axel SpoerlA Offline
            Axel Spoerl
            Moderators
            wrote on last edited by
            #6

            There is some thing wrong:
            print(self.windowHandle().Handle())
            AttributeError: 'PySide6.QtGui.QWindow' object has no attribute 'Handle'

            handle(), not Handle().

            Software Engineer
            The Qt Company, Oslo

            T JonBJ 2 Replies Last reply
            0
            • Axel SpoerlA Axel Spoerl

              There is some thing wrong:
              print(self.windowHandle().Handle())
              AttributeError: 'PySide6.QtGui.QWindow' object has no attribute 'Handle'

              handle(), not Handle().

              T Offline
              T Offline
              Tim Tu
              wrote on last edited by
              #7

              @Axel-Spoerl
              Sorry, but there still has no attribute

                  print(self.windowHandle().handle())
              AttributeError: 'PySide6.QtGui.QWindow' object has no attribute 'handle'
              
              1 Reply Last reply
              0
              • Axel SpoerlA Axel Spoerl

                There is some thing wrong:
                print(self.windowHandle().Handle())
                AttributeError: 'PySide6.QtGui.QWindow' object has no attribute 'Handle'

                handle(), not Handle().

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #8

                @Axel-Spoerl
                QWindow Class shows no sign of a (public at least, from C++, let alone Python) handle() method?

                Axel SpoerlA 1 Reply Last reply
                0
                • JonBJ JonB

                  @Axel-Spoerl
                  QWindow Class shows no sign of a (public at least, from C++, let alone Python) handle() method?

                  Axel SpoerlA Offline
                  Axel SpoerlA Offline
                  Axel Spoerl
                  Moderators
                  wrote on last edited by Axel Spoerl
                  #9

                  @JonB
                  Hm, qwindow.cpp:2050-2070:

                  /*!
                      Returns the platform window corresponding to the window.
                  
                      \internal
                  */
                  QPlatformWindow *QWindow::handle() const
                  {
                      Q_D(const QWindow);
                      return d->platformWindow;
                  }
                  

                  But...wait: It's a public method, documented as internal. That's why it doesn't show up in the documentation and maybe also not in python.

                  Software Engineer
                  The Qt Company, Oslo

                  JonBJ 1 Reply Last reply
                  0
                  • Axel SpoerlA Axel Spoerl

                    @JonB
                    Hm, qwindow.cpp:2050-2070:

                    /*!
                        Returns the platform window corresponding to the window.
                    
                        \internal
                    */
                    QPlatformWindow *QWindow::handle() const
                    {
                        Q_D(const QWindow);
                        return d->platformWindow;
                    }
                    

                    But...wait: It's a public method, documented as internal. That's why it doesn't show up in the documentation and maybe also not in python.

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #10

                    @Axel-Spoerl
                    :) And is it public? If so, either it's not documented, or maybe because of that it didn't get added into PySide/PyQt (since the OP shows it not working from Python)? The comment shows \internal....

                    And it returns a QPlatformWindow, which does not seem to be documented either, so maybe that's why it's not provided?? [It seems to have been mentioned in Qt 4.8 but not since then? :) ]

                    Axel SpoerlA 1 Reply Last reply
                    1
                    • JonBJ JonB

                      @Axel-Spoerl
                      :) And is it public? If so, either it's not documented, or maybe because of that it didn't get added into PySide/PyQt (since the OP shows it not working from Python)? The comment shows \internal....

                      And it returns a QPlatformWindow, which does not seem to be documented either, so maybe that's why it's not provided?? [It seems to have been mentioned in Qt 4.8 but not since then? :) ]

                      Axel SpoerlA Offline
                      Axel SpoerlA Offline
                      Axel Spoerl
                      Moderators
                      wrote on last edited by
                      #11

                      @JonB
                      Messages crossed ;-)
                      It's indeed public.
                      QPlatformWindow also isn't documented and probably not available in PySide/PyQt.
                      Thanks, Jon, for the hint.

                      Software Engineer
                      The Qt Company, Oslo

                      JonBJ Axel SpoerlA 2 Replies Last reply
                      0
                      • Axel SpoerlA Axel Spoerl

                        @JonB
                        Messages crossed ;-)
                        It's indeed public.
                        QPlatformWindow also isn't documented and probably not available in PySide/PyQt.
                        Thanks, Jon, for the hint.

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

                        @Axel-Spoerl said in Get incorrect widget size by window handle:

                        It's indeed public.

                        I just added to my previous: The comment shows \internal....

                        1 Reply Last reply
                        1
                        • Axel SpoerlA Axel Spoerl

                          @JonB
                          Messages crossed ;-)
                          It's indeed public.
                          QPlatformWindow also isn't documented and probably not available in PySide/PyQt.
                          Thanks, Jon, for the hint.

                          Axel SpoerlA Offline
                          Axel SpoerlA Offline
                          Axel Spoerl
                          Moderators
                          wrote on last edited by
                          #13

                          Nontheless, to conclude this thread somehow:
                          FramlessWindowHintis a hint and doesn't guarantee that window is really rendered frameless.
                          Native handles seem to get rendered in the case at hand. The pixel difference represents their size.
                          Given that my proposed way to confirm it doesn't work out in Python, looking at the physical window on the screen is the only way to confirm.

                          Software Engineer
                          The Qt Company, Oslo

                          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
                          • Unsolved