-
-
Notifications
You must be signed in to change notification settings - Fork 674
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[widget Audit] toga.App #2075
[widget Audit] toga.App #2075
Changes from 1 commit
684a45d
2e19256
8f77008
d1a64a4
2dfa2be
8f92cd3
2076dd9
f8c19b3
e0a46dc
fec495d
dde078e
d27307b
d505c95
035fc8b
8219173
fedd4fe
6c8877c
596149f
8140de2
adcecf2
ada9303
cceeb5f
ca1471d
9f24361
a5931ed
c6fe640
28771cf
1334fc6
5cf47cd
b7fe16c
98ef170
eea80a1
7f42fce
69e760b
5c31e88
08b5b33
9f09703
fb25864
7222344
3f67033
ca8410d
1a2baec
9127104
5fdf934
59654ad
f20899a
51141bb
b7977d2
64064b8
a8df430
1029f33
d185acf
3938b1e
688da96
8b83148
500ec7f
74f79fe
40d7120
387a4aa
f063b37
4cde00c
2e69615
1583545
ff64a99
dd9babf
de3fff6
3c2fa56
3ba85dd
7f0b952
2b05ca2
0df6ea2
aaca421
ce9cc85
207b440
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -8,7 +8,7 @@ | |||||||||
from collections.abc import Iterator, MutableSet | ||||||||||
from email.message import Message | ||||||||||
from importlib import metadata as importlib_metadata | ||||||||||
from typing import Any, Protocol | ||||||||||
from typing import Any, Iterable, Protocol | ||||||||||
|
||||||||||
from toga.command import CommandSet | ||||||||||
from toga.documents import Document | ||||||||||
|
@@ -74,22 +74,14 @@ class WindowSet(MutableSet): | |||||||||
def __init__(self, app: App): | ||||||||||
"""A collection of windows managed by an app. | ||||||||||
|
||||||||||
A window is automatically added to the app when it is shown. Alternatively, the | ||||||||||
window can be explicitly added to the app (without being shown) using | ||||||||||
``app.windows.add(toga.Window(...))`` or ``app.windows += toga.Window(...)``. | ||||||||||
Adding a window to an App's window set automatically sets the | ||||||||||
A window is automatically added to the app when it is created, and removed when | ||||||||||
it is closed. Adding a window to an App's window set automatically sets the | ||||||||||
:attr:`~toga.Window.app` property of the Window. | ||||||||||
|
||||||||||
:param app: The app maintaining the window set. | ||||||||||
""" | ||||||||||
self.app = app | ||||||||||
self.elements = set() | ||||||||||
|
||||||||||
def add(self, window: Window) -> None: | ||||||||||
"""Add a window to the window set. | ||||||||||
|
||||||||||
:param window: The :class:`toga.Window` to add | ||||||||||
""" | ||||||||||
if not isinstance(window, Window): | ||||||||||
raise TypeError("Can only add objects of type toga.Window") | ||||||||||
# Silently not add if duplicate | ||||||||||
|
@@ -98,24 +90,12 @@ def add(self, window: Window) -> None: | |||||||||
window.app = self.app | ||||||||||
|
||||||||||
def discard(self, window: Window) -> None: | ||||||||||
"""Remove a window from the Window set. | ||||||||||
|
||||||||||
:param window: The :class:`toga.Window` to remove. | ||||||||||
""" | ||||||||||
if not isinstance(window, Window): | ||||||||||
raise TypeError("Can only discard objects of type toga.Window") | ||||||||||
if window not in self.elements: | ||||||||||
raise ValueError(f"{window!r} is not part of this app") | ||||||||||
self.elements.remove(window) | ||||||||||
|
||||||||||
def __iadd__(self, window: Window) -> None: | ||||||||||
self.add(window) | ||||||||||
return self | ||||||||||
|
||||||||||
def __isub__(self, other: Window) -> None: | ||||||||||
self.discard(other) | ||||||||||
return self | ||||||||||
|
||||||||||
def __iter__(self) -> Iterator: | ||||||||||
return iter(self.elements) | ||||||||||
|
||||||||||
|
@@ -244,6 +224,7 @@ def __init__( | |||||||||
description: str | None = None, | ||||||||||
startup: AppStartupMethod | None = None, | ||||||||||
on_exit: OnExitHandler | None = None, | ||||||||||
windows=None, # DEPRECATED | ||||||||||
): | ||||||||||
"""Create a new App instance. | ||||||||||
|
||||||||||
|
@@ -281,7 +262,22 @@ def __init__( | |||||||||
:param description: A brief (one line) description of the app. If not provided, | ||||||||||
the metadata key ``Summary`` will be used. | ||||||||||
:param startup: A callable to run before starting the app. | ||||||||||
:param on_exit: The handler to invoke before the application exits. | ||||||||||
:param windows: **DEPRECATED** – Windows are now automatically added to the | ||||||||||
current app. Passing this argument will cause an exception. | ||||||||||
""" | ||||||||||
###################################################################### | ||||||||||
# 2023-10: Backwards compatibility | ||||||||||
###################################################################### | ||||||||||
if windows is not None: | ||||||||||
raise ValueError( | ||||||||||
"The `windows` constructor argument of toga.App has been removed. " | ||||||||||
"Windows are now automatically added to the current app." | ||||||||||
) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why a full exception? Elsewhere we've logged a DeprecationWarning and transformed the input as best we can. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As part of the Window audit, I changed it so that Windows are added to the App when they're created, instead of when they're shown. Then as part of this PR, I added a check to make sure that the App is created before the Window: Lines 134 to 137 in ff64a99
I appreciate that this may break some existing code, but I think it's worth it because it makes it significantly easier to reason about the relationship between App and Window, both for us and for the users. Anyone who's been following the style of the Toga examples will not be affected. This means that any windows passed to the App constructor must already have been added to a different App. so there's no way we can handle that situation sensibly. |
||||||||||
###################################################################### | ||||||||||
# End backwards compatibility | ||||||||||
###################################################################### | ||||||||||
|
||||||||||
# Initialize empty widgets registry | ||||||||||
self._widgets = WidgetRegistry() | ||||||||||
|
||||||||||
|
@@ -416,7 +412,7 @@ def __init__( | |||||||||
self._startup_method = startup | ||||||||||
|
||||||||||
self._main_window = None | ||||||||||
self.windows = WindowSet(self) | ||||||||||
self._windows = WindowSet(self) | ||||||||||
|
||||||||||
self._full_screen_windows = None | ||||||||||
|
||||||||||
|
@@ -525,6 +521,12 @@ def widgets(self) -> WidgetRegistry: | |||||||||
""" | ||||||||||
return self._widgets | ||||||||||
|
||||||||||
@property | ||||||||||
def windows(self) -> Iterable[Window]: | ||||||||||
"""The windows managed by the app. Windows are added to the app when they are | ||||||||||
created, and removed when they are closed.""" | ||||||||||
mhsmith marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
return self._windows | ||||||||||
|
||||||||||
@property | ||||||||||
def main_window(self) -> MainWindow: | ||||||||||
"""The main window for the app.""" | ||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although they're no longer required, there will be enough code in existence that uses these methods that I don't think we can delete them completely. Toga's own examples contain a bunch of uses of this.
At the very least, they should exist, but be no-ops that log DeprecationWarnings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I've restored them and added warnings, since they were never consistent with the standard set interface anyway.
I could only find one remaining usage in the examples, which I see you've already removed in #2160.