'PyQt6/PySide6: window move doesn't work properly

I'm trying to create a window with a custom bar on top. For this I am using the following bar code: (bar.py) from PySide6.QtWidgets import QWidget, QLabel, QPushButton, QHBoxLayout from PySide6.QtCore import Qt, QSize, QPointF from PySide6.QtGui import QIcon

class CustomBar(QWidget):
    def __init__(self, main_window):
        super().__init__()
        self.main_window = main_window

        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)

        # ------- title -------
        self.title = QLabel("MyApp")
        self.title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.title.setFixedWidth(100)

        # ------- minimize button -------
        self.minimize_button = QPushButton()
        self.minimize_button.setIcon(QIcon("media\\ui\\icons\\enabled_button.png"))
        self.minimize_button.setStyleSheet("background-color: rgba(0, 0, 0, 0);")
        self.minimize_button.setIconSize(QSize(16, 16))
        self.minimize_button.setFixedSize(16, 16)
        self.minimize_button.clicked.connect(self.minimize_window)

        # ------- close button -------
        self.close_button = QPushButton()
        self.close_button.setIcon(QIcon("media\\ui\\icons\\disabled_button.png"))
        self.close_button.setStyleSheet("background-color: rgba(0, 0, 0, 0);")
        self.close_button.setIconSize(QSize(16, 16))
        self.minimize_button.setFixedSize(16, 16)
        self.close_button.clicked.connect(self.close_window)

        self.layout.addWidget(self.title)
        self.layout.addWidget(self.minimize_button)
        self.layout.addWidget(self.close_button)

        self.setLayout(self.layout)
        self.current_position = QPointF(0, 0)

    def minimize_window(self):
        self.main_window.showMinimized()

    def close_window(self):
        self.main_window.close()

    def mousePressEvent(self, event):
        self.current_position = self.mapToGlobal(event.position())

    def mouseMoveEvent(self, event):
        new_position = self.mapToGlobal(event.position())
        movement = new_position - self.current_position
        print(self.current_position, new_position, movement, "-------------------", sep="\n")
        self.main_window.setGeometry(self.mapToGlobal(movement).x(), self.mapToGlobal(movement).y(),
                                     self.main_window.width(), self.main_window.height())
        self.current_position = new_position

I have created a MainPage widget as the main content of the window:

from PySide6.QtWidgets import QWidget, QVBoxLayout

from gui.toggle_button import ToggleButton
from functools import partial


class MainPage(QWidget):
    def __init__(self, bot):
        super(MainPage, self).__init__()
        self.bot = bot  # an instance of the main program class

        self.buttons = {}
        self.layout = QVBoxLayout()

        for i in self.bot.settings["toggles"]:  # creating buttons for each available switch
            print(i)
            btn = ToggleButton(self.bot.settings["toggles"][i]["name"])
            btn.set_state(self.bot.settings["toggles"][i]["value"])
            btn.clicked.connect(partial(self.bot.toggle_setting, i))
            btn.clicked.connect(self.bot.menu.update)
            btn.clicked.connect(self.update_buttons)
            self.layout.addWidget(btn)
            self.buttons[i] = btn

        self.setLayout(self.layout)

    def update_buttons(self):  # some switches enable/disable other switches, so you need to update the state of all switches.
        for i in self.buttons:
            self.buttons[i].set_state(self.bot.settings["toggles"][i]["value"])

QPushButton custom widget code (ToggleButton):

from PySide6.QtWidgets import QPushButton
from PySide6.QtCore import QSize
from PySide6.QtGui import QIcon


class ToggleButton(QPushButton):
    def __init__(self, name):
        super().__init__()
        self.button_size = QSize(25, 25)
        self.is_enabled = True
        self.setMinimumSize(QSize(50, 25))
        self.setMaximumSize(QSize(200, 25))

        self.setText(name)
        self.setIcon(QIcon("media\\ui\\icons\\enabled_button.png"))
        self.setIconSize(self.button_size)
        self.setStyleSheet("background-color: rgba(0, 0, 0, 0); text-align: left; border: 3px solid rgb(255, 0, 0);")

    def set_disabled(self):
        self.setIcon(QIcon("media\\ui\\icons\\disabled_button.png"))
        self.setIconSize(self.button_size)
        self.is_enabled = False

    def set_enabled(self):
        self.setIcon(QIcon("media\\ui\\icons\\enabled_button.png"))
        self.setIconSize(self.button_size)
        self.is_enabled = True

    def set_state(self, state: bool):
        self.set_enabled() if state else self.set_disabled()

And finally, the main widget:

from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout
from PySide6.QtCore import Qt
from gui.main_menu import MainPage
from gui.bar import CustomBar


class MainWindow(QWidget):
    def __init__(self, bot):
        super().__init__()
        self.setWindowFlag(Qt.FramelessWindowHint)  # disable window frames

        self.layout = QVBoxLayout()

        self.main_widget = MainPage(bot)
        self.bar = CustomBar(self) 
        self.layout.addWidget(self.bar)
        self.layout.addWidget(self.main_widget)
        self.setLayout(self.layout)


