(PyQt Multi-Head Manjaro) 调整大小和重叠 2 个屏幕时的非命令移动事件

问题描述 投票:0回答:0

我正在使用 Manjaro(Arch) 和 3 个头 (3x1),我遇到了 PyQT 的问题。

我正在构建一个模块化应用程序,用户应该能够在其中将窗口调整为他们喜欢的任何可用大小。

然而,当一个窗口与两个屏幕重叠并调整大小(setGeometry()/resize())时,它会捕捉到它最覆盖的屏幕的 X 轴 0 坐标。

然而,这种行为似乎只发生在一些 sizegrips 上,我用#Affected # 标记了它们。

我偶然发现了一个临时修复程序(不要问我它是如何工作的),我已将其包含在受影响的 sizegrips 中,它们被标记为#Workaround #。

这是一个最小的例子,我不得不删掉一堆东西,如果它不完美,我们深表歉意:

import sys
import time

from PyQt6.QtCore import *
from PyQt6.QtWidgets import *
from PyQt6.QtGui import *

# Helpers #
def GridSnap(Value=int):

    ScreenHeight = 1440
    Divider = 36 # 36
    Step = ScreenHeight/Divider
    Value = int(Step*round(Value/Step))

    return Value

class Container(QFrame):
    def __init__(self,Parent):
        super().__init__()

        # Variables #
        self.Parent = Parent

        # Container #
        self.setSizePolicy(QSizePolicy.Policy.Expanding,QSizePolicy.Policy.Expanding)

        # Style #
        self.setStyleSheet(
            'Container { '
                'background-color:blue; }')

    def mousePressEvent(self,event):

        if event.button() == Qt.MouseButton.LeftButton:

            Event = event
            EventX = GridSnap(Event.globalPosition().x())
            EventY = GridSnap(Event.globalPosition().y())
            EventPos = QPoint(EventX,EventY)

            self.StartPos = EventPos

    def mouseDoubleClickEvent(self,event):

        if event.button() == Qt.MouseButton.LeftButton:

            self.window().MaximizeNormal()

    def mouseMoveEvent(self,event):

        Window = self.window()
        WindowX = GridSnap(Window.pos().x())
        WindowY = GridSnap(Window.pos().y())
        WindowPos = QPoint(WindowX,WindowY)
        WindowWidth = GridSnap(Window.width())
        WindowHeight = GridSnap(Window.height())

        Cursor = QCursor
        CursorX = GridSnap(Cursor.pos().x())
        CursorY = GridSnap(Cursor.pos().y())
        CursorPos = QPoint(CursorX,CursorY)

        Screens = Application.screens()
        DesktopWidth = sum([Screen.geometry().width() for Screen in Screens])
        DesktopHeight = max([Screen.geometry().height() for Screen in Screens])

        StartX = GridSnap(self.StartPos.x())
        StartY = GridSnap(self.StartPos.y())

        DeltaX = CursorX-StartX
        DeltaY = CursorY-StartY

        # X #
        if (WindowX+WindowWidth)+DeltaX > DesktopWidth\
        or WindowX+DeltaX < 0:
            NewX = WindowX
        else:
            NewX = WindowX+DeltaX

        # Y #
        if (WindowY+WindowHeight)+DeltaY > DesktopHeight\
        or WindowY+DeltaY < 0:
            NewY = WindowY
        else:
            NewY = WindowY+DeltaY

        # Window #
        if (WindowX,WindowY) == (NewX,NewY):
            return
        else:
            Window.move(NewX,NewY)
            time.sleep(0.009)
            self.StartPos = QPoint(CursorX,CursorY)

