PyQt4中无边框窗口的移动(拖动)_python qt无边框窗口重写鼠标事件拖动窗口-程序员宅基地

技术标签: pyqt  

搜索了很多文章,有关于Qt的C++版本无边框窗口的拖动:

例如这篇《Qt 无标题无边框程序的拖动和改变大小》http://blog.csdn.net/kfbyj/article/details/9284923

其中主要讲到两种方法,但是PyQt(Qt的Python版本)实现就没有找到,以下主要讲PyQt4中的实现

方法1:在QWidget/QDialog中重写mousePressEvent和mouseMoveEvent方法,利用move方法移动窗口

这种方法相对简单,但是缺陷在于会在鼠标按下移动过程中,整个窗口是实时移动,实时重绘,移动快了会出现重影(由于多次重绘)。

#!/usr/bin/python  
#-*-coding:utf-8-*-
from PyQt4.QtGui import *
from PyQt4.Qt import *
from PyQt4.QtCore import *


class AboutUsDialog(QDialog):

    def __init__(self, parent=None):
        super(AboutUsDialog, self).__init__(parent)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.Dialog)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.dragPosition = event.globalPos() - self.frameGeometry().topLeft()
            QApplication.postEvent(self, QEvent(174))
            event.accept()

    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.move(event.globalPos() - self.dragPosition)
            event.accept()

if __name__ == '__main__':

    import sys
    app = QApplication(sys.argv)
    aboutus = AboutUsDialog()
    aboutus.show()
    sys.exit(app.exec_())

而正常的windows窗体移动都会在鼠标按下后呈现虚线边框,只移动虚线边框,鼠标放开后才会将窗体真正移动

方法二:使用winEvent处理消息,将鼠标点击窗体内的事件WM_NCHITTEST,模拟成为点击原生标题栏的事件HTCAPTION。在无边框的窗口中增加isInTitle方法来判断鼠标位置是否在窗口中自定义的标题栏中。

此方法可以实现鼠标在自定义栏中的鼠标拖动,但是暂时不支持鼠标双击进行最大化切换和还原。

#!/usr/bin/python  
#-*-coding:utf-8-*-
from PyQt4.QtGui import *
from PyQt4.Qt import *
from PyQt4.QtCore import *


class AboutUsDialog(QWidget):

    def __init__(self, parent=None):
        super(AboutUsDialog, self).__init__(parent)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.Dialog)

    def isInTitle(self, xPos, yPos):
        return yPos < 30


class MyApplication(QApplication):

    def __init__(self, args):
        super(MyApplication, self).__init__(args)

    def GET_X_LPARAM(self, param):
        #define LOWORD(l)           ((WORD)((DWORD_PTR)(l) & 0xffff))
        #define HIWORD(l)           ((WORD)((DWORD_PTR)(l) >> 16))
        #define GET_X_LPARAM(lp)                        ((int)(short)LOWORD(lp))
        #define GET_Y_LPARAM(lp)                        ((int)(short)HIWORD(lp))
        return param & 0xffff

    def GET_Y_LPARAM(self, param):
        return param >> 16

    def winEventFilter(self, msg):
        if msg.message == 0x84: #WM_NCHITTEST 
            form = self.activeWindow()
            if form:
                xPos = self.GET_X_LPARAM(msg.lParam) - form.frameGeometry().x()
                yPos = self.GET_Y_LPARAM(msg.lParam) - form.frameGeometry().y()
#                鼠标在窗体自定义标题范围内,窗体自定义一个isInTitle的方法判断 
#                if yPos < 30 and xPos < 456:
                if not form.isMaximized() and hasattr(form, 'isInTitle') and form.isInTitle(xPos, yPos):
                    return True, 0x2 #HTCAPTION 

        return False, 0

if __name__ == '__main__':

    import sys
    app = MyApplication(sys.argv)
    aboutus = AboutUsDialog()
    aboutus.showNormal()
    sys.exit(app.exec_())
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013927943/article/details/53193207

智能推荐

机器视觉工程师3-5年内的职业规划与思考,视觉工程师必看!_视觉工程师发展路线-程序员宅基地

文章浏览阅读1.1k次,点赞29次,收藏13次。分析目前国内绝大多数视觉工程师的职业能力现状,机器视觉工程师3-5年内的职业规划与思考,视觉工程师必看!_视觉工程师发展路线

STM32带FIFO的DMA传输应用示例-程序员宅基地

文章浏览阅读6.6k次,点赞16次,收藏91次。STM32系列芯片都内置DMA外设,其中很多系列的DMA配备了FIFO。这里以STM32F429芯片及开发板为例,演示一下带FIFO的DMA传输实现过程。大致情况是这样的,我用TIME..._stm32 dma fifo

