Skip to content

QtInteractor Misalignment Issue After Maximizing and Toggling Visibility in Frameless PyQt5 Window #166

@PanagiotisMenounos

Description

@PanagiotisMenounos

Describe the bug
When using QtInteractor from pyvistaqt within a frameless window created with PyQt5, if the window is maximized and then hidden and shown again, the widget begins to misalign or shift from its original position.

Environment

  • OS: Windows 10
  • DPI scaling: 120%
  • Python: 3.8.0 64bit
  • PyQt5: 5.15.2

To Reproduce

  1. Maximaze the window
  2. Hide and show the window from taskbar a few times
CM4dRYvYfu.mp4

Code
requirements.txt:

PyQt5 
pyvista 
pyvistaqt
PyQt5-Frameless-Window

script:

# Minimum code to reproduce the error
import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget
import pyvista as pv
from pyvistaqt import QtInteractor

from qframelesswindow import FramelessWindow, StandardTitleBar
from qframelesswindow.windows.window_effect import WindowsWindowEffect
from qframelesswindow.utils.win32_utils import isCompositionEnabled
from ctypes import byref
from qframelesswindow.windows.c_structures import MARGINS


class WindowsWindowEffectEdit(WindowsWindowEffect):
    def __init__(self, window):
        # Call the parent class initializer
        super().__init__(window)

    def addShadowEffect(self, hWnd):
        if not isCompositionEnabled():
            return

        hWnd = int(hWnd)
        # set margins from -1 to 1 in order to solve backround color rendering in pyvista plot
        margins = MARGINS(1, 1, 1, 1)
        self.DwmExtendFrameIntoClientArea(hWnd, byref(margins))


class MainWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.layout = QVBoxLayout(self)
        self.interactor = QtInteractor(self)
        self.layout.addWidget(self.interactor)
        self.setLayout(self.layout)
        self.initialize_plot()

    def initialize_plot(self):
        sphere = pv.Sphere()
        self.interactor.add_mesh(sphere, color='orange')
        self.interactor.background_color = 'grey'  # Set the background color to grey
        self.interactor.show_bounds()


class Window(FramelessWindow):
    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.setTitleBar(StandardTitleBar(self))
        self.setWindowTitle('PyVistaQt Minimal Example')

        # Instantiate the subclass to override the effect
        self.windowEffect = WindowsWindowEffectEdit(self)  # Use the subclass here
        self.windowEffect.addShadowEffect(self.winId())  # This should call the overridden method

        self.setupLayout()

    def setupLayout(self):
        titleBarHeight = self.titleBar.sizeHint().height()
        self.layout = QVBoxLayout(self)
        self.layout.setContentsMargins(0, titleBarHeight, 0, 0)
        self.mainWidget = MainWidget(self)
        self.layout.addWidget(self.mainWidget)
        self.setLayout(self.layout)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    demo = Window()
    demo.show()
    sys.exit(app.exec_())

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions