Setting Window Background Transparent, Always on Top, and Borderless in PyQt5
#
self.setAttribute(Qt.WA_TranslucentBackground) # Window background transparent
self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool) # Window always on top, borderless, no icon in taskbar
Without a border, the mouse cannot drag, so rewrite mouse events to drag the widget:
# Rewrite move event to allow mouse dragging
def mouseMoveEvent(self, e: QMouseEvent):
if self._tracking:
self._endPos = e.pos() - self._startPos
self.move(self.pos() + self._endPos)
def mousePressEvent(self, e: QMouseEvent):
if e.button() == Qt.LeftButton:
self._startPos = QPoint(e.x(), e.y())
self._tracking = True
def mouseReleaseEvent(self, e: QMouseEvent):
if e.button() == Qt.LeftButton:
self._tracking = False
self._startPos = None
self._endPos = None
Complete:
# -*- coding: utf-8 -*-
import PyQt5
import sys
import cv2
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from UI import Ui_MainWindow
class MyWindow(QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setupUi(self)
self.setAttribute(Qt.WA_TranslucentBackground) # Window background transparent
self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool) # Window always on top, borderless, no icon in taskbar
def mouseMoveEvent(self, e: QMouseEvent): # Rewrite move event
if self._tracking:
self._endPos = e.pos() - self._startPos
self.move(self.pos() + self._endPos)
def mousePressEvent(self, e: QMouseEvent):
if e.button() == Qt.LeftButton:
self._startPos = QPoint(e.x(), e.y())
self._tracking = True
def mouseReleaseEvent(self, e: QMouseEvent):
if e.button() == Qt.LeftButton:
self._tracking = False
self._startPos = None
self._endPos = None
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWindow = MyWindow()
mainWindow.show()
sys.exit(app.exec_())
Using PyQt5 to Draw a Pointer Clock Widget#
The code is as follows:
# -*- coding:utf-8 -*-
# Using PyQt5 to create a pointer clock to display the current time
# I wanted to achieve this functionality, but there were no ready-made components in PyQt5, so I thought I could only implement it through drawing.
# When it comes to drawing, the turtle framework is undoubtedly the most common choice, but it can also be achieved using PyQt5's QPainter component. Moreover, the final result is quite beautiful.
# Implementation idea: Use PyQt5's QPainter component to draw the clock face, and then continuously change the display position of the current time on the clock face using a timer.
# This ultimately achieves a pointer clock that keeps moving.
# Like the previous UI application, we still use these three UI-related component libraries.
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
# This time we used a new mathematical calculation library because it involves data calculation.
from math import *
# Application operation related modules
import sys
class PointerClock(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Dynamic Pointer Clock")
self.timer = QTimer()
self.setAttribute(Qt.WA_TranslucentBackground) # Window background transparent
self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool) # Window always on top, borderless, no icon in taskbar
# Set up window timer
self.timer.timeout.connect(self.update)
self.timer.start(1000)
# Rewrite move event to allow mouse dragging
def mouseMoveEvent(self, e: QMouseEvent):
if self._tracking:
self._endPos = e.pos() - self._startPos
self.move(self.pos() + self._endPos)
def mousePressEvent(self, e: QMouseEvent):
if e.button() == Qt.LeftButton:
self._startPos = QPoint(e.x(), e.y())
self._tracking = True
def mouseReleaseEvent(self, e: QMouseEvent):
if e.button() == Qt.LeftButton:
self._tracking = False
self._startPos = None
self._endPos = None
def paintEvent(self, event):
'''
Refresh the pointer image in real-time
:param event:
:return:
'''
'''Define the coordinates for hours, minutes, and seconds'''
'''
QPoint(int x, int y); Create a coordinate point, x and y represent the horizontal and vertical coordinates respectively
'''
hour_point = [QPoint(7, 8), QPoint(-7, 8), QPoint(0, -30)]
min_point = [QPoint(7, 8), QPoint(-7, 8), QPoint(0, -65)]
secn_point = [QPoint(7, 8), QPoint(-7, 8), QPoint(0, -80)]
'''Define three colors for the three pointers'''
hour_color = QColor(182, 98, 0, 182)
min_color = QColor(0, 130, 130, 155)
sec_color = QColor(0, 155, 227, 155)
'''Get the minimum width and height of the QWidget object'''
min_size = min(self.width(), self.height())
painter = QPainter(self) # Create a drawing object for the coordinate system
painter.setRenderHint(QPainter.Antialiasing)
# Use the center of the QWidget object as the center coordinate point for drawing
painter.translate(self.width() / 2, self.height() / 2)
# Scale the size
painter.scale(int(min_size / 200), int(min_size / 200))
# Save state
painter.save()
'''Draw the time scale lines on the clock face'''
for a in range(0, 60):
if (a % 5) != 0:
# Draw a scale line for minutes every 1/60
painter.setPen(min_color)
painter.drawLine(92, 0, 96, 0)
else:
# Draw a scale line for hours every 5/60
painter.setPen(hour_color)
painter.drawLine(88, 0, 96, 0) # Draw hour scale line
# Rotate 6 degrees every minute
painter.rotate(360 / 60)
# Restore state
painter.restore()
'''Draw the numbers on the clock face'''
# Save state
painter.save()
# Get font object
font = painter.font()
# Set bold
font.setBold(True)
painter.setFont(font)
# Get font size
font_size = font.pointSize()
# Set the previously defined color
painter.setPen(hour_color)
hour_num = 0
radius = 100
for i in range(0, 12):
# According to the 12-hour system, draw an hour number every three hours, need to iterate 4 times
hour_num = i + 3 # According to QT-Qpainter's coordinate system, the 3-hour scale line corresponds to the 0-degree axis
if hour_num > 12:
hour_num = hour_num - 12
# Calculate the x and y positions for writing the hour number based on the font size
x = radius * 0.8 * cos(i * 30 * pi / 180.0) - font_size
y = radius * 0.8 * sin(i * 30 * pi / 180.0) - font_size / 2.0
width = font_size * 2
height = font_size
painter.drawText(QRectF(x, y, width, height), Qt.AlignCenter, str(hour_num))
# Restore state
painter.restore()
'''Draw the hour, minute, and second hands on the clock face'''
# Get the current time
time = QTime.currentTime()
# Draw hour hand
painter.save()
# Remove outline
painter.setPen(Qt.NoPen)
# Set hour hand color
painter.setBrush(hour_color)
# Rotate hour hand counterclockwise
painter.rotate(30 * (time.hour() + time.minute() / 60))
# Draw hour hand
painter.drawConvexPolygon(QPolygonF(hour_point))
# Restore state
painter.restore()
# Draw minute hand
painter.save()
# Remove outline
painter.setPen(Qt.NoPen)
# Set minute hand color
painter.setBrush(min_color)
# Rotate minute hand counterclockwise
painter.rotate(6 * (time.minute() + time.second() / 60))
# Draw minute hand
painter.drawConvexPolygon(QPolygonF(min_point))
# Restore state
painter.restore()
# Draw second hand
painter.save()
# Remove outline
painter.setPen(Qt.NoPen)
# Set second hand color
painter.setBrush(sec_color)
# Rotate second hand counterclockwise
painter.rotate(6 * time.second())
# Draw second hand
painter.drawConvexPolygon(QPolygonF(secn_point))
# Restore state
painter.restore()
if __name__ == "__main__":
app = QApplication(sys.argv)
form = PointerClock()
form.show()
app.exec_()