|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2012 - 2022 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the snapshot timer widget. |
|
8 """ |
|
9 |
|
10 from PyQt6.QtCore import pyqtSignal, Qt, QTimer, QRect |
|
11 from PyQt6.QtGui import QPainter, QPalette |
|
12 from PyQt6.QtWidgets import QWidget, QApplication, QToolTip |
|
13 |
|
14 |
|
15 class SnapshotTimer(QWidget): |
|
16 """ |
|
17 Class implementing the snapshot timer widget. |
|
18 |
|
19 @signal timeout() emitted after the timer timed out |
|
20 """ |
|
21 timeout = pyqtSignal() |
|
22 |
|
23 def __init__(self): |
|
24 """ |
|
25 Constructor |
|
26 """ |
|
27 super().__init__(None) |
|
28 |
|
29 self.setWindowFlags( |
|
30 Qt.WindowType.WindowStaysOnTopHint | |
|
31 Qt.WindowType.FramelessWindowHint | |
|
32 Qt.WindowType.X11BypassWindowManagerHint |
|
33 ) |
|
34 |
|
35 self.__timer = QTimer() |
|
36 self.__textRect = QRect() |
|
37 self.__time = 0 |
|
38 self.__length = 0 |
|
39 self.__toggle = True |
|
40 |
|
41 # text is taken from paintEvent with maximum number plus some margin |
|
42 try: |
|
43 fmWidth = self.fontMetrics().horizontalAdvance(self.tr( |
|
44 "Snapshot will be taken in %n seconds", "", 99)) |
|
45 except AttributeError: |
|
46 fmWidth = self.fontMetrics().width(self.tr( |
|
47 "Snapshot will be taken in %n seconds", "", 99)) |
|
48 self.resize(fmWidth + 6, self.fontMetrics().height() + 4) |
|
49 |
|
50 self.__timer.timeout.connect(self.__bell) |
|
51 |
|
52 def start(self, seconds): |
|
53 """ |
|
54 Public method to start the timer. |
|
55 |
|
56 @param seconds timeout value (integer) |
|
57 """ |
|
58 screenGeom = QApplication.screens()[0].geometry() |
|
59 self.move(screenGeom.width() // 2 - self.size().width() // 2, |
|
60 screenGeom.top()) |
|
61 self.__toggle = True |
|
62 self.__time = 0 |
|
63 self.__length = seconds |
|
64 self.__timer.start(1000) |
|
65 self.show() |
|
66 |
|
67 def stop(self): |
|
68 """ |
|
69 Public method to stop the timer. |
|
70 """ |
|
71 self.setVisible(False) |
|
72 self.hide() |
|
73 self.__timer.stop() |
|
74 |
|
75 def __bell(self): |
|
76 """ |
|
77 Private slot handling timer timeouts. |
|
78 """ |
|
79 if self.__time == self.__length - 1: |
|
80 self.hide() |
|
81 else: |
|
82 if self.__time == self.__length: |
|
83 self.__timer.stop() |
|
84 self.timeout.emit() |
|
85 |
|
86 self.__time += 1 |
|
87 self.__toggle = not self.__toggle |
|
88 self.update() |
|
89 |
|
90 def paintEvent(self, evt): |
|
91 """ |
|
92 Protected method handling paint events. |
|
93 |
|
94 @param evt paint event (QPaintEvent) |
|
95 """ |
|
96 painter = QPainter(self) |
|
97 |
|
98 if self.__time < self.__length: |
|
99 pal = QToolTip.palette() |
|
100 textBackgroundColor = pal.color(QPalette.ColorGroup.Active, |
|
101 QPalette.ColorRole.Base) |
|
102 if self.__toggle: |
|
103 textColor = pal.color(QPalette.ColorGroup.Active, |
|
104 QPalette.ColorRole.Text) |
|
105 else: |
|
106 textColor = pal.color(QPalette.ColorGroup.Active, |
|
107 QPalette.ColorRole.Base) |
|
108 painter.setPen(textColor) |
|
109 painter.setBrush(textBackgroundColor) |
|
110 helpText = self.tr("Snapshot will be taken in %n seconds", "", |
|
111 self.__length - self.__time) |
|
112 textRect = painter.boundingRect( |
|
113 self.rect().adjusted(2, 2, -2, -2), |
|
114 Qt.AlignmentFlag.AlignHCenter | Qt.TextFlag.TextSingleLine, |
|
115 helpText) |
|
116 painter.drawText( |
|
117 textRect, |
|
118 Qt.AlignmentFlag.AlignHCenter | Qt.TextFlag.TextSingleLine, |
|
119 helpText) |
|
120 |
|
121 def enterEvent(self, evt): |
|
122 """ |
|
123 Protected method handling the mouse cursor entering the widget. |
|
124 |
|
125 @param evt enter event (QEvent) |
|
126 """ |
|
127 screenGeom = QApplication.screens()[0].geometry() |
|
128 if self.x() == screenGeom.left(): |
|
129 self.move( |
|
130 screenGeom.x() + |
|
131 (screenGeom.width() // 2 - self.size().width() // 2), |
|
132 screenGeom.top()) |
|
133 else: |
|
134 self.move(screenGeom.topLeft()) |