def init_ui(bot):
    app = QApplication()
    window = MainWindow(bot)
    window.show()
    app.exec()

The interface looks pretty much as I expected, however, when I try to move it, the window moves straight down to the right, regardless of mouse movement: https://youtu.be/Ont_UsDcA0c

But judging by the console output, the desired position of the window is determined correctly, and, as I understand it, I am using the .mapToGlobal() function incorrectly. Console output:

PySide6.QtCore.QPointF(508.000000, 197.000000)
PySide6.QtCore.QPointF(509.000000, 197.000000)
PySide6.QtCore.QPointF(1.000000, 0.000000)
-------------------
PySide6.QtCore.QPointF(509.000000, 197.000000)
PySide6.QtCore.QPointF(510.000000, 197.000000)
PySide6.QtCore.QPointF(1.000000, 0.000000)
-------------------
PySide6.QtCore.QPointF(510.000000, 197.000000)
PySide6.QtCore.QPointF(510.000000, 196.000000)
PySide6.QtCore.QPointF(0.000000, -1.000000)
-------------------
PySide6.QtCore.QPointF(510.000000, 196.000000)
PySide6.QtCore.QPointF(511.000000, 197.000000)
PySide6.QtCore.QPointF(1.000000, 1.000000)
-------------------
PySide6.QtCore.QPointF(511.000000, 197.000000)
PySide6.QtCore.QPointF(512.000000, 197.000000)
PySide6.QtCore.QPointF(1.000000, 0.000000)
-------------------
PySide6.QtCore.QPointF(512.000000, 197.000000)
PySide6.QtCore.QPointF(511.000000, 197.000000)
PySide6.QtCore.QPointF(-1.000000, 0.000000)
-------------------
PySide6.QtCore.QPointF(511.000000, 197.000000)
PySide6.QtCore.QPointF(511.000000, 196.000000)
PySide6.QtCore.QPointF(0.000000, -1.000000)
-------------------
PySide6.QtCore.QPointF(511.000000, 196.000000)
PySide6.QtCore.QPointF(510.000000, 197.000000)
PySide6.QtCore.QPointF(-1.000000, 1.000000)
-------------------
PySide6.QtCore.QPointF(510.000000, 197.000000)
PySide6.QtCore.QPointF(508.000000, 197.000000)
PySide6.QtCore.QPointF(-2.000000, 0.000000)
-------------------
PySide6.QtCore.QPointF(508.000000, 197.000000)
PySide6.QtCore.QPointF(508.000000, 197.000000)
PySide6.QtCore.QPointF(0.000000, 0.000000)
-------------------
PySide6.QtCore.QPointF(508.000000, 197.000000)
PySide6.QtCore.QPointF(507.000000, 196.000000)
PySide6.QtCore.QPointF(-1.000000, -1.000000)
-------------------
PySide6.QtCore.QPointF(507.000000, 196.000000)
PySide6.QtCore.QPointF(506.000000, 197.000000)
PySide6.QtCore.QPointF(-1.000000, 1.000000)
-------------------
PySide6.QtCore.QPointF(506.000000, 197.000000)
PySide6.QtCore.QPointF(505.000000, 197.000000)
PySide6.QtCore.QPointF(-1.000000, 0.000000)
-------------------
PySide6.QtCore.QPointF(505.000000, 197.000000)
PySide6.QtCore.QPointF(505.000000, 197.000000)
PySide6.QtCore.QPointF(0.000000, 0.000000)
-------------------
PySide6.QtCore.QPointF(505.000000, 197.000000)
PySide6.QtCore.QPointF(504.000000, 196.000000)
PySide6.QtCore.QPointF(-1.000000, -1.000000)
-------------------
PySide6.QtCore.QPointF(504.000000, 196.000000)
PySide6.QtCore.QPointF(503.000000, 197.000000)
PySide6.QtCore.QPointF(-1.000000, 1.000000)
-------------------
PySide6.QtCore.QPointF(503.000000, 197.000000)
PySide6.QtCore.QPointF(502.000000, 197.000000)
PySide6.QtCore.QPointF(-1.000000, 0.000000)
-------------------
PySide6.QtCore.QPointF(502.000000, 197.000000)
PySide6.QtCore.QPointF(502.000000, 197.000000)
PySide6.QtCore.QPointF(0.000000, 0.000000)
-------------------
PySide6.QtCore.QPointF(502.000000, 197.000000)
PySide6.QtCore.QPointF(501.000000, 196.000000)
PySide6.QtCore.QPointF(-1.000000, -1.000000)
-------------------
PySide6.QtCore.QPointF(501.000000, 196.000000)
PySide6.QtCore.QPointF(500.000000, 197.000000)
PySide6.QtCore.QPointF(-1.000000, 1.000000)
-------------------

I took this code as the basis for the custom bar: https://stackoverflow.com/a/44249552/18196171

No matter how much I compared them, I did not find tangible differences that could change the result so much.

What could be the problem?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source