欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PyQt5實(shí)現(xiàn)無(wú)邊框窗口的標(biāo)題拖動(dòng)和窗口縮放

 更新時(shí)間:2018年04月19日 16:50:16   作者:專注劃水  
這篇文章主要為大家詳細(xì)介紹了PyQt5實(shí)現(xiàn)無(wú)邊框窗口的標(biāo)題拖動(dòng)和窗口縮放,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

網(wǎng)上找了半天都找不到好用的PyQt5無(wú)邊框窗口的實(shí)現(xiàn),借鑒部分前輩的窗口拖放代碼,自己實(shí)現(xiàn)了一下無(wú)邊框窗口,問題可能還有一點(diǎn),慢慢改吧

先做個(gè)筆記

py文件

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from PyQt5.QtWidgets import QWidget, QLabel, QPushButton, QVBoxLayout
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtGui import QFont, QCursor

class QTitleLabel(QLabel):
  """
  新建標(biāo)題欄標(biāo)簽類
  """
  def __init__(self, *args):
    super(QTitleLabel, self).__init__(*args)
    self.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
    self.setFixedHeight(30)

class QTitleButton(QPushButton):
  """
  新建標(biāo)題欄按鈕類
  """
  def __init__(self, *args):
    super(QTitleButton, self).__init__(*args)
    self.setFont(QFont("Webdings")) # 特殊字體以不借助圖片實(shí)現(xiàn)最小化最大化和關(guān)閉按鈕
    self.setFixedWidth(40)

