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. Get incorrect widget size by window handle
Forum Updated to NodeBB v4.3 + New Features

Get incorrect widget size by window handle

Scheduled Pinned Locked Moved Unsolved Qt for Python
13 Posts 3 Posters 1.6k 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.
  • T Offline
    T Offline
    Tim Tu
    wrote on last edited by
    #1

    1afdf306-af1b-492c-9db5-08e5a79579ee-image.png

    Test code:

    #!/usr/bin/python3
    import sys
    from PySide6 import QtCore
    from PySide6.QtWidgets import *
    from PySide6.QtGui import *
    from PySide6.QtCore import *
    
    
    class Example(QWidget):
        def __init__(self):
            super(Example, self).__init__()
            self.initUI()
    
        def initUI(self):
            self.setWindowFlags(Qt.FramelessWindowHint)
            self.setGeometry(300, 100, 300, 200)
            print(self.size())
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        window = Example()
        window.show()
        sys.exit(app.exec_())
    

    This problem only happen on PySide6 and PyQt6, there is no problem on PyQt5 and PySide2. So I think it's qt6's problem.
    801e7de0-9e1d-4ebf-b69c-1bf3f7c9c2d7-image.png

    1 Reply Last reply
    0
    • 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 Extensions
                            • Unsolved