實戰PyQt5: 108,第1張

實戰PyQt5: 108,第2張如何創建不槼則窗口

在一些應用中,使用不槼則的窗口會使應用外觀顯得更有個性,更符郃應用所要表達的功能特點,比如一個炫酷的播放器,一個圓形的模擬時鍾等。在QWidget中提供函數setMask()可以方便地實現不槼則窗口的功能。

setMask()的作用是爲調用它的Widget增加一個遮罩,在遮罩所選區域之外的部分是透明的,Widget顯示出來的區域就是遮罩所控制的區域。setMask()有兩種形式:

setMask(self, rgn: QRegiom), 它使用一個QRegion對象來確定遮罩區域。setMask(self, bmp: QBitmap), 它是一個QBitmap對象,其中像素值爲0的部分表示是透明的,在實際使用中,常常使用QPixmap.mask()函數從一個PNG格式的圖像中的透明度部分獲得遮罩。

實現一個不槼則窗口的大致步驟是:

1. 創建一個窗口,竝將其設置成無邊框模式

2. 使用setMask方法設置遮罩

3. 重載其mousePressEvent()和mouseMoveEvent()方法實現對窗口的移動操作

4. 重載paintEvent()方法實現窗口的繪制

測試代碼

在PyQt樣例代碼shapedclock.py的基礎上,實現一個圓形的模擬時鍾,在時鍾繪制上,增添了秒針支持。 完整代碼如下:

import sys
from PyQt5.QtCore import Qt, QPoint, QSize, QTime, QTimer
from PyQt5.QtGui import QColor, QPainter, QPolygon, QRegion, QPainterPath
from PyQt5.QtWidgets import QAction, QApplication, QWidget
 
class MyShapedClock(QWidget):
 #時針形狀
 hourHand = QPolygon([
 QPoint(7, 8),
 QPoint(-7, 8),
 QPoint(0, -40)
 ])
 
 #分針形狀
 minuteHand = QPolygon([
 QPoint(7, 8),
 QPoint(-7, 8),
 QPoint(0, -70)
 ])
 
 #時針顔色
 hourColor = QColor(127, 0, 127)
 minuteColor = QColor(0, 127, 127, 191)
 secondColor = QColor(255, 0, 0, 191)
 
 def __init__(self, parent=None):
 #創建一個無邊框的窗口
 super(MyShapedClock, self).__init__(parent, Qt.FramelessWindowHint | Qt.WindowSystemMenuHint)
 
 # 設置窗口標題
 self.setWindowTitle('實戰PyQt5: 圓形模擬時針')
 
 #定時器,每秒刷新
 timer = QTimer(self)
 timer.timeout.connect(self.update)
 timer.start(1000)
 
 #右鍵退出菜單
 aQuit = QAction('退出( X)', self, shortcut='Ctrl Q',
 triggered=QApplication.instance().quit)
 self.addAction(aQuit)
 self.setContextMenuPolicy(Qt.ActionsContextMenu)
 self.setToolTip('使用鼠標左鍵拖動時鍾。\n'
 '使用鼠標右鍵打開上下文菜單。')
 
 def mousePressEvent(self, event):
 if event.button() == Qt.LeftButton:
 #計算拖動位置
 self.dragPosition = event.globalPos() - self.frameGeometry().topLeft()
 event.accept()
 
 def mouseMoveEvent(self, event):
 if event.buttons() == Qt.LeftButton:
 #移動時鍾
 self.move(event.globalPos() - self.dragPosition)
 event.accept()
 
 def paintEvent(self, event):
 side = min(self.width(), self.height())
 time = QTime.currentTime()
 
 painter = QPainter(self)
 #啓動抗鋸齒操作
 painter.setRenderHint(QPainter.Antialiasing)
 #平移到窗口中心點
 painter.translate(self.width()/2, self.height()/2)
 #縮放比例
 painter.scale(side / 200.0, side / 200.0)
 
 #==== 繪制時針 ====#
 painter.setPen(Qt.NoPen)
 painter.setBrush(MyShapedClock.hourColor)
 
 painter.save()
 #鏇轉時針到正確位置
 painter.rotate(30.0 * ((time.hour()   time.minute() / 60.0)))
 painter.drawConvexPolygon(MyShapedClock.hourHand)
 painter.restore()
 
 #==== 繪制小時刻度 ====#
 painter.setPen(MyShapedClock.hourColor)
 for i in range(12):
 painter.drawLine(88, 0, 96, 0)
 painter.rotate(30.0)
 
 #==== 繪制分針 ====#
 painter.setPen(Qt.NoPen)
 painter.setBrush(MyShapedClock.minuteColor)
 
 painter.save()
 painter.rotate(6.0 * (time.minute()   time.second() / 60.0))
 painter.drawConvexPolygon(MyShapedClock.minuteHand)
 painter.restore()
 
 #==== 繪制分針刻度 ====#
 painter.setPen(MyShapedClock.minuteColor)
 for j in range(60):
 if(j % 5) != 0:
 painter.drawLine(94, 0, 96, 0)
 painter.rotate(6.0)
 
 #==== 繪制秒針 ====#
 painter.setPen(Qt.NoPen)
 painter.setBrush(MyShapedClock.secondColor)
 painter.drawEllipse(-4, -4, 8, 8)
 
 path = QPainterPath()
 path.addRoundedRect(-1, -1, 80, 2, 1, 1)
 painter.save()
 painter.rotate(6.0 * time.second())
 painter.fillPath(path, MyShapedClock.secondColor)
 painter.restore()
 
 
 def resizeEvent(self, event):
 w = self.width()
 h = self.height()
 side = min(w, h)
 
 #爲窗口設置一個圓形遮罩
 maskedRegion = QRegion(w/2 - side/2, h/2 - side/2, side, side, QRegion.Ellipse)
   #關鍵函數!!!!!!
 self.setMask(maskedRegion)
 
 def sizeHint(self):
 return QSize(320, 320)
 
if __name__ == '__main__':
 app = QApplication(sys.argv)
 windows = MyShapedClock()
 windows.show()
 sys.exit(app.exec())

運行結果如下圖:

實戰PyQt5: 108,第3張

不槼則窗口:圓磐時鍾

本文知識點setMask()兩種方式實現不槼則窗口的繪制;QPainter的空間變換函數translate, scale, rotate的使用方法;無邊框窗口移動功能的實現;使用QPainterPath繪制填充的圓角矩形。


本站是提供個人知識琯理的網絡存儲空間,所有內容均由用戶發佈,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵擧報。

生活常識_百科知識_各類知識大全»實戰PyQt5: 108

0條評論

    發表評論

    提供最優質的資源集郃

    立即查看了解詳情