bec-widgets 2.14.0__py3-none-any.whl → 2.15.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- CHANGELOG.md +35 -0
- PKG-INFO +1 -1
- bec_widgets/widgets/containers/main_window/addons/scroll_label.py +110 -0
- bec_widgets/widgets/containers/main_window/main_window.py +125 -20
- {bec_widgets-2.14.0.dist-info → bec_widgets-2.15.1.dist-info}/METADATA +1 -1
- {bec_widgets-2.14.0.dist-info → bec_widgets-2.15.1.dist-info}/RECORD +10 -9
- pyproject.toml +1 -1
- {bec_widgets-2.14.0.dist-info → bec_widgets-2.15.1.dist-info}/WHEEL +0 -0
- {bec_widgets-2.14.0.dist-info → bec_widgets-2.15.1.dist-info}/entry_points.txt +0 -0
- {bec_widgets-2.14.0.dist-info → bec_widgets-2.15.1.dist-info}/licenses/LICENSE +0 -0
CHANGELOG.md
CHANGED
@@ -1,6 +1,41 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
3
|
|
4
|
+
## v2.15.1 (2025-06-16)
|
5
|
+
|
6
|
+
### Bug Fixes
|
7
|
+
|
8
|
+
- **main_window**: Added expiration timer for scroll label for ClientInfoMessage
|
9
|
+
([`187bf49`](https://github.com/bec-project/bec_widgets/commit/187bf493a5b18299a10939901b9ed7e308435092))
|
10
|
+
|
11
|
+
- **scroll_label**: Updating label during scrolling is done imminently, regardless scrolling
|
12
|
+
([`1612933`](https://github.com/bec-project/bec_widgets/commit/1612933dd9689f2bf480ad81811c051201a9ff70))
|
13
|
+
|
14
|
+
|
15
|
+
## v2.15.0 (2025-06-15)
|
16
|
+
|
17
|
+
### Bug Fixes
|
18
|
+
|
19
|
+
- **main_window**: Central widget cleanup check to not remove None
|
20
|
+
([`644be62`](https://github.com/bec-project/bec_widgets/commit/644be621f20cf09037da763f6217df9d1e4642bc))
|
21
|
+
|
22
|
+
### Features
|
23
|
+
|
24
|
+
- **main_window**: Main window can display the messages from the send_client_info as a scrolling
|
25
|
+
horizontal text; closes #700
|
26
|
+
([`0dec78a`](https://github.com/bec-project/bec_widgets/commit/0dec78afbaddbef98d20949d3a0ba4e0dc8529df))
|
27
|
+
|
28
|
+
### Refactoring
|
29
|
+
|
30
|
+
- **main_window**: App id is displayed as QLabel instead of message
|
31
|
+
([`57b9a57`](https://github.com/bec-project/bec_widgets/commit/57b9a57a631f267a8cb3622bf73035ffb15510e6))
|
32
|
+
|
33
|
+
### Testing
|
34
|
+
|
35
|
+
- **main_window**: Becmainwindow tests extended
|
36
|
+
([`30acc4c`](https://github.com/bec-project/bec_widgets/commit/30acc4c236bfbfed19f56512b264a52b4359e6c1))
|
37
|
+
|
38
|
+
|
4
39
|
## v2.14.0 (2025-06-13)
|
5
40
|
|
6
41
|
### Features
|
PKG-INFO
CHANGED
@@ -0,0 +1,110 @@
|
|
1
|
+
from qtpy.QtCore import QTimer
|
2
|
+
from qtpy.QtGui import QFontMetrics, QPainter
|
3
|
+
from qtpy.QtWidgets import QLabel
|
4
|
+
|
5
|
+
|
6
|
+
class ScrollLabel(QLabel):
|
7
|
+
"""A QLabel that scrolls its text horizontally across the widget."""
|
8
|
+
|
9
|
+
def __init__(self, parent=None, speed_ms=30, step_px=1, delay_ms=2000):
|
10
|
+
super().__init__(parent=parent)
|
11
|
+
self._offset = 0
|
12
|
+
self._text_width = 0
|
13
|
+
|
14
|
+
# scrolling timer (runs continuously once started)
|
15
|
+
self._timer = QTimer(self)
|
16
|
+
self._timer.setInterval(speed_ms)
|
17
|
+
self._timer.timeout.connect(self._scroll)
|
18
|
+
|
19
|
+
# delay‑before‑scroll timer (single‑shot)
|
20
|
+
self._delay_timer = QTimer(self)
|
21
|
+
self._delay_timer.setSingleShot(True)
|
22
|
+
self._delay_timer.setInterval(delay_ms)
|
23
|
+
self._delay_timer.timeout.connect(self._timer.start)
|
24
|
+
|
25
|
+
self._step_px = step_px
|
26
|
+
|
27
|
+
def setText(self, text):
|
28
|
+
"""
|
29
|
+
Overridden to ensure that new text replaces the current one
|
30
|
+
immediately.
|
31
|
+
If the label was already scrolling (or in its delay phase),
|
32
|
+
the next message starts **without** the extra delay.
|
33
|
+
"""
|
34
|
+
# Determine whether the widget was already in a scrolling cycle
|
35
|
+
was_scrolling = self._timer.isActive() or self._delay_timer.isActive()
|
36
|
+
|
37
|
+
super().setText(text)
|
38
|
+
|
39
|
+
fm = QFontMetrics(self.font())
|
40
|
+
self._text_width = fm.horizontalAdvance(text)
|
41
|
+
self._offset = 0
|
42
|
+
|
43
|
+
# Skip the delay when we were already scrolling
|
44
|
+
self._update_timer(skip_delay=was_scrolling)
|
45
|
+
|
46
|
+
def resizeEvent(self, event):
|
47
|
+
super().resizeEvent(event)
|
48
|
+
self._update_timer()
|
49
|
+
|
50
|
+
def _update_timer(self, *, skip_delay: bool = False):
|
51
|
+
"""
|
52
|
+
Decide whether to start or stop scrolling.
|
53
|
+
|
54
|
+
If the text is wider than the visible area, start a single‑shot
|
55
|
+
delay timer (2s by default). Scrolling begins only after this
|
56
|
+
delay. Any change (resize or new text) restarts the logic.
|
57
|
+
"""
|
58
|
+
needs_scroll = self._text_width > self.width()
|
59
|
+
|
60
|
+
if needs_scroll:
|
61
|
+
# Reset any running timers
|
62
|
+
if self._timer.isActive():
|
63
|
+
self._timer.stop()
|
64
|
+
if self._delay_timer.isActive():
|
65
|
+
self._delay_timer.stop()
|
66
|
+
|
67
|
+
self._offset = 0
|
68
|
+
|
69
|
+
# Start scrolling immediately when we should skip the delay,
|
70
|
+
# otherwise apply the configured delay_ms interval
|
71
|
+
if skip_delay:
|
72
|
+
self._timer.start()
|
73
|
+
else:
|
74
|
+
self._delay_timer.start()
|
75
|
+
else:
|
76
|
+
if self._delay_timer.isActive():
|
77
|
+
self._delay_timer.stop()
|
78
|
+
if self._timer.isActive():
|
79
|
+
self._timer.stop()
|
80
|
+
self.update()
|
81
|
+
|
82
|
+
def _scroll(self):
|
83
|
+
self._offset += self._step_px
|
84
|
+
if self._offset >= self._text_width:
|
85
|
+
self._offset = 0
|
86
|
+
self.update()
|
87
|
+
|
88
|
+
def paintEvent(self, event):
|
89
|
+
painter = QPainter(self)
|
90
|
+
painter.setRenderHint(QPainter.TextAntialiasing)
|
91
|
+
text = self.text()
|
92
|
+
if not text:
|
93
|
+
return
|
94
|
+
fm = QFontMetrics(self.font())
|
95
|
+
y = (self.height() + fm.ascent() - fm.descent()) // 2
|
96
|
+
if self._text_width <= self.width():
|
97
|
+
painter.drawText(0, y, text)
|
98
|
+
else:
|
99
|
+
x = -self._offset
|
100
|
+
gap = 50 # space between repeating text blocks
|
101
|
+
while x < self.width():
|
102
|
+
painter.drawText(x, y, text)
|
103
|
+
x += self._text_width + gap
|
104
|
+
|
105
|
+
def cleanup(self):
|
106
|
+
"""Stop all timers to prevent memory leaks."""
|
107
|
+
if self._timer.isActive():
|
108
|
+
self._timer.stop()
|
109
|
+
if self._delay_timer.isActive():
|
110
|
+
self._delay_timer.stop()
|
@@ -1,16 +1,17 @@
|
|
1
1
|
import os
|
2
2
|
|
3
|
-
from
|
3
|
+
from bec_lib.endpoints import MessageEndpoints
|
4
|
+
from qtpy.QtCore import QEvent, QSize, Qt, QTimer
|
4
5
|
from qtpy.QtGui import QAction, QActionGroup, QIcon
|
5
|
-
from qtpy.QtWidgets import QApplication, QMainWindow, QStyle
|
6
|
+
from qtpy.QtWidgets import QApplication, QFrame, QLabel, QMainWindow, QStyle, QVBoxLayout, QWidget
|
6
7
|
|
7
8
|
import bec_widgets
|
8
9
|
from bec_widgets.utils import UILoader
|
9
10
|
from bec_widgets.utils.bec_widget import BECWidget
|
10
11
|
from bec_widgets.utils.colors import apply_theme
|
11
|
-
from bec_widgets.utils.container_utils import WidgetContainerUtils
|
12
12
|
from bec_widgets.utils.error_popups import SafeSlot
|
13
13
|
from bec_widgets.utils.widget_io import WidgetHierarchy
|
14
|
+
from bec_widgets.widgets.containers.main_window.addons.scroll_label import ScrollLabel
|
14
15
|
from bec_widgets.widgets.containers.main_window.addons.web_links import BECWebLinksMixin
|
15
16
|
|
16
17
|
MODULE_PATH = os.path.dirname(bec_widgets.__file__)
|
@@ -36,6 +37,14 @@ class BECMainWindow(BECWidget, QMainWindow):
|
|
36
37
|
self._init_ui()
|
37
38
|
self._connect_to_theme_change()
|
38
39
|
|
40
|
+
# Connections to BEC Notifications
|
41
|
+
self.bec_dispatcher.connect_slot(
|
42
|
+
self.display_client_message, MessageEndpoints.client_info()
|
43
|
+
)
|
44
|
+
|
45
|
+
################################################################################
|
46
|
+
# MainWindow Elements Initialization
|
47
|
+
################################################################################
|
39
48
|
def _init_ui(self):
|
40
49
|
|
41
50
|
# Set the icon
|
@@ -43,40 +52,77 @@ class BECMainWindow(BECWidget, QMainWindow):
|
|
43
52
|
|
44
53
|
# Set Menu and Status bar
|
45
54
|
self._setup_menu_bar()
|
55
|
+
self._init_status_bar_widgets()
|
46
56
|
|
47
57
|
# BEC Specific UI
|
48
58
|
self.display_app_id()
|
49
59
|
|
60
|
+
def _init_status_bar_widgets(self):
|
61
|
+
"""
|
62
|
+
Prepare the BEC specific widgets in the status bar.
|
63
|
+
"""
|
64
|
+
status_bar = self.statusBar()
|
65
|
+
|
66
|
+
# Left: App‑ID label
|
67
|
+
self._app_id_label = QLabel()
|
68
|
+
self._app_id_label.setAlignment(
|
69
|
+
Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter
|
70
|
+
)
|
71
|
+
status_bar.addWidget(self._app_id_label)
|
72
|
+
|
73
|
+
# Add a separator after the app ID label
|
74
|
+
self._add_separator()
|
75
|
+
|
76
|
+
# Centre: Client‑info label (stretch=1 so it expands)
|
77
|
+
self._client_info_label = ScrollLabel()
|
78
|
+
self._client_info_label.setAlignment(
|
79
|
+
Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter
|
80
|
+
)
|
81
|
+
status_bar.addWidget(self._client_info_label, 1)
|
82
|
+
|
83
|
+
# Timer to automatically clear client messages once they expire
|
84
|
+
self._client_info_expire_timer = QTimer(self)
|
85
|
+
self._client_info_expire_timer.setSingleShot(True)
|
86
|
+
self._client_info_expire_timer.timeout.connect(lambda: self._client_info_label.setText(""))
|
87
|
+
|
88
|
+
def _add_separator(self):
|
89
|
+
"""
|
90
|
+
Add a vertically centred separator to the status bar.
|
91
|
+
"""
|
92
|
+
status_bar = self.statusBar()
|
93
|
+
|
94
|
+
# The actual line
|
95
|
+
line = QFrame()
|
96
|
+
line.setFrameShape(QFrame.VLine)
|
97
|
+
line.setFrameShadow(QFrame.Sunken)
|
98
|
+
line.setFixedHeight(status_bar.sizeHint().height() - 2)
|
99
|
+
|
100
|
+
# Wrapper to center the line vertically -> work around for QFrame not being able to center itself
|
101
|
+
wrapper = QWidget()
|
102
|
+
vbox = QVBoxLayout(wrapper)
|
103
|
+
vbox.setContentsMargins(0, 0, 0, 0)
|
104
|
+
vbox.addStretch()
|
105
|
+
vbox.addWidget(line, alignment=Qt.AlignHCenter)
|
106
|
+
vbox.addStretch()
|
107
|
+
wrapper.setFixedWidth(line.sizeHint().width())
|
108
|
+
|
109
|
+
status_bar.addWidget(wrapper)
|
110
|
+
|
50
111
|
def _init_bec_icon(self):
|
51
112
|
icon = self.app.windowIcon()
|
52
113
|
if icon.isNull():
|
53
|
-
print("No icon is set, setting default icon")
|
54
114
|
icon = QIcon()
|
55
115
|
icon.addFile(
|
56
116
|
os.path.join(MODULE_PATH, "assets", "app_icons", "bec_widgets_icon.png"),
|
57
117
|
size=QSize(48, 48),
|
58
118
|
)
|
59
119
|
self.app.setWindowIcon(icon)
|
60
|
-
else:
|
61
|
-
print("An icon is set")
|
62
120
|
|
63
121
|
def load_ui(self, ui_file):
|
64
122
|
loader = UILoader(self)
|
65
123
|
self.ui = loader.loader(ui_file)
|
66
124
|
self.setCentralWidget(self.ui)
|
67
125
|
|
68
|
-
def display_app_id(self):
|
69
|
-
"""
|
70
|
-
Display the app ID in the status bar.
|
71
|
-
"""
|
72
|
-
if self.bec_dispatcher.cli_server is None:
|
73
|
-
status_message = "Not connected"
|
74
|
-
else:
|
75
|
-
# Get the server ID from the dispatcher
|
76
|
-
server_id = self.bec_dispatcher.cli_server.gui_id
|
77
|
-
status_message = f"App ID: {server_id}"
|
78
|
-
self.statusBar().showMessage(status_message)
|
79
|
-
|
80
126
|
def _fetch_theme(self) -> str:
|
81
127
|
return self.app.theme.theme
|
82
128
|
|
@@ -164,8 +210,52 @@ class BECMainWindow(BECWidget, QMainWindow):
|
|
164
210
|
help_menu.addAction(widgets_docs)
|
165
211
|
help_menu.addAction(bug_report)
|
166
212
|
|
213
|
+
################################################################################
|
214
|
+
# Status Bar Addons
|
215
|
+
################################################################################
|
216
|
+
def display_app_id(self):
|
217
|
+
"""
|
218
|
+
Display the app ID in the status bar.
|
219
|
+
"""
|
220
|
+
if self.bec_dispatcher.cli_server is None:
|
221
|
+
status_message = "Not connected"
|
222
|
+
else:
|
223
|
+
# Get the server ID from the dispatcher
|
224
|
+
server_id = self.bec_dispatcher.cli_server.gui_id
|
225
|
+
status_message = f"App ID: {server_id}"
|
226
|
+
self._app_id_label.setText(status_message)
|
227
|
+
|
228
|
+
@SafeSlot(dict, dict)
|
229
|
+
def display_client_message(self, msg: dict, meta: dict):
|
230
|
+
"""
|
231
|
+
Display a client message in the status bar.
|
232
|
+
|
233
|
+
Args:
|
234
|
+
msg(dict): The message to display, should contain:
|
235
|
+
meta(dict): Metadata about the message, usually empty.
|
236
|
+
"""
|
237
|
+
# self._client_info_label.setText("")
|
238
|
+
message = msg.get("message", "")
|
239
|
+
expiration = msg.get("expire", 0) # 0 → never expire
|
240
|
+
self._client_info_label.setText(message)
|
241
|
+
|
242
|
+
# Restart the expiration timer if necessary
|
243
|
+
if hasattr(self, "_client_info_expire_timer") and self._client_info_expire_timer.isActive():
|
244
|
+
self._client_info_expire_timer.stop()
|
245
|
+
if expiration and expiration > 0:
|
246
|
+
self._client_info_expire_timer.start(int(expiration * 1000))
|
247
|
+
|
248
|
+
################################################################################
|
249
|
+
# General and Cleanup Methods
|
250
|
+
################################################################################
|
167
251
|
@SafeSlot(str)
|
168
252
|
def change_theme(self, theme: str):
|
253
|
+
"""
|
254
|
+
Change the theme of the application.
|
255
|
+
|
256
|
+
Args:
|
257
|
+
theme(str): The theme to apply, either "light" or "dark".
|
258
|
+
"""
|
169
259
|
apply_theme(theme)
|
170
260
|
|
171
261
|
def event(self, event):
|
@@ -175,8 +265,9 @@ class BECMainWindow(BECWidget, QMainWindow):
|
|
175
265
|
|
176
266
|
def cleanup(self):
|
177
267
|
central_widget = self.centralWidget()
|
178
|
-
central_widget
|
179
|
-
|
268
|
+
if central_widget is not None:
|
269
|
+
central_widget.close()
|
270
|
+
central_widget.deleteLater()
|
180
271
|
if not isinstance(central_widget, BECWidget):
|
181
272
|
# if the central widget is not a BECWidget, we need to call the cleanup method
|
182
273
|
# of all widgets whose parent is the current BECMainWindow
|
@@ -187,8 +278,22 @@ class BECMainWindow(BECWidget, QMainWindow):
|
|
187
278
|
child.cleanup()
|
188
279
|
child.close()
|
189
280
|
child.deleteLater()
|
281
|
+
|
282
|
+
if hasattr(self, "_client_info_expire_timer") and self._client_info_expire_timer.isActive():
|
283
|
+
self._client_info_expire_timer.stop()
|
284
|
+
# Status bar widgets cleanup
|
285
|
+
self._client_info_label.cleanup()
|
190
286
|
super().cleanup()
|
191
287
|
|
192
288
|
|
193
289
|
class UILaunchWindow(BECMainWindow):
|
194
290
|
RPC = True
|
291
|
+
|
292
|
+
|
293
|
+
if __name__ == "__main__":
|
294
|
+
import sys
|
295
|
+
|
296
|
+
app = QApplication(sys.argv)
|
297
|
+
main_window = UILaunchWindow()
|
298
|
+
main_window.show()
|
299
|
+
sys.exit(app.exec())
|
@@ -2,11 +2,11 @@
|
|
2
2
|
.gitlab-ci.yml,sha256=1nMYldzVk0tFkBWYTcUjumOrdSADASheWOAc0kOFDYs,9509
|
3
3
|
.pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
|
4
4
|
.readthedocs.yaml,sha256=ivqg3HTaOxNbEW3bzWh9MXAkrekuGoNdj0Mj3SdRYuw,639
|
5
|
-
CHANGELOG.md,sha256=
|
5
|
+
CHANGELOG.md,sha256=BGd-zRzWE7KTMPqaa3CPc_JyROlDYD5DZ95PQMUjKzQ,301055
|
6
6
|
LICENSE,sha256=Daeiu871NcAp8uYi4eB_qHgvypG-HX0ioRQyQxFwjeg,1531
|
7
|
-
PKG-INFO,sha256=
|
7
|
+
PKG-INFO,sha256=gTntcRGnhQPrg5vyZPQgQOjlhlKK-Y5r__82UIsiJXA,1252
|
8
8
|
README.md,sha256=oY5Jc1uXehRASuwUJ0umin2vfkFh7tHF-LLruHTaQx0,3560
|
9
|
-
pyproject.toml,sha256=
|
9
|
+
pyproject.toml,sha256=HMdAYHc2bpPYaYYmgAWgbC3HiiptNXdnHyTMOQmdXg8,2827
|
10
10
|
.git_hooks/pre-commit,sha256=n3RofIZHJl8zfJJIUomcMyYGFi_rwq4CC19z0snz3FI,286
|
11
11
|
.github/pull_request_template.md,sha256=F_cJXzooWMFgMGtLK-7KeGcQt0B4AYFse5oN0zQ9p6g,801
|
12
12
|
.github/ISSUE_TEMPLATE/bug_report.yml,sha256=WdRnt7HGxvsIBLzhkaOWNfg8IJQYa_oV9_F08Ym6znQ,1081
|
@@ -121,8 +121,9 @@ bec_widgets/widgets/containers/dock/register_dock_area.py,sha256=L7BL4qknCjtqsDP
|
|
121
121
|
bec_widgets/widgets/containers/layout_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
122
122
|
bec_widgets/widgets/containers/layout_manager/layout_manager.py,sha256=V7s8mtB3VLPstyGVaR9YKcoTVlfMMOYNpIJUsw2WQVc,35198
|
123
123
|
bec_widgets/widgets/containers/main_window/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
124
|
-
bec_widgets/widgets/containers/main_window/main_window.py,sha256
|
124
|
+
bec_widgets/widgets/containers/main_window/main_window.py,sha256=-qDkmL-DO6wJV1EnZdauGXzAh_nwRJJPWed1eSJR80Y,10425
|
125
125
|
bec_widgets/widgets/containers/main_window/addons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
126
|
+
bec_widgets/widgets/containers/main_window/addons/scroll_label.py,sha256=RDiLWDkIrXFAdCXNMm6eE6U9h3zjfPhJDqVwdV8aSL8,3743
|
126
127
|
bec_widgets/widgets/containers/main_window/addons/web_links.py,sha256=d5OgzgI9zb-NAC0pOGanOtJX3nZoe4x8QuQTw-_hK_8,434
|
127
128
|
bec_widgets/widgets/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
128
129
|
bec_widgets/widgets/control/buttons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -408,8 +409,8 @@ bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.py,sha256=O
|
|
408
409
|
bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.pyproject,sha256=Lbi9zb6HNlIq14k6hlzR-oz6PIFShBuF7QxE6d87d64,34
|
409
410
|
bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button_plugin.py,sha256=CzChz2SSETYsR8-36meqWnsXCT-FIy_J_xeU5coWDY8,1350
|
410
411
|
bec_widgets/widgets/utility/visual/dark_mode_button/register_dark_mode_button.py,sha256=rMpZ1CaoucwobgPj1FuKTnt07W82bV1GaSYdoqcdMb8,521
|
411
|
-
bec_widgets-2.
|
412
|
-
bec_widgets-2.
|
413
|
-
bec_widgets-2.
|
414
|
-
bec_widgets-2.
|
415
|
-
bec_widgets-2.
|
412
|
+
bec_widgets-2.15.1.dist-info/METADATA,sha256=gTntcRGnhQPrg5vyZPQgQOjlhlKK-Y5r__82UIsiJXA,1252
|
413
|
+
bec_widgets-2.15.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
414
|
+
bec_widgets-2.15.1.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
|
415
|
+
bec_widgets-2.15.1.dist-info/licenses/LICENSE,sha256=Daeiu871NcAp8uYi4eB_qHgvypG-HX0ioRQyQxFwjeg,1531
|
416
|
+
bec_widgets-2.15.1.dist-info/RECORD,,
|
pyproject.toml
CHANGED
File without changes
|
File without changes
|
File without changes
|