class QUnFrameWindow(QWidget):
  """
  無(wú)邊框窗口類
  """
  def __init__(self):
    super(QUnFrameWindow, self).__init__(None, Qt.FramelessWindowHint) # 設(shè)置為頂級(jí)窗口,無(wú)邊框
    self._padding = 5 # 設(shè)置邊界寬度為5
    self.initTitleLabel() # 安放標(biāo)題欄標(biāo)簽
    self.setWindowTitle = self._setTitleText(self.setWindowTitle) # 用裝飾器將設(shè)置WindowTitle名字函數(shù)共享到標(biāo)題欄標(biāo)簽上
    self.setWindowTitle("UnFrameWindow")
    self.initLayout() # 設(shè)置框架布局
    self.setMinimumWidth(250)
    self.setMouseTracking(True) # 設(shè)置widget鼠標(biāo)跟蹤
    self.initDrag() # 設(shè)置鼠標(biāo)跟蹤判斷默認(rèn)值

  def initDrag(self):
    # 設(shè)置鼠標(biāo)跟蹤判斷扳機(jī)默認(rèn)值
    self._move_drag = False
    self._corner_drag = False
    self._bottom_drag = False
    self._right_drag = False

  def initTitleLabel(self):
    # 安放標(biāo)題欄標(biāo)簽
    self._TitleLabel = QTitleLabel(self)
    self._TitleLabel.setMouseTracking(True) # 設(shè)置標(biāo)題欄標(biāo)簽鼠標(biāo)跟蹤(如不設(shè),則標(biāo)題欄內(nèi)在widget上層,無(wú)法實(shí)現(xiàn)跟蹤)
    self._TitleLabel.setIndent(10) # 設(shè)置標(biāo)題欄文本縮進(jìn)
    self._TitleLabel.move(0, 0) # 標(biāo)題欄安放到左上角

  def initLayout(self):
    # 設(shè)置框架布局
    self._MainLayout = QVBoxLayout()
    self._MainLayout.setSpacing(0)
    self._MainLayout.addWidget(QLabel(), Qt.AlignLeft) # 頂一個(gè)QLabel在豎放框架第一行,以免正常內(nèi)容擠占到標(biāo)題范圍里
    self._MainLayout.addStretch()
    self.setLayout(self._MainLayout)

  def addLayout(self, QLayout):
    # 給widget定義一個(gè)addLayout函數(shù),以實(shí)現(xiàn)往豎放框架的正確內(nèi)容區(qū)內(nèi)嵌套Layout框架
    self._MainLayout.addLayout(QLayout)

  def _setTitleText(self, func):
    # 設(shè)置標(biāo)題欄標(biāo)簽的裝飾器函數(shù)
    def wrapper(*args):
      self._TitleLabel.setText(*args)
      return func(*args)
    return wrapper

  def setTitleAlignment(self, alignment):
    # 給widget定義一個(gè)setTitleAlignment函數(shù),以實(shí)現(xiàn)標(biāo)題欄標(biāo)簽的對(duì)齊方式設(shè)定
    self._TitleLabel.setAlignment(alignment | Qt.AlignVCenter)

  def setCloseButton(self, bool):
    # 給widget定義一個(gè)setCloseButton函數(shù),為True時(shí)設(shè)置一個(gè)關(guān)閉按鈕
    if bool == True:
      self._CloseButton = QTitleButton(b'\xef\x81\xb2'.decode("utf-8"), self)
      self._CloseButton.setObjectName("CloseButton") # 設(shè)置按鈕的ObjectName以在qss樣式表內(nèi)定義不同的按鈕樣式
      self._CloseButton.setToolTip("關(guān)閉窗口")
      self._CloseButton.setMouseTracking(True) # 設(shè)置按鈕鼠標(biāo)跟蹤(如不設(shè),則按鈕在widget上層,無(wú)法實(shí)現(xiàn)跟蹤)
      self._CloseButton.setFixedHeight(self._TitleLabel.height()) # 設(shè)置按鈕高度為標(biāo)題欄高度
      self._CloseButton.clicked.connect(self.close) # 按鈕信號(hào)連接到關(guān)閉窗口的槽函數(shù)


  def setMinMaxButtons(self, bool):
    # 給widget定義一個(gè)setMinMaxButtons函數(shù),為True時(shí)設(shè)置一組最小化最大化按鈕
    if bool == True:
      self._MinimumButton = QTitleButton(b'\xef\x80\xb0'.decode("utf-8"), self)
      self._MinimumButton.setObjectName("MinMaxButton") # 設(shè)置按鈕的ObjectName以在qss樣式表內(nèi)定義不同的按鈕樣式
      self._MinimumButton.setToolTip("最小化")
      self._MinimumButton.setMouseTracking(True) # 設(shè)置按鈕鼠標(biāo)跟蹤(如不設(shè),則按鈕在widget上層,無(wú)法實(shí)現(xiàn)跟蹤)
      self._MinimumButton.setFixedHeight(self._TitleLabel.height()) # 設(shè)置按鈕高度為標(biāo)題欄高度
      self._MinimumButton.clicked.connect(self.showMinimized) # 按鈕信號(hào)連接到最小化窗口的槽函數(shù)
      self._MaximumButton = QTitleButton(b'\xef\x80\xb1'.decode("utf-8"), self)
      self._MaximumButton.setObjectName("MinMaxButton") # 設(shè)置按鈕的ObjectName以在qss樣式表內(nèi)定義不同的按鈕樣式
      self._MaximumButton.setToolTip("最大化")
      self._MaximumButton.setMouseTracking(True) # 設(shè)置按鈕鼠標(biāo)跟蹤(如不設(shè),則按鈕在widget上層,無(wú)法實(shí)現(xiàn)跟蹤)
      self._MaximumButton.setFixedHeight(self._TitleLabel.height()) # 設(shè)置按鈕高度為標(biāo)題欄高度
      self._MaximumButton.clicked.connect(self._changeNormalButton) # 按鈕信號(hào)連接切換到恢復(fù)窗口大小按鈕函數(shù)

  def _changeNormalButton(self):
    # 切換到恢復(fù)窗口大小按鈕
    try:
      self.showMaximized() # 先實(shí)現(xiàn)窗口最大化
      self._MaximumButton.setText(b'\xef\x80\xb2'.decode("utf-8")) # 更改按鈕文本
      self._MaximumButton.setToolTip("恢復(fù)") # 更改按鈕提示
      self._MaximumButton.disconnect() # 斷開原本的信號(hào)槽連接
      self._MaximumButton.clicked.connect(self._changeMaxButton) # 重新連接信號(hào)和槽
    except:
      pass

  def _changeMaxButton(self):
    # 切換到最大化按鈕
    try:
      self.showNormal()
      self._MaximumButton.setText(b'\xef\x80\xb1'.decode("utf-8"))
      self._MaximumButton.setToolTip("最大化")
      self._MaximumButton.disconnect()
      self._MaximumButton.clicked.connect(self._changeNormalButton)
    except:
      pass

  def resizeEvent(self, QResizeEvent):
    # 自定義窗口調(diào)整大小事件
    self._TitleLabel.setFixedWidth(self.width()) # 將標(biāo)題標(biāo)簽始終設(shè)為窗口寬度
    # 分別移動(dòng)三個(gè)按鈕到正確的位置
    try:
      self._CloseButton.move(self.width() - self._CloseButton.width(), 0)
    except:
      pass
    try:
      self._MinimumButton.move(self.width() - (self._CloseButton.width() + 1) * 3 + 1, 0)
    except:
      pass
    try:
      self._MaximumButton.move(self.width() - (self._CloseButton.width() + 1) * 2 + 1, 0)
    except:
      pass
    # 重新調(diào)整邊界范圍以備實(shí)現(xiàn)鼠標(biāo)拖放縮放窗口大小,采用三個(gè)列表生成式生成三個(gè)列表
    self._right_rect = [QPoint(x, y) for x in range(self.width() - self._padding, self.width() + 1)
              for y in range(1, self.height() - self._padding)]
    self._bottom_rect = [QPoint(x, y) for x in range(1, self.width() - self._padding)
             for y in range(self.height() - self._padding, self.height() + 1)]
    self._corner_rect = [QPoint(x, y) for x in range(self.width() - self._padding, self.width() + 1)
                  for y in range(self.height() - self._padding, self.height() + 1)]

  def mousePressEvent(self, event):
    # 重寫鼠標(biāo)點(diǎn)擊的事件
    if (event.button() == Qt.LeftButton) and (event.pos() in self._corner_rect):
      # 鼠標(biāo)左鍵點(diǎn)擊右下角邊界區(qū)域
      self._corner_drag = True
      event.accept()
    elif (event.button() == Qt.LeftButton) and (event.pos() in self._right_rect):
      # 鼠標(biāo)左鍵點(diǎn)擊右側(cè)邊界區(qū)域
      self._right_drag = True
      event.accept()
    elif (event.button() == Qt.LeftButton) and (event.pos() in self._bottom_rect):
      # 鼠標(biāo)左鍵點(diǎn)擊下側(cè)邊界區(qū)域
      self._bottom_drag = True
      event.accept()
    elif (event.button() == Qt.LeftButton) and (event.y() < self._TitleLabel.height()):
      # 鼠標(biāo)左鍵點(diǎn)擊標(biāo)題欄區(qū)域
      self._move_drag = True
      self.move_DragPosition = event.globalPos() - self.pos()
      event.accept()

  def mouseMoveEvent(self, QMouseEvent):
    # 判斷鼠標(biāo)位置切換鼠標(biāo)手勢(shì)
    if QMouseEvent.pos() in self._corner_rect:
      self.setCursor(Qt.SizeFDiagCursor)
    elif QMouseEvent.pos() in self._bottom_rect:
      self.setCursor(Qt.SizeVerCursor)
    elif QMouseEvent.pos() in self._right_rect:
      self.setCursor(Qt.SizeHorCursor)
    else:
      self.setCursor(Qt.ArrowCursor)
    # 當(dāng)鼠標(biāo)左鍵點(diǎn)擊不放及滿足點(diǎn)擊區(qū)域的要求后,分別實(shí)現(xiàn)不同的窗口調(diào)整
    # 沒有定義左方和上方相關(guān)的5個(gè)方向,主要是因?yàn)閷?shí)現(xiàn)起來(lái)不難,但是效果很差,拖放的時(shí)候窗口閃爍,再研究研究是否有更好的實(shí)現(xiàn)
    if Qt.LeftButton and self._right_drag:
      # 右側(cè)調(diào)整窗口寬度
      self.resize(QMouseEvent.pos().x(), self.height())
      QMouseEvent.accept()
    elif Qt.LeftButton and self._bottom_drag:
      # 下側(cè)調(diào)整窗口高度
      self.resize(self.width(), QMouseEvent.pos().y())
      QMouseEvent.accept()
    elif Qt.LeftButton and self._corner_drag:
      # 右下角同時(shí)調(diào)整高度和寬度
      self.resize(QMouseEvent.pos().x(), QMouseEvent.pos().y())
      QMouseEvent.accept()
    elif Qt.LeftButton and self._move_drag:
      # 標(biāo)題欄拖放窗口位置
      self.move(QMouseEvent.globalPos() - self.move_DragPosition)
      QMouseEvent.accept()

  def mouseReleaseEvent(self, QMouseEvent):
    # 鼠標(biāo)釋放后,各扳機(jī)復(fù)位
    self._move_drag = False
    self._corner_drag = False
    self._bottom_drag = False
    self._right_drag = False


