How to build an app with Python and GTK on ChromeOS


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:
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
:
sudo apt install nano
After installation, type the following in the terminal:
sudo nano /etc/apt/sources.list
Now, add the testing (sid) repository to the sources.list
file:
# 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:
sudo nano /etc/apt/preferences
Inside this file, add the following code:
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:
sudo apt update
After the repository update is finished, run the following command to install the necessary packages:
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:
python3 -m venv venv
To create a virtual environment with a specific Python version, use:
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:
source venv/bin/activate
Installing the Binding
With the virtual environment active, first upgrade pip
:
python -m pip install \
--upgrade pip
Then, install the PyGObject
binding and PyGObject-stubs
library:
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:
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:
# -*- 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, ['<primary>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)
Subscribe to my newsletter
Read articles from Renato Cruz directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
