eric6/UI/NotificationWidget.py

changeset 7952
1849f61cf2b6
parent 7923
91e843545d9a
child 7956
7db67b70e6a8
equal deleted inserted replaced
7951:fa058239133f 7952:1849f61cf2b6
6 """ 6 """
7 Module implementing a Notification widget. 7 Module implementing a Notification widget.
8 """ 8 """
9 9
10 from PyQt5.QtCore import Qt, QTimer, QPoint 10 from PyQt5.QtCore import Qt, QTimer, QPoint
11 from PyQt5.QtGui import QPixmap 11 from PyQt5.QtWidgets import QFrame, QWidget, QVBoxLayout
12 from PyQt5.QtWidgets import QWidget 12
13 13 from .Ui_NotificationFrame import Ui_NotificationFrame
14 from .Ui_NotificationWidget import Ui_NotificationWidget
15 14
16 import Globals 15 import Globals
17 16 import Preferences
18 17
19 class NotificationWidget(QWidget, Ui_NotificationWidget): 18
19 class NotificationFrame(QFrame, Ui_NotificationFrame):
20 """ 20 """
21 Class implementing a Notification widget. 21 Class implementing a Notification widget.
22 """ 22 """
23 def __init__(self, icon, heading, text, parent=None):
24 """
25 Constructor
26
27 @param icon icon to be used
28 @type QPixmap
29 @param heading heading to be used
30 @type str
31 @param text text to be used
32 @type str
33 @param parent reference to the parent widget
34 @type QWidget
35 """
36 super(NotificationFrame, self).__init__(parent)
37 self.setupUi(self)
38
39 self.layout().setAlignment(
40 self.verticalLayout, Qt.AlignLeft | Qt.AlignVCenter)
41
42 self.icon.setPixmap(icon)
43 self.heading.setText(heading)
44 self.text.setText(text)
45
46 self.show()
47 self.adjustSize()
48
49
50 class NotificationWidget(QWidget):
51 """
52 Class implementing a Notification list widget.
53 """
23 def __init__(self, parent=None, setPosition=False): 54 def __init__(self, parent=None, setPosition=False):
24 """ 55 """
25 Constructor 56 Constructor
26 57
27 @param parent reference to the parent widget (QWidget) 58 @param parent reference to the parent widget
59 @type QWidget
28 @param setPosition flag indicating to set the display 60 @param setPosition flag indicating to set the display
29 position interactively (boolean) 61 position interactively
62 @type bool
30 """ 63 """
31 super(NotificationWidget, self).__init__(parent) 64 super(NotificationWidget, self).__init__(parent)
32 self.setupUi(self) 65
66 self.__layout = QVBoxLayout(self)
67 self.__layout.setContentsMargins(0, 0, 0, 0)
68 self.setLayout(self.__layout)
33 69
34 self.__timeout = 5000 70 self.__timeout = 5000
35 self.__icon = QPixmap()
36 self.__heading = ""
37 self.__text = ""
38 self.__dragPosition = QPoint() 71 self.__dragPosition = QPoint()
72 self.__timers = {}
39 73
40 self.__settingPosition = setPosition 74 self.__settingPosition = setPosition
41 75
42 flags = ( 76 flags = (
43 Qt.Tool | 77 Qt.Tool |
47 ) 81 )
48 if Globals.isWindowsPlatform(): 82 if Globals.isWindowsPlatform():
49 flags |= Qt.ToolTip 83 flags |= Qt.ToolTip
50 self.setWindowFlags(flags) 84 self.setWindowFlags(flags)
51 85
52 self.frame.layout().setAlignment(
53 self.verticalLayout, Qt.AlignLeft | Qt.AlignVCenter)
54
55 self.__timer = QTimer(self)
56 self.__timer.setSingleShot(True)
57 self.__timer.timeout.connect(self.close)
58
59 if self.__settingPosition: 86 if self.__settingPosition:
60 self.setCursor(Qt.OpenHandCursor) 87 self.setCursor(Qt.OpenHandCursor)
61 88
62 def setPixmap(self, icon): 89 def showNotification(self, icon, heading, text, timeout=0):
63 """ 90 """
64 Public method to set the icon for the notification. 91 Public method to show a notification.
65 92
66 @param icon icon to be used (QPixmap) 93 @param icon icon to be used
67 """ 94 @type QPixmap
68 self.__icon = QPixmap(icon) 95 @param heading heading to be used
69 96 @type str
70 def setHeading(self, heading): 97 @param text text to be used
71 """ 98 @type str
72 Public method to set the heading for the notification. 99 @param timeout timeout in seconds after which the notification is
73 100 to be removed (0 = do not remove until it is clicked on)
74 @param heading heading to be used (string) 101 """
75 """ 102 notificationFrame = NotificationFrame(icon, heading, text, self)
76 self.__heading = heading 103 self.__layout.addWidget(notificationFrame)
77 104
78 def setText(self, text): 105 self.show()
79 """ 106
80 Public method to set the text for the notification. 107 self.__adjustSizeAndPosition()
81 108
82 @param text text to be used (string) 109 if timeout:
83 """ 110 timer = QTimer()
84 self.__text = text 111 self.__timers[repr(notificationFrame)] = timer
85 112 timer.setSingleShot(True)
86 def setTimeout(self, timeout): 113 timer.timeout.connect(
87 """ 114 lambda: self.__removeNotification(notificationFrame)
88 Public method to set the timeout for the notification. 115 )
89 116 timer.setInterval(timeout * 1000)
90 @param timeout timeout to be used in seconds (0 = indefinitely) 117 timer.start()
91 @type int 118
92 """ 119 def __adjustSizeAndPosition(self):
93 self.__timeout = timeout * 1000 120 """
94 121 Private slot to adjust the notification list widget size and position.
95 def show(self): 122 """
96 """ 123 self.adjustSize()
97 Public method to show the notification.
98 """
99 self.icon.setPixmap(self.__icon)
100 self.heading.setText(self.__heading)
101 self.text.setText(self.__text)
102 124
103 if not self.__settingPosition: 125 if not self.__settingPosition:
104 self.__timer.stop() 126 pos = Preferences.getUI("NotificationPosition")
105 if self.__timeout > 0: 127 try:
106 self.__timer.setInterval(self.__timeout) 128 screen = self.screen()
107 self.__timer.start() 129 except AttributeError:
108 130 # < Qt 5.15
109 super(NotificationWidget, self).show() 131 from PyQt5.QtGui import QGuiApplication
110 132 screen = QGuiApplication.screenAt(pos)
111 sh = self.sizeHint() 133 screenGeom = screen.geometry()
112 self.resize(max(self.width(), sh.width()), sh.height()) 134
135 newX = pos.x()
136 newY = pos.y()
137 if newX < screenGeom.x():
138 newX = screenGeom.x()
139 if newY < screenGeom.y():
140 newY = screenGeom.y()
141 if newX + self.width() > screenGeom.width():
142 newX = screenGeom.width() - self.width()
143 if newY + self.height() > screenGeom.height():
144 newY = screenGeom.height() - self.height()
145
146 self.move(newX, newY)
147
148 def __removeNotification(self, notification):
149 """
150 Private method to remove a notification from the list.
151
152 @param notification reference to the notification to be removed
153 @type NotificationFrame
154 """
155 notification.hide()
156
157 # delete timer of an auto close notification
158 key = repr(notification)
159 if key in self.__timers:
160 self.__timers[key].stop()
161 del self.__timers[key]
162
163 # delete the notification
164 index = self.__layout.indexOf(notification)
165 self.__layout.takeAt(index)
166 notification.deleteLater()
167
168 if self.__layout.count():
169 self.__adjustSizeAndPosition()
170 else:
171 self.close()
113 172
114 def mousePressEvent(self, evt): 173 def mousePressEvent(self, evt):
115 """ 174 """
116 Protected method to handle presses of a mouse button. 175 Protected method to handle presses of a mouse button.
117 176
118 @param evt reference to the mouse event (QMouseEvent) 177 @param evt reference to the mouse event (QMouseEvent)
119 """ 178 """
120 if not self.__settingPosition: 179 if not self.__settingPosition:
121 self.close() 180 clickedLabel = self.childAt(evt.pos())
181 clickedNotification = clickedLabel.parent()
182 self.__removeNotification(clickedNotification)
122 return 183 return
123 184
124 if evt.button() == Qt.LeftButton: 185 if evt.button() == Qt.LeftButton:
125 self.__dragPosition = ( 186 self.__dragPosition = (
126 evt.globalPos() - self.frameGeometry().topLeft() 187 evt.globalPos() - self.frameGeometry().topLeft()

eric ide

mercurial