if __name__ == "__main__":
  from PyQt5.QtWidgets import QApplication
  import sys
  app = QApplication(sys.argv)
  app.setStyleSheet(open("./UnFrameStyle.qss").read())
  window = QUnFrameWindow()
  window.setCloseButton(True)
  window.setMinMaxButtons(True)
  window.show()
  sys.exit(app.exec_())

qss文件

/**********Title**********/
QTitleLabel{
    background-color: Gainsboro;
    font: 100 10pt;
}


/**********Button**********/
QTitleButton{
    background-color: rgba(255, 255, 255, 0);
    color: black;
    border: 0px;
    font: 100 10pt;
}
QTitleButton#MinMaxButton:hover{
    background-color: #D0D0D1;
    border: 0px;
    font: 100 10pt;
}
QTitleButton#CloseButton:hover{
    background-color: #D32424;
    color: white;
    border: 0px;
    font: 100 10pt;
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python裝飾器模式定義與用法分析

    Python裝飾器模式定義與用法分析

    這篇文章主要介紹了Python裝飾器模式定義與用法,結(jié)合實(shí)例形式分析了Python裝飾器模式的具體定義、使用方法及相關(guān)操作技巧,需要的朋友可以參考下
    2018-08-08
  • pycharm修改file type方式

    pycharm修改file type方式

    今天小編就為大家分享一篇pycharm修改file type方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2019-11-11
  • python動(dòng)態(tài)加載包的方法小結(jié)

    python動(dòng)態(tài)加載包的方法小結(jié)

    這篇文章主要介紹了python動(dòng)態(tài)加載包的方法,結(jié)合實(shí)例形式總結(jié)分析了Python動(dòng)態(tài)加載模塊,動(dòng)態(tài)增加屬性及動(dòng)態(tài)加載包的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2016-04-04
  • 基于Python的關(guān)鍵字監(jiān)控及告警

    基于Python的關(guān)鍵字監(jiān)控及告警

    這篇文章主要為大家詳細(xì)介紹了基于Python的關(guān)鍵字監(jiān)控及告警,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Django debug為True時(shí),css加載失敗的解決方案

    Django debug為True時(shí),css加載失敗的解決方案

    這篇文章主要介紹了Django debug為True時(shí),css加載失敗的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2021-04-04
  • pandas的排序、分組groupby及cumsum累計(jì)求和方式

    pandas的排序、分組groupby及cumsum累計(jì)求和方式

    這篇文章主要介紹了pandas的排序、分組groupby及cumsum累計(jì)求和方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • python 日志模塊 日志等級(jí)設(shè)置失效的解決方案

    python 日志模塊 日志等級(jí)設(shè)置失效的解決方案

    這篇文章主要介紹了python 日志模塊 日志等級(jí)設(shè)置失效的問題及解決方案,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • python 實(shí)現(xiàn)socket服務(wù)端并發(fā)的四種方式

    python 實(shí)現(xiàn)socket服務(wù)端并發(fā)的四種方式

    這篇文章主要介紹了python 實(shí)現(xiàn)socket服務(wù)端并發(fā)的四種方式,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2020-12-12
  • 通過Py2exe將自己的python程序打包成.exe/.app的方法

    通過Py2exe將自己的python程序打包成.exe/.app的方法

    這篇文章主要介紹了通過Py2exe將自己的python程序打包成.exe/.app的方法,需要的朋友可以參考下
    2018-05-05
  • 簡(jiǎn)單瞅瞅Python vars()內(nèi)置函數(shù)的實(shí)現(xiàn)

    簡(jiǎn)單瞅瞅Python vars()內(nèi)置函數(shù)的實(shí)現(xiàn)

    這篇文章主要介紹了簡(jiǎn)單瞅瞅Python vars()內(nèi)置函數(shù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09

最新評(píng)論