SwiftGUI 0.11.19__tar.gz → 0.11.20__tar.gz
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.
- {swiftgui-0.11.19 → swiftgui-0.11.20}/PKG-INFO +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/pyproject.toml +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Base.py +49 -3
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Canvas_Elements/Text.py +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Combined_Elements/BaseCombinedElement.py +6 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Combined_Elements/Form.py +104 -43
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Examples/AllElements.py +9 -6
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Extended_Elements/Table.py +3 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/GlobalOptions.py +11 -1
- swiftgui-0.11.20/src/SwiftGUI/Popups/TooltipPopup.py +41 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Popups/__init__.py +1 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Themes/FourColors.py +3 -0
- swiftgui-0.11.20/src/SwiftGUI/Tooltips.py +112 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Button.py +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Checkbox.py +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Combobox.py +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Frame.py +3 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Input.py +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Listbox.py +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Radiobutton.py +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Scale.py +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Spinbox.py +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Text.py +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/TextField.py +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Treeview.py +1 -1
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Windows.py +34 -2
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/__init__.py +1 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/LICENSE +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/README.md +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/BasePopup.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Canvas_Elements/Arc.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Canvas_Elements/Bitmap.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Canvas_Elements/Element.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Canvas_Elements/Image.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Canvas_Elements/Line.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Canvas_Elements/Oval.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Canvas_Elements/Polygon.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Canvas_Elements/Rectangle.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Canvas_Elements/_Base.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Canvas_Elements/__init__.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Colors.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Combined_Elements/Calendar.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Combined_Elements/Console.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Combined_Elements/MultistateButton.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Compat.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Debug.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/DecoratorKeys.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/ElementFlags.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Events.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Examples/AllThemes.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Examples/GlobalOptionBrowser.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Examples/Previews.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Examples/__init__.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Exceptions.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Extended_Elements/ColorChooserButton.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Extended_Elements/ComboboxMapping.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Extended_Elements/FileBrowseButton.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Extended_Elements/Image.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Extended_Elements/ImageButton.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Extended_Elements/PythonConsole.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Extended_Elements/Separator.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Extended_Elements/Spacer.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Extended_Elements/TabFrame.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Extras/SwiftGUI.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Extras/__init__.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Files/ConfigFile.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Files/ConfigurationEditor.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Files/DictFile.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Files/ProgramDirectory.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Files/__init__.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Fonts.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/KeyFunctions.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Literals.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Popups/ElementPopup.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Popups/ListPicker.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Popups/SmallPopups.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Popups/VirtualKeyboard.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Themes/Thematic.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Themes/_BaseTheme.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Themes/__init__.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Tools.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Utilities/Images.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Utilities/Threads.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Canvas.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/GridFrame.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/LabelFrame.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Notebook.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Progressbar.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/Scrollbar.py +0 -0
- {swiftgui-0.11.19 → swiftgui-0.11.20}/src/SwiftGUI/Widget_Elements/TKContainer.py +0 -0
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
from collections.abc import Iterable, Callable
|
|
2
1
|
from functools import wraps
|
|
3
|
-
from typing import Literal, Union, Any, Hashable, Protocol
|
|
2
|
+
from typing import Literal, Union, Any, Hashable, Protocol, Iterable, Callable, TypeVar
|
|
4
3
|
from SwiftGUI.Compat import Self
|
|
5
4
|
import tkinter as tk
|
|
6
5
|
|
|
7
|
-
from SwiftGUI import Event, GlobalOptions, Color, remove_None_vals, Literals, ReuseError, RowTypeError
|
|
6
|
+
from SwiftGUI import Event, GlobalOptions, Color, remove_None_vals, Literals, ReuseError, RowTypeError, Tooltips
|
|
8
7
|
from SwiftGUI.ElementFlags import ElementFlag
|
|
9
8
|
#from SwiftGUI.Widget_Elements.Frame import Frame
|
|
10
9
|
|
|
@@ -52,6 +51,7 @@ class _BaseSharedAttributes:
|
|
|
52
51
|
key: Hashable = None # If given, this will be written to the event-value. Elements without a key can not throw key-events
|
|
53
52
|
_key_function: Callable | Iterable[Callable] = None # Saves the key-function(s), if given
|
|
54
53
|
|
|
54
|
+
same_class = TypeVar("same_class")
|
|
55
55
|
class BaseElement(_BaseSharedAttributes):
|
|
56
56
|
"""
|
|
57
57
|
Base for every element and widget.
|
|
@@ -383,6 +383,52 @@ class BaseElement(_BaseSharedAttributes):
|
|
|
383
383
|
|
|
384
384
|
return self
|
|
385
385
|
|
|
386
|
+
_tooltip_text: str | None = None
|
|
387
|
+
_bound_tooltip_functions: bool = False # True, if the events for tooltips are already bound
|
|
388
|
+
@run_after_window_creation
|
|
389
|
+
def set_tooltip(self, text: str | None = None) -> Self:
|
|
390
|
+
"""
|
|
391
|
+
Add/Change/Remove a tooltip from this element.
|
|
392
|
+
|
|
393
|
+
Set it to None to deactivate tooltips for this element
|
|
394
|
+
|
|
395
|
+
:param text: Text for the tooltip to show
|
|
396
|
+
:return:
|
|
397
|
+
"""
|
|
398
|
+
self._tooltip_text = text
|
|
399
|
+
|
|
400
|
+
if not self._bound_tooltip_functions:
|
|
401
|
+
self._bound_tooltip_functions = True
|
|
402
|
+
aw = self.window.actual_window
|
|
403
|
+
aw.activate_tooltips()
|
|
404
|
+
self.bind_event(
|
|
405
|
+
"Enter",
|
|
406
|
+
key_function=Tooltips.mouse_entered_elem_callback,
|
|
407
|
+
).bind_event(
|
|
408
|
+
"Leave",
|
|
409
|
+
key_function=Tooltips.mouse_exited_elem_callback,
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
@property
|
|
413
|
+
def tooltip_text(self) -> str | None:
|
|
414
|
+
return self._tooltip_text
|
|
415
|
+
|
|
416
|
+
@tooltip_text.setter
|
|
417
|
+
def tooltip_text(self, text: str | None):
|
|
418
|
+
self.set_tooltip(text)
|
|
419
|
+
|
|
420
|
+
@classmethod
|
|
421
|
+
def with_go(cls: type[same_class], go_class: type[GlobalOptions.DEFAULT_OPTIONS_CLASS]) -> type[same_class]:
|
|
422
|
+
"""
|
|
423
|
+
Create this element with a different global-option-class
|
|
424
|
+
:param go_class: The global-option-class this object should apply
|
|
425
|
+
:return:
|
|
426
|
+
"""
|
|
427
|
+
class Modified(cls):
|
|
428
|
+
defaults = go_class
|
|
429
|
+
|
|
430
|
+
return Modified
|
|
431
|
+
|
|
386
432
|
class BaseWidget(BaseElement):
|
|
387
433
|
"""
|
|
388
434
|
Base for every Widget
|
|
@@ -89,7 +89,7 @@ class Text(Canvas_Elements.BaseCanvasElement):
|
|
|
89
89
|
new_font = font.Font(
|
|
90
90
|
self.canvas.tk_widget,
|
|
91
91
|
family=self._fonttype,
|
|
92
|
-
size=self._fontsize,
|
|
92
|
+
size=self._fontsize if self._fontsize else 8,
|
|
93
93
|
weight="bold" if self._bold else "normal",
|
|
94
94
|
slant="italic" if self._italic else "roman",
|
|
95
95
|
underline=bool(self._underline),
|
|
@@ -43,6 +43,7 @@ class BaseCombinedElement(MixinElementWithDefaultEvent, BaseElement):
|
|
|
43
43
|
frame = layout
|
|
44
44
|
else:
|
|
45
45
|
frame = Frame(layout)
|
|
46
|
+
self.frame = frame
|
|
46
47
|
|
|
47
48
|
if internal_key_system:
|
|
48
49
|
self._has_sublayout = True
|
|
@@ -233,3 +234,8 @@ class BaseCombinedElement(MixinElementWithDefaultEvent, BaseElement):
|
|
|
233
234
|
self.set_value(val)
|
|
234
235
|
|
|
235
236
|
return self
|
|
237
|
+
|
|
238
|
+
def _bind_event_to_widget(self, tk_event: str, event_function: Callable) -> Self:
|
|
239
|
+
self.frame.tk_widget.bind(tk_event, event_function)
|
|
240
|
+
|
|
241
|
+
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
from collections.abc import Iterable, Callable
|
|
3
|
-
from functools import partial
|
|
4
|
-
from typing import Any, Hashable, Mapping
|
|
1
|
+
from typing import Any, Hashable, Mapping, Iterable, Callable
|
|
5
2
|
from SwiftGUI.Compat import Self
|
|
6
|
-
import json
|
|
7
3
|
|
|
8
|
-
from SwiftGUI import BaseElement,
|
|
9
|
-
#from SwiftGUI.Widget_Elements.Separator import HorizontalSeparator
|
|
10
|
-
from SwiftGUI.Extended_Elements.Spacer import Spacer
|
|
4
|
+
from SwiftGUI import BaseElement, Text, Input, BaseCombinedElement, Button, Event, GlobalOptions, ValueDict, Spacer
|
|
11
5
|
|
|
12
6
|
|
|
13
7
|
# Advanced / Combined elements
|
|
@@ -18,6 +12,8 @@ class Form(BaseCombinedElement):
|
|
|
18
12
|
It is WIP, but I'm adding more functionality regularely
|
|
19
13
|
I'll probably throw this whole class out of the window and redo it, since it is so unfathomly bad atm.
|
|
20
14
|
"""
|
|
15
|
+
defaults = GlobalOptions.Form
|
|
16
|
+
value: ValueDict | tuple
|
|
21
17
|
|
|
22
18
|
def __init__(
|
|
23
19
|
self,
|
|
@@ -27,11 +23,15 @@ class Form(BaseCombinedElement):
|
|
|
27
23
|
key: Hashable = None,
|
|
28
24
|
key_function: Callable | Iterable[Callable] = None,
|
|
29
25
|
default_event: bool = None,
|
|
26
|
+
return_submits: bool = None,
|
|
30
27
|
small_clear_buttons: bool = None,
|
|
31
28
|
big_clear_button: bool = None,
|
|
29
|
+
clear_button_text: str = None,
|
|
32
30
|
submit_button: bool = None,
|
|
31
|
+
submit_button_text: str = None,
|
|
32
|
+
space_over_buttons: int = None,
|
|
33
|
+
space_between_rows: int = None,
|
|
33
34
|
#submit_key: Any = None,
|
|
34
|
-
return_submits: bool = None,
|
|
35
35
|
):
|
|
36
36
|
"""
|
|
37
37
|
|
|
@@ -44,10 +44,17 @@ class Form(BaseCombinedElement):
|
|
|
44
44
|
:param big_clear_button: One big clear-button under the inputs to clear all inputs at once
|
|
45
45
|
:param submit_button: True, if there should be a submit-button that throws an event when clicked. Ignores the default event
|
|
46
46
|
:param return_submits: True, if pressing enter should be equal to pressing submit. Ignores the default event
|
|
47
|
+
:param clear_button_text: Text on the clear-button
|
|
48
|
+
:param submit_button_text: Text on the submit-button
|
|
49
|
+
:param space_over_buttons: Height of the separator in the row before the buttons
|
|
50
|
+
:param space_between_rows: Height of the separators between the rows
|
|
47
51
|
"""
|
|
48
|
-
|
|
52
|
+
space_between_rows = self.defaults.single("space_between_rows", space_between_rows)
|
|
53
|
+
space_over_buttons = self.defaults.single("space_over_buttons", space_over_buttons)
|
|
49
54
|
|
|
50
|
-
|
|
55
|
+
self._mapping_mode = isinstance(texts, Mapping)
|
|
56
|
+
|
|
57
|
+
if self._mapping_mode:
|
|
51
58
|
values = list(texts.values())
|
|
52
59
|
else:
|
|
53
60
|
values = list(texts)
|
|
@@ -56,41 +63,51 @@ class Form(BaseCombinedElement):
|
|
|
56
63
|
|
|
57
64
|
self._input_elements: list[Input] = list()
|
|
58
65
|
self._text_elements: list[Text] = list()
|
|
66
|
+
self._small_clear_button_elements: list[Button] = list()
|
|
59
67
|
|
|
60
68
|
self._small_clear_buttons = small_clear_buttons
|
|
61
69
|
self._return_submits = return_submits
|
|
62
70
|
|
|
63
|
-
if self.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
self._make_row(k,t, text_len=_max_len) for t,k in texts.items()
|
|
67
|
-
]
|
|
71
|
+
if self._mapping_mode:
|
|
72
|
+
rows = [
|
|
73
|
+
self._make_row(k,t, text_len=_max_len) for t,k in texts.items()
|
|
68
74
|
]
|
|
69
75
|
else:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
self._make_row(t, text_len=_max_len) for t in values
|
|
73
|
-
]
|
|
76
|
+
rows = [
|
|
77
|
+
self._make_row(t, text_len=_max_len) for t in values
|
|
74
78
|
]
|
|
75
79
|
|
|
80
|
+
layout = []
|
|
81
|
+
if space_between_rows:
|
|
82
|
+
for row in rows[:-1]:
|
|
83
|
+
layout.append(row)
|
|
84
|
+
layout.append([Spacer(height=space_between_rows)])
|
|
85
|
+
|
|
86
|
+
if len(rows):
|
|
87
|
+
layout.append(rows[-1])
|
|
88
|
+
else:
|
|
89
|
+
layout = rows
|
|
90
|
+
|
|
76
91
|
button_row: list[BaseElement] = list()
|
|
77
92
|
|
|
78
|
-
|
|
79
|
-
self.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
button_row.append(self.clear_button)
|
|
93
|
+
self.clear_button = Button(
|
|
94
|
+
self.defaults.single("clear_button_text", clear_button_text),
|
|
95
|
+
key_function= lambda: self.clear_all_values(throw_default_event=True),
|
|
96
|
+
).set_visible(big_clear_button)
|
|
97
|
+
button_row.append(self.clear_button)
|
|
84
98
|
|
|
85
|
-
|
|
86
|
-
self.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
button_row.append(self.submit_button)
|
|
99
|
+
self.submit_button = Button(
|
|
100
|
+
self.defaults.single("submit_button_text", submit_button_text),
|
|
101
|
+
key_function=self.throw_event,
|
|
102
|
+
).set_visible(submit_button)
|
|
103
|
+
button_row.append(self.submit_button)
|
|
91
104
|
|
|
92
|
-
if
|
|
93
|
-
layout.append(
|
|
105
|
+
if space_over_buttons:
|
|
106
|
+
layout.append([Spacer(height=space_over_buttons)])
|
|
107
|
+
elif space_between_rows:
|
|
108
|
+
layout.append([Spacer(height=space_between_rows)])
|
|
109
|
+
|
|
110
|
+
layout.append(button_row)
|
|
94
111
|
|
|
95
112
|
super().__init__(
|
|
96
113
|
layout,
|
|
@@ -102,6 +119,18 @@ class Form(BaseCombinedElement):
|
|
|
102
119
|
if default_values is not None:
|
|
103
120
|
self.set_value(default_values)
|
|
104
121
|
|
|
122
|
+
def _update_special_key(self,key:str,new_val:Any) -> bool|None:
|
|
123
|
+
match key:
|
|
124
|
+
case "clear_button_text":
|
|
125
|
+
self.clear_button.set_value(new_val)
|
|
126
|
+
case "submit_button_text":
|
|
127
|
+
self.submit_button.set_value(new_val)
|
|
128
|
+
|
|
129
|
+
case _:
|
|
130
|
+
return super()._update_special_key(key, new_val)
|
|
131
|
+
|
|
132
|
+
return True
|
|
133
|
+
|
|
105
134
|
def _make_row(self, text: str, key: Hashable = None, text_len: int = 20) -> list[BaseElement]:
|
|
106
135
|
"""
|
|
107
136
|
Create a single row of elements
|
|
@@ -128,15 +157,32 @@ class Form(BaseCombinedElement):
|
|
|
128
157
|
]
|
|
129
158
|
|
|
130
159
|
if self._small_clear_buttons:
|
|
131
|
-
|
|
160
|
+
button = Button(
|
|
132
161
|
text= "x",
|
|
133
162
|
width=2,
|
|
134
163
|
key_function= lambda: input_elem.set_value("", throw_event=True),
|
|
135
164
|
takefocus= False,
|
|
136
|
-
)
|
|
165
|
+
)
|
|
166
|
+
row.append(button)
|
|
167
|
+
self._small_clear_button_elements.append(button)
|
|
137
168
|
|
|
138
169
|
return row
|
|
139
170
|
|
|
171
|
+
def __getitem__(self, item: Hashable | int) -> str:
|
|
172
|
+
assert self._mapping_mode or isinstance(item, int), f"{repr(self)} is created in list-mode, so only integer indexes can be used as key!"
|
|
173
|
+
|
|
174
|
+
return self.value[item]
|
|
175
|
+
|
|
176
|
+
def __setitem__(self, key: Hashable | int, value):
|
|
177
|
+
assert self._mapping_mode or isinstance(key, int), f"{repr(self)} is created in list-mode, so only integer indexes can be used as key!"
|
|
178
|
+
|
|
179
|
+
if self._mapping_mode:
|
|
180
|
+
if not key in self.v:
|
|
181
|
+
raise KeyError(f"{repr(self)} was given a key that it doesn't contain")
|
|
182
|
+
self.v[key] = value
|
|
183
|
+
else:
|
|
184
|
+
self._input_elements[key].value = value
|
|
185
|
+
|
|
140
186
|
@BaseCombinedElement._run_after_window_creation
|
|
141
187
|
def set_value(self, val: Iterable | Mapping) -> Self:
|
|
142
188
|
"""
|
|
@@ -150,7 +196,9 @@ class Form(BaseCombinedElement):
|
|
|
150
196
|
for value, elem in zip(val, self._input_elements):
|
|
151
197
|
elem.value = value
|
|
152
198
|
|
|
153
|
-
|
|
199
|
+
return self
|
|
200
|
+
|
|
201
|
+
def as_tuple(self) -> tuple:
|
|
154
202
|
"""
|
|
155
203
|
Return a tuple with all form-values one after the other
|
|
156
204
|
:return:
|
|
@@ -158,10 +206,10 @@ class Form(BaseCombinedElement):
|
|
|
158
206
|
return tuple(map(lambda a:a.value, self._input_elements))
|
|
159
207
|
|
|
160
208
|
def _get_value(self):
|
|
161
|
-
if self.
|
|
209
|
+
if self._mapping_mode:
|
|
162
210
|
return super()._get_value()
|
|
163
211
|
|
|
164
|
-
return self.
|
|
212
|
+
return self.as_tuple()
|
|
165
213
|
|
|
166
214
|
@BaseElement._run_after_window_creation
|
|
167
215
|
def update_texts(self,**kwargs) -> Self:
|
|
@@ -177,7 +225,7 @@ class Form(BaseCombinedElement):
|
|
|
177
225
|
@BaseElement._run_after_window_creation
|
|
178
226
|
def update_inputs(self,**kwargs) -> Self:
|
|
179
227
|
"""
|
|
180
|
-
Evoke .update on every
|
|
228
|
+
Evoke .update on every input-element
|
|
181
229
|
:param kwargs:
|
|
182
230
|
:return:
|
|
183
231
|
"""
|
|
@@ -185,7 +233,18 @@ class Form(BaseCombinedElement):
|
|
|
185
233
|
elem._update_initial(**kwargs)
|
|
186
234
|
return self
|
|
187
235
|
|
|
188
|
-
|
|
236
|
+
@BaseElement._run_after_window_creation
|
|
237
|
+
def update_small_clear_buttons(self,**kwargs) -> Self:
|
|
238
|
+
"""
|
|
239
|
+
Evoke .update on every input-element
|
|
240
|
+
:param kwargs:
|
|
241
|
+
:return:
|
|
242
|
+
"""
|
|
243
|
+
for elem in self._small_clear_button_elements:
|
|
244
|
+
elem._update_initial(**kwargs)
|
|
245
|
+
return self
|
|
246
|
+
|
|
247
|
+
def clear_all_values(self, throw_default_event: bool = False) -> Self:
|
|
189
248
|
"""
|
|
190
249
|
Does what it says
|
|
191
250
|
:return:
|
|
@@ -196,13 +255,15 @@ class Form(BaseCombinedElement):
|
|
|
196
255
|
if throw_default_event:
|
|
197
256
|
self.throw_default_event()
|
|
198
257
|
|
|
199
|
-
|
|
258
|
+
return self
|
|
259
|
+
|
|
260
|
+
def set_focus(self) -> Self:
|
|
200
261
|
"""
|
|
201
262
|
Focus the first row of this element
|
|
202
263
|
:return:
|
|
203
264
|
"""
|
|
204
265
|
self._input_elements[0].set_focus()
|
|
205
|
-
|
|
266
|
+
return self
|
|
206
267
|
|
|
207
268
|
|
|
208
269
|
|
|
@@ -165,7 +165,6 @@ def preview_all_elements(
|
|
|
165
165
|
sg.Notebook(
|
|
166
166
|
sg.TabFrame([[sg.T("sg.Notebook")]], fake_key="Tab1"),
|
|
167
167
|
sg.TabFrame([[sg.T("still sg.Notebook")]], fake_key="Tab2"),
|
|
168
|
-
|
|
169
168
|
)
|
|
170
169
|
],[
|
|
171
170
|
sg.Spacer(height=20)
|
|
@@ -174,9 +173,9 @@ def preview_all_elements(
|
|
|
174
173
|
[
|
|
175
174
|
sg.T("sg.SubLayout"),
|
|
176
175
|
],[
|
|
177
|
-
sg.T("A
|
|
176
|
+
sg.T("A separate layout inside your layout.")
|
|
178
177
|
],[
|
|
179
|
-
sg.T("It has
|
|
178
|
+
sg.T("It has separate keys and its own segregated event-loop.")
|
|
180
179
|
]
|
|
181
180
|
], alignment="left"))
|
|
182
181
|
]
|
|
@@ -225,6 +224,8 @@ def preview_all_elements(
|
|
|
225
224
|
big_clear_button= True,
|
|
226
225
|
submit_button= True,
|
|
227
226
|
default_values= ("", "", "Click on Clear"),
|
|
227
|
+
).update_inputs(
|
|
228
|
+
readonly=flip_readonly,
|
|
228
229
|
)
|
|
229
230
|
],[
|
|
230
231
|
sg.HSep()
|
|
@@ -258,7 +259,9 @@ def preview_all_elements(
|
|
|
258
259
|
sg.T("Lets you select a day"),
|
|
259
260
|
], [
|
|
260
261
|
sg.T(expand=True),
|
|
261
|
-
sg.Calendar(
|
|
262
|
+
sg.Calendar(
|
|
263
|
+
disabled=flip_disabled,
|
|
264
|
+
),
|
|
262
265
|
sg.T(expand=True),
|
|
263
266
|
], [
|
|
264
267
|
sg.HSep()
|
|
@@ -318,7 +321,7 @@ def preview_all_elements(
|
|
|
318
321
|
[
|
|
319
322
|
sg.T("sgc.Element")
|
|
320
323
|
],[
|
|
321
|
-
sg.Button("Put any sg-element onto your canvas!!")
|
|
324
|
+
sg.Button("Put any sg-element onto your canvas!!", disabled=flip_disabled)
|
|
322
325
|
]
|
|
323
326
|
]),
|
|
324
327
|
anchor= "nw",
|
|
@@ -401,7 +404,7 @@ def preview_all_elements(
|
|
|
401
404
|
]
|
|
402
405
|
]
|
|
403
406
|
|
|
404
|
-
w = sg.SubWindow(layout, title="Preview of all currently available elements")
|
|
407
|
+
w = sg.SubWindow(layout, title="Preview of all currently available elements", grab_anywhere=True)
|
|
405
408
|
w["List"].index = 2
|
|
406
409
|
console.print("Hi, I am sg.Console!")
|
|
407
410
|
console.print("I have a print-function that works just like the normal print(...)")
|
|
@@ -235,7 +235,9 @@ class Table(MixinElementWithDefaultEvent, BaseWidgetTTK, MixinScrollbar):
|
|
|
235
235
|
|
|
236
236
|
self._prev_selection = all_indexes
|
|
237
237
|
|
|
238
|
-
if not all_indexes: # It's impossible for the user to cause a real event without anything selected in the table
|
|
238
|
+
if not all_indexes: # It's NEARLY impossible for the user to cause a real event without anything selected in the table
|
|
239
|
+
# The annoyance is worse without this check, so keep it!
|
|
240
|
+
# If the selectmode is extended, you can deselect rows. This is the only exception
|
|
239
241
|
return
|
|
240
242
|
|
|
241
243
|
self.throw_default_event()
|
|
@@ -253,9 +253,9 @@ class Text(Common, Common_Textual, Common_Background):
|
|
|
253
253
|
justify:Literal["left","right","center"] = "left"
|
|
254
254
|
#borderwidth:int = "5c" # Does not work
|
|
255
255
|
apply_parent_background_color:bool = True
|
|
256
|
-
|
|
257
256
|
padding:Literals.padding = 0
|
|
258
257
|
width:int = None
|
|
258
|
+
relief: Literals.relief = "flat"
|
|
259
259
|
|
|
260
260
|
class Scale(Common_Background, Common_Textual):
|
|
261
261
|
default_value: int | float = None
|
|
@@ -409,6 +409,10 @@ class Window(Common_Background):
|
|
|
409
409
|
hidden: bool = False
|
|
410
410
|
minimized: bool = False
|
|
411
411
|
|
|
412
|
+
class Tooltip(Text):
|
|
413
|
+
relief: Literals.relief = "ridge"
|
|
414
|
+
padding: Literals.padding = (10, 5)
|
|
415
|
+
text_color: Color | str = None
|
|
412
416
|
|
|
413
417
|
class SubWindow(Window):
|
|
414
418
|
...
|
|
@@ -708,6 +712,12 @@ class Canvas_Image(Common_Canvas_Element, Image):
|
|
|
708
712
|
image_height: int = None
|
|
709
713
|
anchor: sg.Literals.anchor = None
|
|
710
714
|
|
|
715
|
+
class Form(EMPTY):
|
|
716
|
+
clear_button_text: str = "Clear"
|
|
717
|
+
submit_button_text: str = "Submit"
|
|
718
|
+
space_over_buttons: int = 2
|
|
719
|
+
space_between_rows: int = 0
|
|
720
|
+
|
|
711
721
|
def reset_all_options():
|
|
712
722
|
"""
|
|
713
723
|
Reset everything done to the global options on runtime.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import SwiftGUI as sg
|
|
2
|
+
|
|
3
|
+
TooltipText = sg.T.with_go(sg.GlobalOptions.Tooltip)
|
|
4
|
+
|
|
5
|
+
class TooltipPopup(sg.BasePopupNonblocking):
|
|
6
|
+
|
|
7
|
+
def __init__(
|
|
8
|
+
self,
|
|
9
|
+
tooltip_text: str,
|
|
10
|
+
titlebar: bool = False,
|
|
11
|
+
padx: int = 0,
|
|
12
|
+
pady: int = 0,
|
|
13
|
+
**window_kwargs,
|
|
14
|
+
):
|
|
15
|
+
super().__init__(
|
|
16
|
+
self._create_layout(tooltip_text),
|
|
17
|
+
titlebar=titlebar,
|
|
18
|
+
padx=padx,
|
|
19
|
+
pady=pady,
|
|
20
|
+
position= self._get_position(),
|
|
21
|
+
**window_kwargs,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
def _get_position(self) -> tuple[int, int]:
|
|
25
|
+
posx, posy = sg.main_window().get_mouse_position_global()
|
|
26
|
+
return posx + 15, posy
|
|
27
|
+
|
|
28
|
+
def _create_layout(self, tooltip_text: str) -> list[list[sg.BaseElement]]:
|
|
29
|
+
layout = [
|
|
30
|
+
[
|
|
31
|
+
TooltipText( # Options of this text are defined in GlobalOptions.Tooltip
|
|
32
|
+
tooltip_text,
|
|
33
|
+
)
|
|
34
|
+
]
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
return layout
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
sg.Tooltips.set_tooltip_callable(TooltipPopup)
|
|
41
|
+
|
|
@@ -109,6 +109,9 @@ class BaseFourColors(BaseTheme):
|
|
|
109
109
|
temp = go.Canvas_Text
|
|
110
110
|
temp.color = c4
|
|
111
111
|
|
|
112
|
+
temp = go.Tooltip
|
|
113
|
+
temp.text_color = c3
|
|
114
|
+
|
|
112
115
|
def get_palette_frame(self, width: int = 50, height: int = 200) -> sg.Frame:
|
|
113
116
|
"""
|
|
114
117
|
Returns an sg.Frame that contains the 4 containing colors.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
from typing import Callable, Protocol, Union
|
|
3
|
+
|
|
4
|
+
import SwiftGUI as sg
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
### YOU MAY CHANGE THESE ###
|
|
8
|
+
tooltip_open_delay: float = 0.7 # How long the mouse must be still to open a tooltip
|
|
9
|
+
tooltip_close_delay: float = 0.1 # Maximum delay before a tooltip closes
|
|
10
|
+
|
|
11
|
+
### PLEASE DO NOT TOUCH ###
|
|
12
|
+
_last_mouse_movement = 0 # When the mouse last moved
|
|
13
|
+
_current_elem = None # The sg.element the mouse is currently hovering over
|
|
14
|
+
_tooltips_active: bool = False # If the tooltip-thread is running
|
|
15
|
+
_tooltip_function: Callable[[str], "SupportsClose"] | None = None # This gets called when a tooltip is opened. Must take one parameter: text
|
|
16
|
+
|
|
17
|
+
class SupportsClose(Protocol):
|
|
18
|
+
def close(self):
|
|
19
|
+
...
|
|
20
|
+
|
|
21
|
+
def set_tooltip_callable(fct: Callable[[str], SupportsClose], only_if_nonexistent: bool = False):
|
|
22
|
+
"""
|
|
23
|
+
Specify the function called on tooltip-opening
|
|
24
|
+
:param fct: The function to call
|
|
25
|
+
:param only_if_nonexistent: Only set that function if no function was set yet
|
|
26
|
+
:return:
|
|
27
|
+
"""
|
|
28
|
+
global _tooltip_function
|
|
29
|
+
|
|
30
|
+
if only_if_nonexistent and _tooltip_function:
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
_tooltip_function = fct
|
|
34
|
+
|
|
35
|
+
def mouse_moved_callback():
|
|
36
|
+
"""Callback for the move-event"""
|
|
37
|
+
global _last_mouse_movement
|
|
38
|
+
_last_mouse_movement = time.time()
|
|
39
|
+
|
|
40
|
+
def mouse_entered_elem_callback(elem): # Can't use typehints due to circular imports
|
|
41
|
+
"""
|
|
42
|
+
Mouse entered an element (key-function)
|
|
43
|
+
:param elem:
|
|
44
|
+
:return:
|
|
45
|
+
"""
|
|
46
|
+
global _current_elem
|
|
47
|
+
_current_elem = elem
|
|
48
|
+
|
|
49
|
+
def mouse_exited_elem_callback(elem):
|
|
50
|
+
"""
|
|
51
|
+
Mouse is no longer over an element
|
|
52
|
+
:param elem:
|
|
53
|
+
:return:
|
|
54
|
+
"""
|
|
55
|
+
global _current_elem
|
|
56
|
+
|
|
57
|
+
if _current_elem is elem:
|
|
58
|
+
_current_elem = None
|
|
59
|
+
|
|
60
|
+
def _handle_tooltips():
|
|
61
|
+
"""
|
|
62
|
+
Threaded.
|
|
63
|
+
If the mouse hasn't moved in some time, open the tooltip
|
|
64
|
+
:return:
|
|
65
|
+
"""
|
|
66
|
+
global _last_mouse_movement
|
|
67
|
+
_tooltip_open = False
|
|
68
|
+
_opened_tooltip_object: Union["SupportsClose", None] = None # The currently opened tooltip-object
|
|
69
|
+
|
|
70
|
+
while True:
|
|
71
|
+
while not _tooltip_open:
|
|
72
|
+
time_since_movement = time.time() - _last_mouse_movement
|
|
73
|
+
time_until_tooltip = tooltip_open_delay - time_since_movement
|
|
74
|
+
|
|
75
|
+
if time_until_tooltip > 0:
|
|
76
|
+
time.sleep(time_until_tooltip + 0.01)
|
|
77
|
+
continue
|
|
78
|
+
|
|
79
|
+
if _current_elem is None:
|
|
80
|
+
time.sleep(tooltip_open_delay)
|
|
81
|
+
continue
|
|
82
|
+
|
|
83
|
+
_tooltip_open = True
|
|
84
|
+
|
|
85
|
+
_last_mouse_movement = 0
|
|
86
|
+
_opened_for_this_element = _current_elem
|
|
87
|
+
_opened_tooltip_object = _tooltip_function(_current_elem.tooltip_text) # Open tooltip
|
|
88
|
+
|
|
89
|
+
while _tooltip_open: # Tooltip open
|
|
90
|
+
time.sleep(tooltip_close_delay)
|
|
91
|
+
|
|
92
|
+
if _current_elem is not _opened_for_this_element: # If the mouse moved again
|
|
93
|
+
_tooltip_open = False
|
|
94
|
+
break
|
|
95
|
+
|
|
96
|
+
_opened_tooltip_object.close() # Close tooltip
|
|
97
|
+
_opened_tooltip_object = None
|
|
98
|
+
|
|
99
|
+
def activate_tooltips():
|
|
100
|
+
"""
|
|
101
|
+
Activate the tooltip-thread if it isn't running already
|
|
102
|
+
:return:
|
|
103
|
+
"""
|
|
104
|
+
global _tooltips_active
|
|
105
|
+
|
|
106
|
+
if _tooltips_active:
|
|
107
|
+
return
|
|
108
|
+
|
|
109
|
+
_tooltips_active = True
|
|
110
|
+
threading.Thread(target=_handle_tooltips, daemon=True).start()
|
|
111
|
+
|
|
112
|
+
|
|
@@ -214,7 +214,7 @@ class Button(MixinElementWithDefaultEvent, BaseWidget):
|
|
|
214
214
|
self._tk_kwargs["font"] = font.Font(
|
|
215
215
|
self.window.parent_tk_widget,
|
|
216
216
|
family=self._fonttype,
|
|
217
|
-
size=self._fontsize,
|
|
217
|
+
size=self._fontsize if self._fontsize else 8,
|
|
218
218
|
weight="bold" if self._bold else "normal",
|
|
219
219
|
slant="italic" if self._italic else "roman",
|
|
220
220
|
underline=bool(self._underline),
|
|
@@ -153,7 +153,7 @@ class Checkbox(MixinElementWithValue, BaseWidget):
|
|
|
153
153
|
self._tk_kwargs["font"] = font.Font(
|
|
154
154
|
self.window.parent_tk_widget,
|
|
155
155
|
family=self._fonttype,
|
|
156
|
-
size=self._fontsize,
|
|
156
|
+
size=self._fontsize if self._fontsize else 8,
|
|
157
157
|
weight="bold" if self._bold else "normal",
|
|
158
158
|
slant="italic" if self._italic else "roman",
|
|
159
159
|
underline=bool(self._underline),
|
|
@@ -285,7 +285,7 @@ class Combobox(MixinElementWithValue, BaseWidgetTTK):
|
|
|
285
285
|
self._tk_kwargs["font"] = font.Font(
|
|
286
286
|
self.window.parent_tk_widget,
|
|
287
287
|
family=self._fonttype,
|
|
288
|
-
size=self._fontsize,
|
|
288
|
+
size=self._fontsize if self._fontsize else 8,
|
|
289
289
|
weight="bold" if self._bold else "normal",
|
|
290
290
|
slant="italic" if self._italic else "roman",
|
|
291
291
|
underline=bool(self._underline),
|
|
@@ -187,6 +187,9 @@ class Frame(BaseWidgetContainer):
|
|
|
187
187
|
|
|
188
188
|
element._init(self._containing_row_elements[row_index], self.window)
|
|
189
189
|
|
|
190
|
+
if self.has_flag(ElementFlag.IS_CREATED):
|
|
191
|
+
element.init_window_creation_done()
|
|
192
|
+
|
|
190
193
|
return self
|
|
191
194
|
|
|
192
195
|
def get_row_index(self, elem: BaseElement) -> int | None:
|
|
@@ -160,7 +160,7 @@ class Input(MixinElementWithValue, BaseWidget):
|
|
|
160
160
|
self._tk_kwargs["font"] = font.Font(
|
|
161
161
|
self.window.parent_tk_widget,
|
|
162
162
|
family=self._fonttype,
|
|
163
|
-
size=self._fontsize,
|
|
163
|
+
size=self._fontsize if self._fontsize else 8,
|
|
164
164
|
weight="bold" if self._bold else "normal",
|
|
165
165
|
slant="italic" if self._italic else "roman",
|
|
166
166
|
underline=bool(self._underline),
|
|
@@ -222,7 +222,7 @@ class Listbox(MixinElementWithValue, BaseWidget, MixinScrollbar):
|
|
|
222
222
|
self._tk_kwargs["font"] = font.Font(
|
|
223
223
|
self.window.parent_tk_widget,
|
|
224
224
|
family=self._fonttype,
|
|
225
|
-
size=self._fontsize,
|
|
225
|
+
size=self._fontsize if self._fontsize else 8,
|
|
226
226
|
weight="bold" if self._bold else "normal",
|
|
227
227
|
slant="italic" if self._italic else "roman",
|
|
228
228
|
underline=bool(self._underline),
|
|
@@ -192,7 +192,7 @@ class Radiobutton(MixinElementWithDefaultEvent, BaseWidget):
|
|
|
192
192
|
self._tk_kwargs["font"] = font.Font(
|
|
193
193
|
self.window.parent_tk_widget,
|
|
194
194
|
family=self._fonttype,
|
|
195
|
-
size=self._fontsize,
|
|
195
|
+
size=self._fontsize if self._fontsize else 8,
|
|
196
196
|
weight="bold" if self._bold else "normal",
|
|
197
197
|
slant="italic" if self._italic else "roman",
|
|
198
198
|
underline=bool(self._underline),
|
|
@@ -158,7 +158,7 @@ class Scale(MixinElementWithValue, BaseWidget):
|
|
|
158
158
|
self._tk_kwargs["font"] = font.Font(
|
|
159
159
|
self.window.parent_tk_widget,
|
|
160
160
|
family=self._fonttype,
|
|
161
|
-
size=self._fontsize,
|
|
161
|
+
size=self._fontsize if self._fontsize else 8,
|
|
162
162
|
weight="bold" if self._bold else "normal",
|
|
163
163
|
slant="italic" if self._italic else "roman",
|
|
164
164
|
underline=bool(self._underline),
|
|
@@ -189,7 +189,7 @@ class Spinbox(MixinElementWithValue, BaseWidget):
|
|
|
189
189
|
self._tk_kwargs["font"] = font.Font(
|
|
190
190
|
self.window.parent_tk_widget,
|
|
191
191
|
family=self._fonttype,
|
|
192
|
-
size=self._fontsize,
|
|
192
|
+
size=self._fontsize if self._fontsize else 8,
|
|
193
193
|
weight="bold" if self._bold else "normal",
|
|
194
194
|
slant="italic" if self._italic else "roman",
|
|
195
195
|
underline=bool(self._underline),
|
|
@@ -115,7 +115,7 @@ class Text(BaseWidget):
|
|
|
115
115
|
self._tk_kwargs["font"] = font.Font(
|
|
116
116
|
self.window.parent_tk_widget,
|
|
117
117
|
family=self._fonttype,
|
|
118
|
-
size=self._fontsize,
|
|
118
|
+
size=self._fontsize if self._fontsize else 8,
|
|
119
119
|
weight="bold" if self._bold else "normal",
|
|
120
120
|
slant="italic" if self._italic else "roman",
|
|
121
121
|
underline=bool(self._underline),
|
|
@@ -258,7 +258,7 @@ class TextField(MixinElementWithValue, BaseWidget, MixinScrollbar):
|
|
|
258
258
|
temp = font.Font(
|
|
259
259
|
self.window.parent_tk_widget,
|
|
260
260
|
family=self._fonttype,
|
|
261
|
-
size=self._fontsize,
|
|
261
|
+
size=self._fontsize if self._fontsize else 8,
|
|
262
262
|
weight="bold" if self._bold else "normal",
|
|
263
263
|
slant="italic" if self._italic else "roman",
|
|
264
264
|
underline=bool(self._underline),
|
|
@@ -140,7 +140,7 @@ class Treeview(BaseWidget):
|
|
|
140
140
|
temp = font.Font(
|
|
141
141
|
self.window.parent_tk_widget,
|
|
142
142
|
family=self._fonttype,
|
|
143
|
-
size=self._fontsize,
|
|
143
|
+
size=self._fontsize if self._fontsize else 8,
|
|
144
144
|
weight="bold" if self._bold else "normal",
|
|
145
145
|
slant="italic" if self._italic else "roman",
|
|
146
146
|
underline=bool(self._underline),
|
|
@@ -16,7 +16,7 @@ from PIL import Image, ImageTk
|
|
|
16
16
|
import time
|
|
17
17
|
import logging
|
|
18
18
|
|
|
19
|
-
from SwiftGUI import BaseElement, Frame, ElementFlag, Literals, GlobalOptions, Color, Debug
|
|
19
|
+
from SwiftGUI import BaseElement, Frame, ElementFlag, Literals, GlobalOptions, Color, Debug, Tooltips
|
|
20
20
|
|
|
21
21
|
if TYPE_CHECKING:
|
|
22
22
|
from SwiftGUI import AnyElement
|
|
@@ -640,6 +640,15 @@ class BaseKeyHandler(BaseElement):
|
|
|
640
640
|
self.value.from_json(data)
|
|
641
641
|
return self
|
|
642
642
|
|
|
643
|
+
def activate_tooltips(self) -> Self:
|
|
644
|
+
"""
|
|
645
|
+
Activate the necessary event for tooltip-handling.
|
|
646
|
+
You don't need to call this, just ignore.
|
|
647
|
+
:return:
|
|
648
|
+
"""
|
|
649
|
+
self.actual_window.activate_tooltips()
|
|
650
|
+
return self
|
|
651
|
+
|
|
643
652
|
class SubLayout(BaseKeyHandler):
|
|
644
653
|
"""
|
|
645
654
|
Can be used as an sg-element.
|
|
@@ -862,6 +871,7 @@ class Window(BaseKeyHandler):
|
|
|
862
871
|
|
|
863
872
|
self._sg_widget:Frame = Frame(layout,alignment= self.defaults.single("alignment", alignment), expand_y=True, expand=True)
|
|
864
873
|
self.root = tk.Tk()
|
|
874
|
+
self.root.withdraw()
|
|
865
875
|
self.ttk_style: ttk.Style = ttk.Style(self.root)
|
|
866
876
|
|
|
867
877
|
if ttk_style is None:
|
|
@@ -1425,6 +1435,22 @@ class Window(BaseKeyHandler):
|
|
|
1425
1435
|
|
|
1426
1436
|
return x, y
|
|
1427
1437
|
|
|
1438
|
+
### TOOLTIPS ###
|
|
1439
|
+
_tooltips_active: bool = False
|
|
1440
|
+
def activate_tooltips(self) -> Self:
|
|
1441
|
+
if self._tooltips_active:
|
|
1442
|
+
return self
|
|
1443
|
+
|
|
1444
|
+
self.bind_event("Motion", key_function=Tooltips.mouse_moved_callback)
|
|
1445
|
+
self._tooltips_active = True
|
|
1446
|
+
Tooltips.activate_tooltips()
|
|
1447
|
+
return self
|
|
1448
|
+
|
|
1449
|
+
@staticmethod
|
|
1450
|
+
def _mouse_moved():
|
|
1451
|
+
"""Callback for the motion-event"""
|
|
1452
|
+
Tooltips.mouse_moved_callback()
|
|
1453
|
+
|
|
1428
1454
|
class HiddenMainWindow(Window):
|
|
1429
1455
|
def __init__(self):
|
|
1430
1456
|
"""
|
|
@@ -1509,7 +1535,8 @@ class SubWindow(Window):
|
|
|
1509
1535
|
self._grab_anywhere = self.defaults.single("grab_anywhere", grab_anywhere)
|
|
1510
1536
|
|
|
1511
1537
|
self._sg_widget:Frame = Frame(layout,alignment= self.defaults.single("alignment", alignment), expand_y=True, expand=True)
|
|
1512
|
-
self.root: tk.Toplevel = tk.Toplevel()
|
|
1538
|
+
self.root: tk.Toplevel = tk.Toplevel(_main_window.root)
|
|
1539
|
+
self.root.withdraw() # Todo: Stop the window from flickering when it is being created
|
|
1513
1540
|
self.ttk_style: ttk.Style = _main_window.ttk_style
|
|
1514
1541
|
|
|
1515
1542
|
if icon is None:
|
|
@@ -1535,6 +1562,7 @@ class SubWindow(Window):
|
|
|
1535
1562
|
)
|
|
1536
1563
|
|
|
1537
1564
|
self.init(self._sg_widget, self.root, grab_anywhere_window= self)
|
|
1565
|
+
self.root.deiconify()
|
|
1538
1566
|
|
|
1539
1567
|
self.bind_grab_anywhere_to_element(self._sg_widget.tk_widget)
|
|
1540
1568
|
|
|
@@ -1543,6 +1571,10 @@ class SubWindow(Window):
|
|
|
1543
1571
|
_main_window.register_element(self)
|
|
1544
1572
|
_main_window._value_dict.set_extra_value(key, self.value)
|
|
1545
1573
|
|
|
1574
|
+
def init_window_creation_done(self):
|
|
1575
|
+
super().init_window_creation_done()
|
|
1576
|
+
self.root.deiconify()
|
|
1577
|
+
|
|
1546
1578
|
def loop_close(self, block_others: bool = True) -> tuple[Any,dict[Hashable, Any]]:
|
|
1547
1579
|
"""
|
|
1548
1580
|
Loop until the first keyed event.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|