国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Python > 正文

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

2020-02-22 23:45:03
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

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

先做個(gè)筆記

py文件

#!/usr/bin/env python#-*- coding:utf-8 -*-from PyQt5.QtWidgets import QWidget, QLabel, QPushButton, QVBoxLayoutfrom PyQt5.QtCore import Qt, QPointfrom PyQt5.QtGui import QFont, QCursorclass 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)整    # 沒(méi)有定義左方和上方相關(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 = Falseif __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_())            
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 交城县| 双柏县| 墨竹工卡县| 东平县| 金寨县| 英超| 马公市| 永靖县| 塘沽区| 栖霞市| 平昌县| 察哈| 泸西县| 瓦房店市| 阿城市| 永胜县| 门头沟区| 抚顺市| 固阳县| 潼南县| 昌邑市| 明星| 临海市| 明水县| 金湖县| 临夏县| 潢川县| 都兰县| 宜都市| 庄浪县| 巴林左旗| 民权县| 栖霞市| 汝阳县| 白玉县| 南乐县| 铁岭市| 怀仁县| 旬阳县| 龙州县| 当涂县|