mongodb java spring_Spring集成MongoDB-程序员宅基地

文章浏览阅读314次。开篇Spring提供了对非关系数据库的集成,Spring的spring-data包提供了对mongoDB和redis集成的工具包。此篇博客介绍一下Spring和MongoDB的集成。导入工具包需要的工具包有spring的jar包、spring-common的jar包以及spring-data的mongoDB的jar包。其中,spring的jar包有aop、asm、aspects、beans、con..._spring-common.jar

CGAL的三维点集_cgal polymesh points-程序员宅基地

文章浏览阅读2.3k次,点赞78次,收藏30次。CGAL提供了几种处理点集的算法,从形状检测到通过标准点集处理工具进行的表面重建。虽然这些算法不强制使用特定的数据结构,但该软件包提供了一个3D点集结构,使用户更容易处理附加属性,如法向量、颜色、标签,并在其上调用CGAL算法。_cgal polymesh points

使用Github Actions将Vue项目部署到Github Pages_github actions vue.js 到 github page-程序员宅基地

文章浏览阅读457次。GitHub Actions 是 GitHub 的持续集成服务,是一个非常强大的功能,用它可以实现很多自动化功能。现在我们来使用Github Actions将我们做好的Vue项目部署到Github Pages上。_github actions vue.js 到 github page

关于路由器-程序员宅基地

文章浏览阅读54次。1.又称网关设备(Gateway),专业来说是,所谓逻辑网络是代表一个单独的网络或者一个子网。当数据从一个子网传输到另一个子网时,可通过路由器的路由功能来完成。

随便推点

C++ QT进阶_qt 进阶培训-程序员宅基地

文章浏览阅读5.6k次,点赞17次,收藏241次。前言为什么会有这篇文章呢?为什么学QT呢?学了c/c++,除了会刷几道leetcode,用二分法解个方程,尝试深搜走地图,用线性筛找个素数······;难道C++的应用就是为了ACM吗?不,个人觉得并不是,这不是自己的初衷!于是乎,开始学习数据结构,网络编程,系统编程,web前端(html、css、JavaScript)······因为学了c++还没找到一个好的应用,感觉很糟!如果您想了解为什么学习qt,请点击链接查看:《为什么 qt 成为 c++ 界面编程的第一选择?》推荐一个详细_qt 进阶培训

maven 包管理平台 windows 安装配置 + mac 安装配置-程序员宅基地

文章浏览阅读928次,点赞19次,收藏18次。磁盘空间: Maven 安装本身需要大约 10MB。除此之外,您的本地 Maven 仓库还将使用额外的磁盘空间。或更高版本才能执行 - 它仍然允许您针对 1.3 和其他 JDK 版本进行构建,使用 Toolchains。基于项目对象模型(POM)的概念,Maven 可以从一个中心信息管理项目的构建、报告和文档。您的本地仓库大小将根据使用情况而变化,但至少需要。可以获取本地包下的目录。文件,配置对应的代码仓库存储地址。退出 mac 终端,重新启动终端。可以看到您设置的内容,并且。本文由博客一文多发平台。

关于STM32 HAL库获取RTC时间不更新问题_为什么用hal库生成的rtc代码秒数不会增加-程序员宅基地

文章浏览阅读1.5k次。将获取日期的接口放在获取时间之后_为什么用hal库生成的rtc代码秒数不会增加

Redis-程序员宅基地

文章浏览阅读92次。Redis1、Nosql概述1.1、为什么使用nosql单机Mysql时代90年代,一个网站的访问量一般不会太大,单个数据库完全够用。随着用户增多,网站出现以下问题数据量增加到一定程度,单机数据库就放不下了数据的索引(B+ Tree),一个机器内存也存放不下访问量变大后(读写混合),一台服务器承受不住。Memcached(缓存) + Mysql + 垂直拆分(读写分离)网站80%的情况都是在读,每次都要去查询数据库的话就十分的麻烦!所以说我们希望减轻数据库的压力,我们可以使用缓

Dubbo添加过滤器(二)---日志打印接口耗时_dubbo耗时过滤器-程序员宅基地

文章浏览阅读85次。Dubbo添加过滤器详情见: https://www.cnblogs.com/expiator/p/14557091.html本文主要是用Dubbo添加过滤器,统计接口耗时日志打印接口耗时import com.alibaba.dubbo.common.Constants;import com.alibaba.dubbo.common.extension.Activate;import..._dubbo耗时过滤器

Dijkstra-程序员宅基地

文章浏览阅读389次,点赞5次,收藏7次。【代码】Dijkstra。