# Level 03 #
class Window(QFrame):
    def __init__(self,Parent):
        super().__init__()

        # Variables #
        self.Parent = Parent
        self.IContainer = Container(self)

        # Window #
        self.setWindowTitle('Phantom Move')
        self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
        self.setMinimumWidth(GridSnap(720))
        self.setMinimumHeight(GridSnap(480))

        class NorthWest(QSizeGrip):
            def __init__(self,Window,Parent):
                super().__init__(Window)

                # Variables #
                self.Parent = Parent

                # NorthWest #
                self.setSizePolicy(QSizePolicy.Policy.Fixed,QSizePolicy.Policy.Fixed)
                self.setFixedWidth(4)
                self.setFixedHeight(4)

                # Style #
                self.setStyleSheet('NorthWest { '
                    'background-color:red; }')

            def mouseMoveEvent(self,event):

                Window = self.window()
                WindowX = GridSnap(Window.pos().x())
                WindowY = GridSnap(Window.pos().y())
                WindowPos = QPoint(WindowX,WindowY)
                WindowWidth = GridSnap(Window.width())
                WindowHeight = GridSnap(Window.height())
                WindowMinWidth = GridSnap(Window.minimumWidth())
                WindowMinHeight = GridSnap(Window.minimumHeight())

                Cursor = QCursor
                CursorX = GridSnap(Cursor.pos().x())
                CursorY = GridSnap(Cursor.pos().y())
                CursorPos = QPoint(CursorX,CursorY)

                GripPos = QPoint(WindowX,WindowY)
                GripX = GripPos.x()
                GripY = GripPos.y()

                DeltaX = GripX-CursorX
                DeltaY = GripY-CursorY

                # X #
                if WindowWidth+DeltaX < WindowMinWidth:
                    NewX = WindowX
                    NewWidth = WindowWidth
                else:
                    NewX = CursorX
                    NewWidth = WindowWidth+DeltaX

                # Y #
                if WindowHeight+DeltaY < WindowMinHeight:
                    NewY = WindowY
                    NewHeight = WindowHeight
                else:
                    NewY = CursorY
                    NewHeight = WindowHeight+DeltaY

                # Window #
                if (WindowX,WindowY,WindowWidth,WindowHeight) == (NewX,NewY,NewWidth,NewHeight):
                    return
                else:
                    #Window.setGeometry(NewX+1,NewY+1,NewWidth,NewHeight)
                    #time.sleep(0.009)
                    Window.setGeometry(NewX,NewY,NewWidth,NewHeight)
                    time.sleep(0.009)

        self.INorthWest = NorthWest(self,self)

        class North(QSizeGrip):
            def __init__(self,Window,Parent):
                super().__init__(Window)

                # Variables #
                self.Parent = Parent

                # North #
                self.setSizePolicy(QSizePolicy.Policy.Expanding,QSizePolicy.Policy.Fixed)
                self.setFixedHeight(4)

                # Style #
                self.setStyleSheet('North { '
                    'background-color:#0d0e0f; }')

            def paintEvent(self,event):

                QSizeGrip.paintEvent(self,event)
                self.setCursor(Qt.CursorShape.SizeVerCursor)
                self.setStyleSheet('North { '
                    'background-color:orange; }')

            def mouseMoveEvent(self,event):

                Window = self.window()
                WindowX = GridSnap(Window.pos().x())
                WindowY = GridSnap(Window.pos().y())
                WindowPos = QPoint(WindowX,WindowY)
                WindowWidth = GridSnap(Window.width())
                WindowHeight = GridSnap(Window.height())
                WindowMinHeight = GridSnap(Window.minimumHeight())

                Cursor = QCursor
                CursorY = GridSnap(Cursor.pos().y())

                GripY = WindowY

                DeltaY = GripY-CursorY

                # X #
                NewX = WindowX
                NewWidth = WindowWidth

                # Y #
                if WindowHeight+DeltaY < WindowMinHeight:
                    return
                else:
                    NewY = WindowY-DeltaY
                    NewHeight = WindowHeight+DeltaY

                # Window #
                if (WindowX,WindowY,WindowWidth,WindowHeight) == (NewX,NewY,NewWidth,NewHeight):
                    return
                else:
                    #Window.setGeometry(NewX+1,NewY+1,NewWidth,NewHeight)
                    #time.sleep(0.009)
                    Window.setGeometry(NewX,NewY,NewWidth,NewHeight)
                    time.sleep(0.009)

        self.INorth = North(self,self)

        class NorthEast(QSizeGrip): # Affected #
            def __init__(self,Window,Parent):
                super().__init__(Window)

                # Variables #
                self.Parent = Parent

                # NorthEast #
                self.setSizePolicy(QSizePolicy.Policy.Fixed,QSizePolicy.Policy.Fixed)
                self.setFixedWidth(4)
                self.setFixedHeight(4)

                # Style #
                self.setStyleSheet('NorthEast { '
                    'background-color:red; }')

            def mouseMoveEvent(self,event):

                Window = self.window()
                WindowX = GridSnap(Window.pos().x())
                WindowY = GridSnap(Window.pos().y())
                WindowPos = QPoint(WindowX,WindowY)
                WindowWidth = GridSnap(Window.width())
                WindowHeight = GridSnap(Window.height())
                WindowMinWidth = GridSnap(Window.minimumWidth())
                WindowMinHeight = GridSnap(Window.minimumHeight())

                Cursor = QCursor
                CursorX = GridSnap(Cursor.pos().x())
                CursorY = GridSnap(Cursor.pos().y())
                CursorPos = QPoint(CursorX,CursorY)

                GripPos = QPoint(WindowX+WindowWidth,WindowY)
                GripX = GripPos.x()
                GripY = GripPos.y()

                DeltaX = CursorX-GripX
                DeltaY = CursorY-GripY

                # X #
                if WindowWidth+DeltaX < WindowMinWidth:
                    NewX = WindowX
                    NewWidth = WindowWidth
                else:
                    NewX = WindowX
                    NewWidth = WindowWidth+DeltaX

                # Y #
                if WindowHeight-DeltaY < WindowMinHeight:
                    NewY = WindowY
                    NewHeight = WindowHeight
                else:
                    NewY = CursorY
                    NewHeight = WindowHeight-DeltaY

                # Window #
                if (WindowX,WindowY,WindowWidth,WindowHeight) == (NewX,NewY,NewWidth,NewHeight):
                    return
                else:
                    #Window.setGeometry(NewX+1,NewY+1,NewWidth,NewHeight) # Workaround #
                    #time.sleep(0.009)
                    Window.setGeometry(NewX,NewY,NewWidth,NewHeight)
                    time.sleep(0.009)

        self.INorthEast = NorthEast(self,self)

        class East(QSizeGrip): # Affected #
            def __init__(self,Window,Parent):
                super().__init__(Window)

                # Variables #
                self.Parent = Parent

                # East #
                self.setSizePolicy(QSizePolicy.Policy.Fixed,QSizePolicy.Policy.Expanding)
                self.setFixedWidth(4)

                # Style #
                self.setStyleSheet('East { '
                    'background-color:orange; }')

            def paintEvent(self,event):

                QSizeGrip.paintEvent(self,event)
                self.setCursor(Qt.CursorShape.SizeHorCursor)
                self.setStyleSheet('East { '
                    'background-color:orange; }')

            def mouseMoveEvent(self,event):

                Window = self.window()
                WindowX = GridSnap(Window.pos().x())
                WindowY = GridSnap(Window.pos().y())
                WindowPos = QPoint(WindowX,WindowY)
                WindowWidth = GridSnap(Window.width())
                WindowHeight = GridSnap(Window.height())
                WindowMinWidth = GridSnap(Window.minimumWidth())

                Cursor = QCursor
                CursorX = GridSnap(Cursor.pos().x())

                GripX = WindowX+WindowWidth

                DeltaX = GripX-CursorX

                # X #
                if WindowWidth-DeltaX < WindowMinWidth:
                    return
                else:
                    NewX = WindowX
                    NewWidth = WindowWidth-DeltaX

                # Y #
                NewY = WindowY
                NewHeight = WindowHeight

                # Window #
                if (WindowX,WindowY,WindowWidth,WindowHeight) == (NewX,NewY,NewWidth,NewHeight):
                    return
                else:
                    #Window.setGeometry(NewX+1,NewY+1,NewWidth,NewHeight) # Workaround #
                    #time.sleep(0.009)
                    Window.setGeometry(NewX,NewY,NewWidth,NewHeight)
                    time.sleep(0.009)

        self.IEast = East(self,self)

        class SouthEast(QSizeGrip): # Affected #
            def __init__(self,Window,Parent):
                super().__init__(Window)

                # Variables #
                self.Parent = Parent

                # SouthEast #
                self.setSizePolicy(QSizePolicy.Policy.Fixed,QSizePolicy.Policy.Fixed)
                self.setFixedWidth(4)
                self.setFixedHeight(4)

                # Style #
                self.setStyleSheet('SouthEast { '
                    'background-color:red; }')

            def mouseMoveEvent(self,event):

                Window = self.window()
                WindowX = GridSnap(Window.pos().x())
                WindowY = GridSnap(Window.pos().y())
                WindowPos = QPoint(WindowX,WindowY)
                WindowWidth = GridSnap(Window.width())
                WindowHeight = GridSnap(Window.height())
                WindowMinWidth = GridSnap(Window.minimumWidth())
                WindowMinHeight = GridSnap(Window.minimumHeight())

                Cursor = QCursor
                CursorX = GridSnap(Cursor.pos().x())
                CursorY = GridSnap(Cursor.pos().y())
                CursorPos = QPoint(CursorX,CursorY)

                GripPos = QPoint(WindowX+WindowWidth,WindowY+WindowHeight)
                GripX = GripPos.x()
                GripY = GripPos.y()

                DeltaX = GripX-CursorX
                DeltaY = GripY-CursorY

                # X #
                if WindowWidth-DeltaX < WindowMinWidth:
                    NewX = WindowX
                    NewWidth = WindowWidth
                else:
                    NewX = WindowX
                    NewWidth = WindowWidth-DeltaX

                # Y #
                if WindowHeight-DeltaY < WindowMinHeight:
                    NewY = WindowY
                    NewHeight = WindowHeight
                else:
                    NewY = WindowY
                    NewHeight = WindowHeight-DeltaY

                # Window #
                if (WindowX,WindowY,WindowWidth,WindowHeight) == (NewX,NewY,NewWidth,NewHeight):
                    return
                else:
                    #Window.setGeometry(NewX+1,NewY+1,NewWidth,NewHeight) # Workaround #
                    #time.sleep(0.009)
                    Window.setGeometry(NewX,NewY,NewWidth,NewHeight)
                    time.sleep(0.009)

        self.ISouthEast = SouthEast(self,self)

        class South(QSizeGrip): # Affected #
            def __init__(self,Window,Parent):
                super().__init__(Window)

                # Variables #
                self.Parent = Parent

                # South #
                self.setSizePolicy(QSizePolicy.Policy.Expanding,QSizePolicy.Policy.Fixed)
                self.setFixedHeight(4)

                # Style #
                self.setStyleSheet('South { '
                    'background-color:orange; }')

            def paintEvent(self,event):

                QSizeGrip.paintEvent(self,event)
                self.setCursor(Qt.CursorShape.SizeVerCursor)
                self.setStyleSheet('South { '
                    'background-color:orange; }')

            def mouseMoveEvent(self,event):

                Window = self.window()
                WindowX = GridSnap(Window.pos().x())
                WindowY = GridSnap(Window.pos().y())
                WindowPos = QPoint(WindowX,WindowY)
                WindowWidth = GridSnap(Window.width())
                WindowHeight = GridSnap(Window.height())
                WindowMinHeight = GridSnap(Window.minimumHeight())

                Cursor = QCursor
                CursorY = GridSnap(Cursor.pos().y())

                GripY = WindowY+WindowHeight

                DeltaY = GripY-CursorY

                # Y #
                NewX = WindowX
                NewWidth = WindowWidth

                # Y #
                if WindowHeight-DeltaY < WindowMinHeight:
                    return
                else:
                    NewY = WindowY
                    NewHeight = WindowHeight-DeltaY

                # Window #
                if (WindowX,WindowY,WindowWidth,WindowHeight) == (NewX,NewY,NewWidth,NewHeight):
                    return
                else:
                    #Window.setGeometry(NewX+1,NewY+1,NewWidth,NewHeight) # Workaround #
                    #time.sleep(0.009)
                    Window.setGeometry(NewX,NewY,NewWidth,NewHeight)
                    time.sleep(0.009)

        self.ISouth = South(self,self)

        class SouthWest(QSizeGrip): # Affected #
            def __init__(self,Window,Parent):
                super().__init__(Window)

                # Variables #
                self.Parent = Parent

                # SouthWest #
                self.setSizePolicy(QSizePolicy.Policy.Fixed,QSizePolicy.Policy.Fixed)
                self.setFixedWidth(4)
                self.setFixedHeight(4)

                # Style #
                self.setStyleSheet('SouthWest { '
                    'background-color:red; }')

            def mouseMoveEvent(self,event):

                Window = self.window()
                WindowX = GridSnap(Window.pos().x())
                WindowY = GridSnap(Window.pos().y())
                WindowPos = QPoint(WindowX,WindowY)
                WindowWidth = GridSnap(Window.width())
                WindowHeight = GridSnap(Window.height())
                WindowMinWidth = GridSnap(Window.minimumWidth())
                WindowMinHeight = GridSnap(Window.minimumHeight())

                Cursor = QCursor
                CursorX = GridSnap(Cursor.pos().x())
                CursorY = GridSnap(Cursor.pos().y())
                CursorPos = QPoint(CursorX,CursorY)

                GripPos = QPoint(WindowX,WindowY+WindowHeight)
                GripX = GripPos.x()
                GripY = GripPos.y()

                DeltaX = CursorX-GripX
                DeltaY = CursorY-GripY

                # X #
                if WindowWidth-DeltaX < WindowMinWidth:
                    NewX = WindowX
                    NewWidth = WindowWidth
                else:
                    NewX = CursorX
                    NewWidth = WindowWidth-DeltaX

                # Y #
                if WindowHeight+DeltaY < WindowMinHeight:
                    NewY = WindowY
                    NewHeight = WindowHeight
                else:
                    NewY = WindowY
                    NewHeight = WindowHeight+DeltaY

                # Window #
                if (WindowX,WindowY,WindowWidth,WindowHeight) == (NewX,NewY,NewWidth,NewHeight):
                    return
                else:
                    #Window.setGeometry(NewX+1,NewY+1,NewWidth,NewHeight) # Workaround #
                    #time.sleep(0.009)
                    Window.setGeometry(NewX,NewY,NewWidth,NewHeight)
                    time.sleep(0.009)

        self.ISouthWest = SouthWest(self,self)

        class West(QSizeGrip):
            def __init__(self,Window,Parent):
                super().__init__(Window)

                # Variables #
                self.Parent = Parent

                # West #
                self.setSizePolicy(QSizePolicy.Policy.Fixed,QSizePolicy.Policy.Expanding)
                self.setFixedWidth(4)

                # Style #
                self.setStyleSheet('West { '
                    'background-color:orange; }')

            def paintEvent(self,event):

                QSizeGrip.paintEvent(self,event)
                self.setCursor(Qt.CursorShape.SizeHorCursor)
                self.setStyleSheet('West { '
                    'background-color:orange; }')

            def mouseMoveEvent(self,event):

                Window = self.window()
                WindowX = GridSnap(Window.pos().x())
                WindowY = GridSnap(Window.pos().y())
                WindowPos = QPoint(WindowX,WindowY)
                WindowWidth = GridSnap(Window.width())
                WindowHeight = GridSnap(Window.height())
                WindowMinWidth = GridSnap(Window.minimumWidth())

                Cursor = QCursor
                CursorX = GridSnap(Cursor.pos().x())

                GripX = WindowX

                DeltaX = GripX-CursorX

                # X #
                if WindowWidth+DeltaX < WindowMinWidth:
                    return
                else:
                    NewX = WindowX-DeltaX
                    NewWidth = WindowWidth+DeltaX

                # Y #
                NewY = WindowY
                NewHeight = WindowHeight

                # Window #
                if (WindowX,WindowY,WindowWidth,WindowHeight) == (NewX,NewY,NewWidth,NewHeight):
                    return
                else:
                    Window.setGeometry(NewX,NewY,NewWidth,NewHeight)
                    time.sleep(0.009)

        self.IWest = West(self,self)

        class Layout(QGridLayout):
            def __init__(self,Parent):
                super().__init__()

                # Variables #
                self.Parent = Parent

                # Layout #
                self.setSpacing(0)
                self.setContentsMargins(0,0,0,0)
                self.addWidget(Parent.IContainer,1,1)
                self.addWidget(Parent.INorthWest,0,0)
                self.addWidget(Parent.INorth,0,1)
                self.addWidget(Parent.INorthEast,0,2)
                self.addWidget(Parent.IEast,1,2)
                self.addWidget(Parent.ISouthEast,2,2)
                self.addWidget(Parent.ISouth,2,1)
                self.addWidget(Parent.ISouthWest,2,0)
                self.addWidget(Parent.IWest,1,0)

        self.ILayout = Layout(self)
        self.setLayout(self.ILayout)

    def mouseEvent(self,event):
        print('Window Mouse')
        return

    def resizeEvent(self,event):
        print('Window Resize')
        return

    def mouseMoveEvent(self,event):
        print('Window MouseMove')
        return

    def moveEvent(self,event):
        print('Window Move')
        return

    def dragMoveEvent(self,event):
        print('Window dragMove')
        return

    def MaximizeNormal(self):

        if self.windowState() == Qt.WindowState.WindowNoState:

            self.setWindowState(Qt.WindowState.WindowMaximized)
            for Child in self.children():
                if isinstance(Child,QSizeGrip):
                    Child.setEnabled(False)

        elif self.windowState() == Qt.WindowState.WindowMaximized:

            self.setWindowState(Qt.WindowState.WindowNoState)
            for Child in self.children():
                if isinstance(Child,QSizeGrip):
                    Child.setEnabled(True)

class Application(QApplication):
    def __init__(self,argv):
        super().__init__(argv)

        self.IWindow = Window(self)
        self.IWindow.show()
        self.IWindow.move(GridSnap(self.IWindow.pos().x()),GridSnap(self.IWindow.pos().y())) # Snap to Center #

IApplication = Application(sys.argv)
sys.exit(Application.exec())

任何帮助将不胜感激......

编辑:解决方法作为当前代码的补充,只需取消注释...保持其他 setGeometry/sleep 调用不变。

python multiple-monitors pyqt6 manjaro
© www.soinside.com 2019 - 2024. All rights reserved.