Document

A representation of a file on disk that will be displayed in one or more windows.

Availability (Key)

macOS

GTK

Windows

iOS

Android

Web

Terminal

Usage

A common requirement for apps is to view or edit a particular type of file. In Toga, you define a toga.Document class to represent each type of content that your app is able to manipulate. This Document class is then registered with your app when the App instance is created.

The toga.Document class describes how your document can be read, displayed, and saved. It also tracks whether the document has been modified. In this example, the code declares an “Example Document” document type, which will create files with the extensions .mydoc and .mydocument; because it is listed first, the .mydoc extension will be the default for documents of this type. The main window for this document type contains a MultilineTextInput. Whenever the content of that widget changes, the document is marked as modified:

import toga

class ExampleDocument(toga.Document):
    description = "Example Document"
    extensions = ["mydoc", "mydocument"]

    def create(self):
        # Create the main window for the document. The window has a single widget;
        # when that widget changes, the document is modified.
        self.main_window = toga.DocumentMainWindow(
            doc=self,
            content=toga.MultilineTextInput(on_change=self.touch),
        )

    def read(self):
        # Read the content of the file represented by the document, and populate the
        # widgets in the main window with that content.
        with self.path.open() as f:
            self.main_window.content.value = f.read()

    def write(self):
        # Save the content currently displayed by the main window.
        with self.path.open("w") as f:
            f.write(self.main_window.content.value)

The document window uses the modification status to determine whether the window is allowed to close. If a document is modified, the user will be asked if they want to save changes to the document.

Registering document types

A document type is used by registering it with an app instance. The constructor for toga.App allows you to declare the collection of document types that your app supports. The first declared document type is treated as the default document type for your app; this is the type that will be connected to the keyboard shortcut of the NEW command.

After startup() returns, any filenames which were passed to the app by the operating system will be opened using the registered document types. If after this the app still has no windows, then:

  • On Windows and GTK, an untitled document of the default type will be opened.

  • On macOS, an Open dialog will be shown.

In the following example, the app will be able to manage documents of type ExampleDocument or OtherDocument, with ExampleDocument being the default content type. The app is configured to not have a single “main” window, so the life cycle of the app is not tied to a specific window.

import toga

class ExampleApp(toga.App):
    def startup(self):
        # The app does not have a single main window
        self.main_window = None

app = ExampleApp(
    "Document App",
    "com.example.documentapp",
    document_types=[ExampleDocument, OtherDocument]
)

app.main_loop()

By declaring these document types, the app will automatically have file management commands (New, Open, Save, etc) added.

Reference

class toga.Document(app)

Bases: ABC

Create a new Document. Do not call this constructor directly - use DocumentSet.new, DocumentSet.open or DocumentSet.request_open instead.

Parameters:

app (App) – The application the document is associated with.

property app: App

The app that this document is associated with (read-only).

abstractmethod create()

Create the window (or windows) for the document.

This method must, at a minimum, assign the main_window property. It may also create additional windows or UI elements if desired.

Return type:

None

description: str

A short description of the type of document (e.g., “Text document”). This is a class variable that subclasses should define.

extensions: list[str]

["doc", "txt"]). The list must have at least one extension; the first is the default extension for documents of this type. This is a class variable that subclasses should define.

focus()

Give the document focus in the app.

hide()

Hide the visual representation for this document.

Return type:

None

property main_window: Window | None

The main window for the document.

property modified: bool

Has the document been modified?

open(path)

Open a file as a document.

Parameters:

path (str | Path) – The file to open.

property path: Path

The path where the document is stored (read-only).

abstractmethod read()

Load a representation of the document into memory from path, and populate the document window.

Return type:

None

save(path=None)

Save the document as a file.

If a path is provided, the path for the document will be updated. Otherwise, the existing path will be used.

If the write() method has not been implemented, this method is a no-op.

Parameters:

path (str | Path | None) – If provided, the new file name for the document.

show()

Show the visual representation for this document.

Return type:

None

property title: str

The title of the document.

This will be used as the default title of a toga.DocumentWindow that contains the document.

touch(*args, **kwargs)

Mark the document as modified.

This method accepts *args and **kwargs so that it can be used as an on_change handler; these arguments are not used.

write()

Persist a representation of the current state of the document.

This method is a no-op by default, to allow for read-only document types.

Return type:

None

class toga.documents.DocumentSet(app, types)

Bases: Sequence[Document], Mapping[Path, Document]

A collection of documents managed by an app.

A document is automatically added to the app when it is created, and removed when it is closed. The document collection will be stored in the order that documents were created.

Parameters:
  • app (App) – The app that this instance is bound to.

  • types (list[type[Document]]) – The document types managed by this app.

new(document_type)

Create a new document of the given type, and show the document window.

Parameters:

document_type (type[Document]) – The document type that has been requested.

Returns:

The newly created document.

Return type:

Document

open(path)

Open a document in the app, and show the document window.

If the provided path is already an open document, the existing representation for the document will be given focus.

Parameters:

path (Path | str) – The path to the document to be opened.

Returns:

The document that was opened.

Raises:

ValueError – If the path describes a file that is of a type that doesn’t match a registered document type.

Return type:

Document

async request_open()

Present a dialog asking the user for a document to open, and pass the selected path to open().

Returns:

The document that was opened.

Raises:

ValueError – If the path describes a file that is of a type that doesn’t match a registered document type.

Return type:

Document

async save()

Save the current content of an app.

If there isn’t a current window, or current window doesn’t define a save() method, the save request will be ignored.

async save_all()

Save the state of all content in the app.

This method will attempt to call save() on every window associated with the app. Any windows that do not provide a save() method will be ignored.

async save_as()

Save the current content of an app under a different filename.

If there isn’t a current window, or the current window hasn’t defined a save_as() method, the save-as request will be ignored.

property types: list[type[Document]]

The list of document types the app can manage.

The first document type in the list is the app’s default document type.