首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何创建可拖动和可调整大小的无框架窗口

如何创建可拖动和可调整大小的无框架窗口
EN

Stack Overflow用户
提问于 2022-03-24 06:51:31
回答 1查看 382关注 0票数 1

我希望在Pyside6中通过重写mouseEvent和resizeEvent.And创建一个可拖动和可调整大小的无框架窗口,尝试使用QSizeGrip来控制窗口的形状。

拖动和调整大小,我可以单独实现这两个函数,但当它们合并时会出现问题。

当我在拖动后调整窗口的大小时,位置将是错误的。我想知道这段代码有什么问题:

代码语言:javascript
运行
AI代码解释
复制
import sys
from PySide6.QtCore import *
from PySide6.QtWidgets import *
from PySide6.QtGui import *

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()


        self.text = QLabel("Hello World",alignment=Qt.AlignCenter)
        self.layout =QVBoxLayout(self)
        self.layout.addWidget(self.text)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        self.gripSize = 16
        self.grips = []
        for i in range(4):
            grip = QSizeGrip(self)
            grip.resize(self.gripSize, self.gripSize)
            self.grips.append(grip)

    def resizeEvent(self, event):
        QWidget.resizeEvent(self, event)
        rect = self.rect()
        # top left grip doesn't need to be moved...
        # top right
        self.grips[1].move(rect.right() - self.gripSize, 0)
        # bottom right
        self.grips[2].move(
            rect.right() - self.gripSize, rect.bottom() - self.gripSize)
        # bottom left
        self.grips[3].move(0, rect.bottom() - self.gripSize)


    def mousePressEvent(self, event):
        self.oldPos = event.globalPos()

    def mouseMoveEvent(self, event):
        delta = QPoint(event.globalPos() - self.oldPos)
        self.move(self.x() + delta.x(), self.y() + delta.y())
        self.oldPos = event.globalPos()




if __name__ == "__main__":
    app =QApplication([])
EN

回答 1

Stack Overflow用户

发布于 2022-03-25 15:10:09

默认情况下,QSizeGrip与OS接口,以便在激活后立即进行实际大小调整(按下鼠标左键)。

结果是,在此之后,所有鼠标移动事件都会被系统拦截,直到按钮被释放。由于按钮发布也被系统拦截(为了知道调整大小已经完成),QSizeGrip只能在按钮发布之后才能再次处理鼠标事件;由于以前的条件是按鼠标按钮,它将接收一个MouseMove事件,而在默认情况下,如果这些事件不能处理,这些事件就会被小部件忽略。

如果忽略鼠标事件,则将其传播到其父事件(在本例中为MyWidget )。

不幸的是,您的假设是只有在按下按钮之后才能得到鼠标移动事件,但由于上面解释的情况,情况并非如此:您将不会收到鼠标按钮按下(它是由大小抓地力处理的),而只是鼠标移动(因为大小抓地力忽略了它)。

现在,有两种情况:

您以前移动过的窗口,因此有一个基于上一个开始鼠标位置的oldPos,该窗口将使用错误的parameters;

  • you移动,只在启动后调整窗口的大小,程序将崩溃,因为没有oldPos属性;

有各种可能的解决方案,但简单的解决方案是创建一个具有None值的默认None属性,在鼠标按下设置它,在鼠标移动中检查if self.oldPos is not None (并最终移动),最重要的是在鼠标版本中恢复self.oldPos = None

注意,通常最好只用一个按钮移动窗口(约定是左边的,但中间的按钮并不少见)。

代码语言:javascript
运行
AI代码解释
复制
class MyWidget(QWidget):
    oldPos = None

    # ...

    def mousePressEvent(self, event):
        if event.button() == Qt.MouseButton.LeftButton:
            self.oldPos = event.globalPos()

    def mouseMoveEvent(self, event):
        if self.oldPos is not None:
            delta = event.globalPos() - self.oldPos
            self.move(self.pos() + delta)
            self.oldPos = event.globalPos()

    def mouseReleaseEvent(self, event):
        self.oldPos = None

注意:QPoint + QPoint已经是一个QPoint,move()默认接受一个QPoint,因此不需要单独求和x和y坐标。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71604670

复制
相关文章

相似问题

领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文