Pyqt实现无边框窗口拖动以及窗口大小改变

yipeiwu_com6年前Python基础

本文实例为大家分享了Pyqt实现无边框窗口拖动及大小改变的具体代码,供大家参考,具体内容如下

做个记录,绘制边框阴影可以忽略这里不是主要

根据网上某位仁兄Qt的实现转过来的大笑,上完整代码

# coding:utf-8 
from PyQt4.Qt import * 
import sys 
 
PADDING=4  
sys.setrecursionlimit(10000) 
class ShadowWidget(QWidget): 
  def __init__(self,parent=None): 
    super(ShadowWidget,self).__init__(parent) 
    self.setWindowFlags(Qt.FramelessWindowHint|Qt.WindowSystemMenuHint) 
    self.setAttribute(Qt.WA_TranslucentBackground) 
    self.SHADOW_WIDTH=0  #边框距离 
    self.isLeftPressDown = False #鼠标左键是否按下 
    self.dragPosition=0   #拖动时坐标 
    self.Numbers = self.enum(UP=0, DOWN=1, LEFT=2, RIGHT=3, LEFTTOP=4, LEFTBOTTOM=5, RIGHTBOTTOM=6, RIGHTTOP=7, NONE=8) #枚举参数 
    self.setMinimumHeight(500) #窗体最小高度 
    self.setMinimumWidth(1000) #窗体最小宽度 
    self.dir=self.Numbers.NONE #初始鼠标状态 
    self.setMouseTracking(True) 
 
  #绘制边框阴影 
  def drawShadow(self,painter): 
    #绘制左上角、左下角、右上角、右下角、上、下、左、右边框 
    self.pixmaps=QStringList() 
    self.pixmaps.append(QString("./img/border/left_top.png")) 
    self.pixmaps.append(QString("./img/border/left_bottom.png")) 
    self.pixmaps.append(QString("./img/border/right_top.png")) 
    self.pixmaps.append(QString("./img/border/right_bottom.png")) 
    self.pixmaps.append(QString("./img/border/top_mid.png")) 
    self.pixmaps.append(QString("./img/border/bottom_mid.png")) 
    self.pixmaps.append(QString("./img/border/left_mid.png")) 
    self.pixmaps.append(QString("./img/border/right_mid.png")) 
    painter.drawPixmap(0, 0, self.SHADOW_WIDTH, self.SHADOW_WIDTH, QPixmap(self.pixmaps[0]))  #左上角 
    painter.drawPixmap(self.width()-self.SHADOW_WIDTH, 0, self.SHADOW_WIDTH, self.SHADOW_WIDTH, QPixmap(self.pixmaps[2]))  #右上角 
    painter.drawPixmap(0,self.height()-self.SHADOW_WIDTH, self.SHADOW_WIDTH, self.SHADOW_WIDTH, QPixmap(self.pixmaps[1]))  #左下角 
    painter.drawPixmap(self.width()-self.SHADOW_WIDTH, self.height()-self.SHADOW_WIDTH, self.SHADOW_WIDTH, self.SHADOW_WIDTH, QPixmap(self.pixmaps[3])) #右下角 
    painter.drawPixmap(0, self.SHADOW_WIDTH, self.SHADOW_WIDTH, self.height()-2*self.SHADOW_WIDTH, QPixmap(self.pixmaps[6]).scaled(self.SHADOW_WIDTH, self.height()-2*self.SHADOW_WIDTH)) #左 
    painter.drawPixmap(self.width()-self.SHADOW_WIDTH, self.SHADOW_WIDTH, self.SHADOW_WIDTH, self.height()-2*self.SHADOW_WIDTH, QPixmap(self.pixmaps[7]).scaled(self.SHADOW_WIDTH, self.height()- 2*self.SHADOW_WIDTH)) #右 
    painter.drawPixmap(self.SHADOW_WIDTH, 0, self.width()-2*self.SHADOW_WIDTH, self.SHADOW_WIDTH, QPixmap(self.pixmaps[4]).scaled(self.width()-2*self.SHADOW_WIDTH, self.SHADOW_WIDTH)) #上 
    painter.drawPixmap(self.SHADOW_WIDTH, self.height()-self.SHADOW_WIDTH, self.width()-2*self.SHADOW_WIDTH, self.SHADOW_WIDTH, QPixmap(self.pixmaps[5]).scaled(self.width()-2*self.SHADOW_WIDTH, self.SHADOW_WIDTH))  #下 
 
  #枚举参数 
  def enum(self,**enums): 
    return type('Enum', (), enums) 
 
  def region(self,cursorGlobalPoint): 
    #获取窗体在屏幕上的位置区域,tl为topleft点,rb为rightbottom点 
    rect = self.rect() 
    tl = self.mapToGlobal(rect.topLeft()) 
    rb = self.mapToGlobal(rect.bottomRight()) 
 
    x = cursorGlobalPoint.x() 
    y = cursorGlobalPoint.y() 
 
    if(tl.x() + PADDING >= x and tl.x() <= x and tl.y() + PADDING >= y and tl.y() <= y): 
      #左上角 
      self.dir = self.Numbers.LEFTTOP 
      self.setCursor(QCursor(Qt.SizeFDiagCursor))  #设置鼠标形状 
    elif(x >= rb.x() - PADDING and x <= rb.x() and y >= rb.y() - PADDING and y <= rb.y()): 
      #右下角 
      self.dir = self.Numbers.RIGHTBOTTOM 
      self.setCursor(QCursor(Qt.SizeFDiagCursor)) 
    elif(x <= tl.x() + PADDING and x >= tl.x() and y >= rb.y() - PADDING and y <= rb.y()): 
      #左下角 
      self.dir = self.Numbers.LEFTBOTTOM 
      self.setCursor(QCursor(Qt.SizeBDiagCursor)) 
    elif(x <= rb.x() and x >= rb.x() - PADDING and y >= tl.y() and y <= tl.y() + PADDING): 
      #右上角 
      self.dir = self.Numbers.RIGHTTOP 
      self.setCursor(QCursor(Qt.SizeBDiagCursor)) 
    elif(x <= tl.x() + PADDING and x >= tl.x()): 
      #左边 
      self.dir = self.Numbers.LEFT 
      self.setCursor(QCursor(Qt.SizeHorCursor)) 
    elif( x <= rb.x() and x >= rb.x() - PADDING): 
      #右边 
 
      self.dir = self.Numbers.RIGHT 
      self.setCursor(QCursor(Qt.SizeHorCursor)) 
    elif(y >= tl.y() and y <= tl.y() + PADDING): 
      #上边 
      self.dir = self.Numbers.UP 
      self.setCursor(QCursor(Qt.SizeVerCursor)) 
    elif(y <= rb.y() and y >= rb.y() - PADDING): 
      #下边 
      self.dir = self.Numbers.DOWN 
      self.setCursor(QCursor(Qt.SizeVerCursor)) 
    else: 
      #默认 
      self.dir = self.Numbers.NONE 
      self.setCursor(QCursor(Qt.ArrowCursor)) 
 
  def mouseReleaseEvent(self,event): 
    if(event.button() == Qt.LeftButton): 
      self.isLeftPressDown = False 
      if(self.dir != self.Numbers.NONE): 
        self.releaseMouse() 
        self.setCursor(QCursor(Qt.ArrowCursor)) 
 
  def mousePressEvent(self,event): 
    if(event.button()==Qt.LeftButton): 
      self.isLeftPressDown=True 
      if(self.dir != self.Numbers.NONE): 
        self.mouseGrabber() 
      else: 
        self.dragPosition = event.globalPos() - self.frameGeometry().topLeft() 
 
  def mouseMoveEvent(self,event): 
    gloPoint = event.globalPos() 
    rect = self.rect() 
    tl = self.mapToGlobal(rect.topLeft()) 
    rb = self.mapToGlobal(rect.bottomRight()) 
 
    if(not self.isLeftPressDown): 
      self.region(gloPoint)  
    else: 
      if(self.dir != self.Numbers.NONE): 
        rmove=QRect(tl, rb) 
        if(self.dir==self.Numbers.LEFT): 
          if(rb.x() - gloPoint.x() <= self.minimumWidth()): 
            rmove.setX(tl.x()) 
          else: 
            rmove.setX(gloPoint.x()) 
        elif(self.dir==self.Numbers.RIGHT): 
          print u"youbian" 
          rmove.setWidth(gloPoint.x() - tl.x()) 
        elif(self.dir==self.Numbers.UP): 
          if(rb.y() - gloPoint.y() <= self.minimumHeight()): 
            rmove.setY(tl.y()) 
          else: 
            rmove.setY(gloPoint.y()) 
        elif(self.dir==self.Numbers.DOWN): 
          rmove.setHeight(gloPoint.y() - tl.y()) 
        elif(self.dir==self.Numbers.LEFTTOP): 
          if(rb.x() - gloPoint.x() <= self.minimumWidth()): 
            rmove.setX(tl.x()) 
          else: 
            rmove.setX(gloPoint.x()) 
          if(rb.y() - gloPoint.y() <= self.minimumHeight()): 
            rmove.setY(tl.y()) 
          else: 
            rmove.setY(gloPoint.y()) 
        elif(self.dir==self.Numbers.RIGHTTOP): 
          rmove.setWidth(gloPoint.x() - tl.x()) 
          rmove.setY(gloPoint.y()) 
        elif(self.dir==self.Numbers.LEFTBOTTOM): 
          rmove.setX(gloPoint.x()) 
          rmove.setHeight(gloPoint.y() - tl.y()) 
        elif(self.dir==self.Numbers.RIGHTBOTTOM): 
          rmove.setWidth(gloPoint.x() - tl.x()) 
          rmove.setHeight(gloPoint.y() - tl.y()) 
        else: 
          pass 
        self.setGeometry(rmove) 
      else: 
        self.move(event.globalPos() - self.dragPosition) 
        event.accept() 
 
