pyqt6/pyside6:窗口移动不正常工作
我正在尝试创建一个带有自定义栏的窗口。 为此,我使用以下条形码:(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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论