'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 |
|---|
