pyqt6/pyside6:窗口移动不正常工作

发布于 2025-01-27 11:31:20 字数 9121 浏览 4 评论 0原文

我正在尝试创建一个带有自定义栏的窗口。 为此,我使用以下条形码:(bar.py) 来自pyside6.qtwidgets导入qwidget,qlabel,qpushbutton,qhboxlayout 来自pyside6.qtcore导入qt,qsize,qpointf 从pyside6.qtgui导入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

我创建了一个mainpage窗口小部件作为窗口的主要内容:

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自定义窗口小零件(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()

和最后,主要小部件:

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()

接口看起来几乎是我预期的,但是,当我尝试移动它时,窗口直接向右移动,无论鼠标运动如何: https://youtu.be/ont_usdca0c

但是,根据控制台输出的判断,窗口的所需位置正确确定,据我了解,我正在理解,我正在使用它,我正在使用,我正在使用它.maptoglobal()函数不正确。 控制台输出:

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

我将此代码作为自定义栏的基础: https://stackover.com/a/a/44249552/44249552/18196171

无论我比较了多少,我都找不到可能改变结果的切实差异。

有什么问题?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文