if __name__ == '__main__': 
  app = QApplication(sys.argv) 
  shadow = ShadowWidget() 
  shadow.show() 
  sys.exit(app.exec_()) 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持【听图阁-专注于Python设计】。

相关文章

Python中集合类型(set)学习小结

set 是一个无序的元素集合,支持并、交、差及对称差等数学运算, 但由于 set 不记录元素位置,因此不支持索引、分片等类序列的操作。 初始化 复制代码 代码如下: s0 = set()...

Python3 venv搭建轻量级虚拟环境的步骤(图文)

Python3 venv搭建轻量级虚拟环境的步骤(图文)

今天先聊一聊在windows/mac iOS系统下用venv搭建python轻量级虚拟环境的问题。 使用venv搭建的虚拟环境同virtualenv搭建的虚拟环境,即venv可替代vir...

pycharm运行和调试不显示结果的解决方法

pycharm运行和调试不显示结果的解决方法

刚在虚拟机里面安装了pycharm,配置(setting)完后,新建一个py文件,键入"hello world",竟然没有结果,虽然运行成功。pycharm太不友好了吧! 然后开始找问...

使用Python的toolz库开始函数式编程的方法

在这个由两部分组成的系列文章的第二部分中,我们将继续探索如何将函数式编程方法中的好想法引入到 Python中,以实现两全其美。 在上一篇文章中,我们介绍了不可变数据结构 。 这些数据结构...

Python自动化运维之IP地址处理模块详解

实用的IP地址处理模块IPy 在IP地址规划中,涉及到计算大量的IP地址,包括网段、网络掩码、广播地址、子网数、IP类型等 别担心,Ipy模块拯救你。Ipy模块可以很好的辅助我们高效的...