--- title: How to build an app with Python and GTK on ChromeOS date: 2025-08-09 modified: 2025-08-09 slug: how-to-build-an-app-with-python-and-gtk-on-chromeos cover: https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/YQnTaPvCLGo/upload/587e563269347aa821b8cd303da2fc79.jpeg tags: chromebook, python, chromeos, gtk-4 category: GTK lang: en_US status: published --- To prepare a Chromebook development environment for creating applications using Python (PyGObject) and the GTK graphical toolkit, follow these steps. **Note**: The Linux environment must be configured on ChromeOS beforehand. Additional configurations may be necessary depending on the Debian version. ## Debian Bookworm Debian Bookworm includes GTK 4 packages in its stable repositories. Open the terminal and execute the following command: ```bash sudo apt -t sid install \ python3-full \ python3-dev \ python3-gi \ python3-gi-cairo \ libcairo2-dev \ libgirepository1.0-dev \ gir1.2-gtk-4.0 \ libgtk-4-dev \ libadwaita-1-dev ``` Once the installation is complete, Python, PyGObject binding, and GTK graphics libraries will be installed on ChromeOS. ## Debian Buster and Bullseye For Debian Buster and Bullseye, GTK 4 packages are not available in stable repositories, requiring the configuration of the `sid` repository. ### Debian Sid To add the **sid repository**, edit the `sources.list` file. Open the terminal and install `nano` if you are not familiar with `vi` or `vim`: ```bash sudo apt install nano ``` After installation, type the following in the terminal: ```bash sudo nano /etc/apt/sources.list ``` Now, add the **testing** (sid) repository to the `sources.list` file: ```bash # Generated by distrobuilder deb https://deb.debian.org/debian bullseye main deb https://deb.debian.org/debian bullseye-updates main deb https://deb.debian.org/debian-security/ bullseye-security main deb http://http.us.debian.org/debian sid main non-free contrib ``` **Warning**: Do not run `sudo apt update` or `sudo apt upgrade`! Next, create or edit the `preferences` file. If this configuration is not done, the system will attempt to update all packages, potentially leading to broken packages. In the terminal, execute: ```bash sudo nano /etc/apt/preferences ``` Inside this file, add the following code: ```bash Package: * Pin: release a=stable Pin-Priority: 700 Package: * Pin: release a=testing Pin-Priority: 650 Package: * Pin: release a=unstable Pin-Priority: 600 ``` Save the file, then update the repositories: ```bash sudo apt update ``` After the repository update is finished, run the following command to install the necessary packages: ```bash sudo apt -t sid install \ python3-full \ python3-dev \ python3-gi \ python3-gi-cairo \ libcairo2-dev \ libgirepository1.0-dev \ gir1.2-gtk-4.0 \ libgtk-4-dev \ libadwaita-1-dev ``` After installation, Python, GTK 4 toolkit, and PyGObject binding will be ready for use on ChromeOS. ## Virtual Environments Consider using virtual environments for project isolation. Some popular options include: * Poetry * Pipenv * Pyenv * PDM * venv (native) ### Creating a Virtual Environment Navigate to your project's root folder, open a terminal, and execute: ```bash python3 -m venv venv ``` To create a virtual environment with a **specific Python version**, use: ```bash python3.X -m venv venv ``` **Note**: Replace `X` with the desired Python version, and ensure the version is installed on your operating system. ### Activating the Virtual Environment After creation, the virtual environment **must be activated**; otherwise, packages will be installed in the system's local Python installation. To activate: ```bash source venv/bin/activate ``` ### Installing the Binding **With the virtual environment active**, first upgrade `pip`: ```bash python -m pip install \ --upgrade pip ``` Then, install the `PyGObject` binding and `PyGObject-stubs` library: ```bash pip install \ pygobject \ PyGObject-stubs ``` This sets up an isolated environment for development. ## Testing The simplest way to test communication between Python and GTK is by running the following command in the terminal: ```bash python3 -c "import gi" ``` **Note**: This command must be executed with the virtual environment active! If no errors are returned, the Python and GTK environment setup on your Chromebook is correct. ## Example Code Use the following example code in your text editor or IDE to test the configuration: ```python # -*- coding: utf-8 -*- """Python e GTK: PyGObject Gtk.ApplicationWindow().""" import gi gi.require_version(namespace='Gtk', version='4.0') gi.require_version(namespace='Adw', version='1') from gi.repository import Adw, Gio, Gtk Adw.init() class ExampleWindow(Gtk.ApplicationWindow): def __init__(self, **kwargs): super().__init__(**kwargs) self.set_title(title='Python - PyGObjet - GTK:') self.set_default_size(width=int(1366 / 2), height=int(768 / 2)) self.set_size_request(width=int(1366 / 2), height=int(768 / 2)) headerbar = Gtk.HeaderBar.new() self.set_titlebar(titlebar=headerbar) menu_button_model = Gio.Menu() menu_button_model.append('Preferências', 'app.preferences') menu_button = Gtk.MenuButton.new() menu_button.set_icon_name(icon_name='open-menu-symbolic') menu_button.set_menu_model(menu_model=menu_button_model) headerbar.pack_end(child=menu_button) # Your code here: # ... class ExampleApplication(Adw.Application): def __init__(self): super().__init__(application_id='br.com.justcode.Example', flags=Gio.ApplicationFlags.FLAGS_NONE) self.create_action('quit', self.exit_app, ['q']) self.create_action('preferences', self.on_preferences_action) def do_activate(self): win = self.props.active_window if not win: win = ExampleWindow(application=self) win.present() def do_startup(self): Gtk.Application.do_startup(self) def do_shutdown(self): Gtk.Application.do_shutdown(self) def on_preferences_action(self, action, param): print('Ação app.preferences foi ativa.') def exit_app(self, action, param): self.quit() def create_action(self, name, callback, shortcuts=None): action = Gio.SimpleAction.new(name, None) action.connect('activate', callback) self.add_action(action) if shortcuts: self.set_accels_for_action(f'app.{name}', shortcuts) if __name__ == '__main__': import sys app = ExampleApplication() app.run(sys.argv) ```