User alert: in October 2024, the Pydroid 3 app's version 7.4 has finally gained Android's All Files Access permission, which means you may again download, unzip, and run the programs here anywhere in shared (a.k.a. internal) storage on your phone or drives. Likewise, your data files, including calendars in Frigcal, may be kept anywhere in shared storage, and freely accessed there by other apps. This is a recent development, and reverses a 2023 change in the app's version 6 that radically reduced program functionality. For more info, see this page.
Version: | June 8, 2019 (revised Jan-2021) |
Author: | © M. Lutz, learning-python.com |
Quick links: | View and
fetch this guide's media |
View the related Mergeall doc |
This document describes how to run tkinter GUI programs on Android in the Pydroid 3 app's IDE (its edit+run GUI). This app recently added fledgling but astonishing tkinter support, which allows many Python 3.X programs with tkinter GUIs to be run in source-code form on smartphones, with no or minimal changes. The focus here is on using this app to run both the complete application programs at this site as well as the tutorial examples in the book Programming Python, 4th Edition (a.k.a. PP4E), but this coverage should apply to tkinter GUIs on Android devices in general.
Please note: the programs described here are wholly dependent on five other systems—Android, vendor extensions, Python, Android Tk, and Pydroid 3—all of which regularly change their behavior for both better and worse. Undocumented changes in Pydroid 3, for example, recently forced patches here and here, and Android currently threatens a much broader sea change. It's difficult for documentation to remain current in this context, and just as tough for programs to continue working as intended.
While this guide presents potentially useful information and software that hope to be updated periodically, its content should be taken as a point-in-time snapshot. As usual, you should judge platform viability for yourself in whatever reality has bubbled up from a stew of morphing systems by the time you read these words.
Android 11 Happens
And bubbled it has: initial testing of Android 11 in early January 2021 regrettably suggests that some of the programs noted in this guide may be partly or wholly unusable on this Android today, though this story may improve over time with app and vendor fixes. Please see the off-page update here for details, and consider postponing an Android 11 install on your phone until its full implications for the programs you use are clearer.
Mergeall users: you probably cannot use the Mergeall GUI described here for syncs on Android 11 and later, because this platform revokes direct USB access for POSIX programs coded in Python, and microSD cards are increasingly rare. See the update on the original Mergeall scripts' page for more info; the interim Android Deltas Sync non-GUI alternative for performing syncs on later Androids (and more); and the standalone-app update below for a later solution. Other GUIs on this page are not harmed as badly by 11's changes.
And So Does Android 12
Late in 2021, Android 12 introduced a "phantom process killer" which starts terminating
child processes at arbitrary points after 32 are running. This has the
potential to impact Python programs of all sorts, including tkinter
GUIs. The impact can be mitigated by a new Developer feature flag or
adb
command in
Android 12L and 13, and depends on how you use your phone; a Fold3,
for example, has not triggered a single process kill in one year of usage
(and a 12L Fold4 is faring the same).
See the full details
here.
As of May 2023, the new Kivy/buildozer Android app PC-Phone USB Sync largely replaces the former Mergeall tkinter GUI described ahead. Unlike source code run in Pydroid 3's IDE (until its 2024 fix), the new standalone app is able to use All Files Access permission to process content on removable USB drives; retains the shared-storage access revoked later by Pydroid 3's version 6; skirts process culls with foreground services; and provides a much more seamless and paradigmatic Android user experience.
For info on the new app, please see its separate website, as well as coverage on pages like this and this. Such apps must also use Kivy or other toolkits to build their GUIs because there is no support for tkinter-based apps today, but are nevertheless recommended for new Python development on Android. Running code in Pydroid 3 may suffice for learning Python basics sans a PC, but little else.
Before jumping into specific programs, here are a few administrative and global notes up front:
Findings here reflect versions 2.22 and 3.0 of Pydroid 3; 3.6 and 3.7 of Python; 7, 8, and 9 of Android (Nougat, Oreo, and Pie); and 8.6 of the Tk library wrapped by tkinter (in an Android port of unknown origin). Programs described here are currently known to work on all these systems, except where noted ahead. Per the notebox above, be sure to check facts here against these systems' current status if you're reading this in the future.
Suggestions for Pydroid 3 fullscreen and maximized viewing modes vary per program ahead. In general, fullscreen mode saves space but may conflict with Android's status-bar pulldown at display top; maximized mode uses space well, but works only for GUIs without persistent popup windows, and with either explicit exit widgets or no need to process or verify exits (Pydroid 3 double-back exits do not run program exit handlers).
More on Fitting tkinter GUIs to Your Display
(Added fall 2020) Like most Android apps, the programs described on this page are sensitive to Android font-size, screen-zoom, and display-resolution settings and specs, and may vary in appearance and fit across devices. If parts of a GUI are clipped or offscreen on your display, try these options to see more content:
Pydroid 3's options at the top of this list are among the easiest solutions. They're all accessed by opening the app's top-left-corner pulldown, selecting "Settings," and tapping "System." They're also largely undocumented and come with tradeoffs, and merit a few extra words here:
Downsides: you'll need to access the status bar manually if needed while using the GUI, and a GUI's window border can interfere with a pulled-down status bar when both are present at the top of the display.
Downsides: this mode works well for GUIs that follow the one-window-at-a-time paradigm of Android apps, but makes it difficult—or impossible—to use desktop-metaphor GUIs with multiple persistent windows. Perhaps worse, this mode omits window-border titles and exit buttons that may be useful or required in some GUIs; Pydroid 3's double-back exit provides an alternative to window-border exit, but it may skip crucial tkinter exit handlers that finalize changed content (and is now single-back exit in Pydroid 3 4.X on some devices, oddly; more details here).
Downsides: at very-low DPI values, some widgets may be too small to see or use. Moreover, the available DPI values seem too sparse; you can't pick one between those offered, even if it may work better.
You may not prefer the results of some Pydroid 3 settings, and some may not work for specific GUIs (e.g., maximizing the first window hides the window-border exit button needed to save Frigcal changes). Tweak as desired for your GUIs and devices.
Example: a Galaxy Note20 Ultra's 120Hz screen required a lower resolution setting, which in turn made all tkinter GUIs larger and pushed one dialog's text partly off-screen. A lower Pydroid 3 screen-DPI setting of 320 improved size and fit, fixed the dialog, and roughly matched higher-resolution appearance at "Auto" DPI. See the effects of DPI and font settings on GUIs and dialogs for yourself in the captures gallery here.
Most of the tutorial-level tkinter GUI examples in the book Programming Python, 4th Edition work unchanged in Pydroid 3. True to its educational focus, this makes Pydroid 3 viable as a platform for working along with the book's presentation.
Here's a sample of the book's programs running on Android in Pydroid 3:
You can also view these screenshots in slideshow mode starting here.
Most of these examples yield smaller displays, which need not use tkinter fullscreen or maximized modes in Pydroid 3, but experiment with screen modes and phone orientations for best effect. Note that double-back exits in any viewing mode do not run tkinter exit handlers, and rotating the screen after a GUI is running may not work on some devices per usage notes ahead.
PP4E-Examples-1.4/Examples/PP4E/Gui
But navigate the examples-package tree to find additional tkinter code to run. Naturally, only this last step must be repeated whenever you wish to run an example.
Also keep the following in mind when using PP4E book examples on Android:
Gui
folder.
Shortcuts look like
this or
this,
and can be made by multiple Android file explorers including the app
here,
but be sure to set the default app or command to Pydroid 3.
Tip: uncheck "Parameters" when making shortcuts in Total Commander 3.0
(details).
On some devices, Pydroid 3 either kills the GUI silently or hangs altogether if the screen is rotated between portrait and landscape orientations while a tkinter GUI is running. Per details here, rotations are known to fail on multiple Samsung devices, but the latest of these rotate correctly if they avoid the Small screen-zoom display setting. If your rotates don't work, change your screen zoom to Medium or Large, apply system updates, or don't rotate.
In the same department as the preceding note: per here, changing phone orientation during a spawned activity (e.g., a Share or program-help browse) may cause the GUI to slide off screen or similarly hang, even on devices that handle rotations in general. Rotate twice to restore the GUI where supported.
sys.path
list at the start of examples' code.
Use the unzipped examples folder's path up to and including its
Examples
folder. For example, after an import sys
:
sys.path.append('/sdcard/Download/PP4E-Examples-1.4/Examples')
pip install Pillow
command line in Pydroid 3's
Terminal, or use the app's Pip interface. Both can be found in the
app's main (top left) menu. Pillow subsumes PIL, and generally
requires no code changes in book examples.
helvetica
,
but its other font limitations described here are still present.
Because some font types cause tkinter GUIs to crash silently in Pydroid 3,
examples that use custom text fonts may require code changes.
In general, font families courier
,
times
, and helvetica
work (and monaco
is
courier
and arial
is helvetica
), but most
others crash the GUI, and italic and bold styles are ignored for courier
.
sys.executable
and
webbrowser
spawning workarounds described
here).
On the other hand, changing code is a normal part of the book's learning
experience, and a few blemishes seem a reasonable price for running PC-level
GUIs on a phone.
Preface: as of May 2023, Mergeall's original tkinter GUI described here has been subsumed and superseded on Android by the standalone app PC-Phone USB Sync. This new app uses Android's All Files Access permissions to regain access to both removable storage (e.g., USB drives) lost in Android 11, and general shared storage temporarily lost in Pydroid 3 version 6. Mergeall's tkinter GUI still runs on Android in Pydroid 3 today, but is largely moot; please use the new app instead.
Mergeall—an incremental-backup and change-propagation system—can be used to sync on-phone content to and from removable media. This program has both a command-line mode usable in apps like Termux, as well as a tkinter GUI usable in Pydroid 3. Pydroid 3 has a Terminal interface too, but it's too limited to recommend for Mergeall's command-line mode. The following summarizes the expanded coverage in this document, and augments Mergeall's base user guide. Note that Mergeall changes a destination folder by design; use it with care.
Mergeall's GUI looks like this when run on Android in Pydroid 3:
You can also view these screenshots in slideshow mode starting here.
Mergeall's GUI is usable in either landscape or portrait phone orientation, though portrait mode displays more run messages without scrolls, and landscape is less likely to truncate GUI content. Per usage notes ahead, rotating the screen after the GUI is running may not work on some devices.
Because Mergeall's GUI has no persistent popup windows and its exit verification can be skipped, it may render and work best using Pydroid 3's tkinter fullscreen and maximized viewing modes, the latter of which automatically resizes for fit on rotations. Select these modes by turning the first "Tkinter" switch off and the second on in Pydroid 3's Settings ⇨ System dialog before running the GUI, and press your phone's back button twice to exit the GUI. Mergeall's GUI can be run in non-fullscreen and non-maximized viewing modes too (see the captures above), but they hold little usage advantage.
To run Mergeall on your Android device, follow these steps:
And move them to the top level of your unzipped Mergeall source-code package, replacing their original versions. Download by clicking "save" in the "Raw text" line of these links' pages, and search for "# ANDROID" to see code changes made if desired. Note: some browsers may append a bogus ".txt" to the end of a saved ".pyw" file's name; delete the ".txt" manually by renaming.
launch-mergeall-GUI.pyw
in the Pydroid 3
app's editor, and pressing the editor's big yellow run
button.
Mergeall's GUI should appear, and work largely the same as it does on
PCs.
Naturally, only this last step must be repeated on later runs.
Also keep the following in mind when using Mergeall on Android:
launch-mergeall-GUI.pyw
source-code file.
Shortcuts look like
this or
this,
and can be made by multiple Android file explorers including the app
here,
but be sure to set the default app or command to Pydroid 3.
Tip: uncheck "Parameters" when making shortcuts in Total Commander 3.0
(details).
On some devices, Pydroid 3 either kills the GUI silently or hangs altogether if the screen is rotated between portrait and landscape orientations while a tkinter GUI is running. Per details here, rotations are known to fail on multiple Samsung devices, but the latest of these rotate correctly if they avoid the Small screen-zoom display setting. If your rotates don't work, change your screen zoom to Medium or Large, apply system updates, or don't rotate.
In the same department as the preceding note: per here, changing phone orientation during a spawned activity (e.g., a Share or program-help browse) may cause the GUI to slide off screen or similarly hang, even on devices that handle rotations in general. Rotate twice to restore the GUI where supported.
Removable media used with Mergeall on Android should generally be formatted as FAT32 instead of exFAT, due to an existing Android exFAT timestamp bug which may skew file modification times both read and written (by 16 hours in US Pacific time), and hampers Mergeall file comparisons. To date, this bug has been observed on Samsung Android devices only, though it appears on multiple such devices, and its full scope is unknown. Note that file times on FAT32 drives may need to be adjusted on daylight-savings-time (DST) rollovers to make them compare correctly with times on non-FAT drives that use UTC-based time; for details and instructions, see this note.
Mergeall can be used with both Termux command lines and Pydroid 3 GUIs.
The full story on its storage constraints for Termux and Pydroid 3 is
here and
here. In brief,
because both Termux and Pydroid 3 can update only their own app-specific
folders on removable media, you must either choose which app will update
removable-media content and nest it appropriately (see the next note),
or locate your content anywhere in internal storage (e.g., /sdcard
)
where it can be updated by both apps.
If you choose to use Mergeall in Pydroid 3 only, content that will only
be read can be located anywhere. Content that will be updated
can be located anywhere in internal storage (e.g., /sdcard
),
or nested in Pydroid 3's app-specific folder created manually on removable drives
and named as follows (where the x
s are your drive's Android ID):
/storage/xxxx-xxxx/Android/data/ru.iiec.pydroid3
Merging to removable media looks like this in the GUI.
cpall.py
utility from a command-line interface;
or by running a sync in Mergeall's GUI to an empty folder.
See the Mergeall-on-Android how-to's extended coverage
here and
here.
helvetica
,
but its other font limitations described here are still present.
Because some font types cause tkinter GUIs to crash silently in Pydroid 3,
Mergeall's configuration file mergeall_configs.py
was changed
to disable text-area font customization by presetting it to None, which
applies the system default.
Experiment with font settings in this file as desired. In general, font families courier
,
times
, and helvetica
work (and monaco
is
courier
and arial
is helvetica
), but most
others crash the GUI, and italic and bold styles are ignored for courier
.
You can still use the GUI's
Browse buttons
to pick arbitrary folders as before (in addition to manual entry
and file-explorer copy/paste), but the new starting-folder settings can
make the dialog less frustrating, and the new prefills will likely suffice
in most common usage (and are the Pydroid 3 GUI equivalent of
Termux command-line $plug
and $data
shell
settings).
The logfile default folder was also changed to Admin-Mergeall
in /sdcard
; its former Documents
might not
exist unless you run MS Office apps.
Tip: if you opt to use the Browse file-chooser dialogs instead of the new prefill settings (or must use the dialogs for a run's unique requirements), spread/pinch zooms can make these dialogs much more usable, especially on smaller displays. See the general tkinter usage notes here for more.
If labels are still too wide for a smaller phone you use,
either interact with the GUI in landscape mode for more
space (and rotate to portrait to see more messages where
supported);
edit the code to shorten labels further (search for
"# ANDROID - shorter" in
launch-mergeall-GUI.pyw
to find labels' text);
or simply change the new LABELFONT
setting in the
configurations file to
a smaller custom font.
For symmetry, a new HEADERFONT
in the same file supports
custom section-header fonts too, but its default is small enough on
all devices tested, and usually leaves room for messages.
webbrowser
module they employ. This required users to open
Mergeall's user guide and logfiles outside the GUI (the user guide is
available both at the top level of the source-code package and
online,
and logfiles appear after a run in the folder chosen in the GUI).
This program worked around the webbrowser
issues
in April 2019, using techniques described
here and
here.
Hence, Mergeall's
user guide
and
logfiles now
open from within the GUI on Android just as they do on PCs, though
viewer options may be limited, and Android always displays the online
version of help to include recent changes; open files manually if they
are subpar in the GUI.
Mergeall's "Help" button is also uncolored on Android, due to
an unrelated tkinter
issue.
Caution: changing phone orientation during spawned activities can
misplace or hang the GUI; see the earlier rotations note.
Version 3.0 mods:
as of October 2024, the new 3.0 release of Frigcal integrates all required
Android patches in its source-code package, so the extra patches described below
need no longer be applied. Simply download the source-code
package, unzip on your phone, and
open and run the resulting "frigcal-main.py" in Pydroid 3 to start the
program. For more 3.0 usage tips, please see this release's
README-3.0.txt.
Temporary storage issue: in 2023,
Frigcal was adversely impacted by the new version 6 of Pydroid 3, which
revoked access to general shared storage from Python code. The net effect
meant that Frigcal users had to either use an older Pydroid 3, or unzip Frigcal
in a Pydroid 3 folder and import/export their calendar files to this folder with
manual copies. Per the alert at the top of this page, this
constraint has been removed in the app's 2024 version 7, but its coverage
remains here.
Standalone apps avoid such Pydroid 3 dependencies.
Frigcal—a personal calendar program that uses portable iCalendar ICS files for event storage—can be used on Android to view and edit calendars which can also be used on other platforms, including Windows, Mac OS, and Linux PCs. Frigcal's animated launcher is not currently supported, but its main script can be run directly. This program runs only as a GUI. The following augments Frigcal's base user guide.
Frigcal's GUI looks like this when run on Android in Pydroid 3:
You can also view these screenshots in slideshow mode starting here.
Due to its size, Frigcal's GUI may work best in landscape (horizontal) phone orientation to maximize event label size. Per usage notes ahead, rotating the screen after the GUI is running may not work on some devices; where needed, rotate your phone to landscape orientation before running the program, and view more events by clicking a day's number or rotating to portrait where supported (more on event views ahead).
Pydroid 3's maximized viewing mode cannot be used for Frigcal if you wish to either save calendar changes or view Frigcal's persistent popup windows like month clones and images. Most importantly, saves do not work in this mode because they happen in Frigcal only on exit requests; maximized mode hides the window-border exit button; Frigcal has no exit button of its own; and Pydroid 3 double-back exits do not run GUIs' exit handers. Persistent popups can't be viewed because the main window overlays and thus hides them.
Technically, Pydroid 3's double-back exits can be used in either maximized or non-maximized modes, but are the only Frigcal exit option in the former. Hence, maximized mode makes sense for Frigcal only when viewing but not changing calendars, and you should always use the window-border's upper-right "X" exit button instead of double-back exits in non-maximized mode unless you have no calendar changes to save.
Select or disable maximized mode before running the GUI with "Tkinter: maximize first window" in Pydroid 3's Settings ⇨ System dialog, and use a stylus or mouse for best window move/resize results in non-maximized mode; when used, maximized mode automatically sizes for fit.
(Much of the following no longer applies as of Frigcal 3.0: see the note above)
To run Frigcal on your Android device, follow these steps:
And move them to the top level of your unzipped Frigcal source-code package, replacing their original versions. Download by clicking "save" in the "Raw text" line of these links' pages, and search for "# ANDROID" to see code changes made if desired.
frigcal-launcher.pyw
,
but this is not currently required, as it applies only to the unusable launcher (see Usage
Notes ahead). To experiment with its code, fetch and move this file to the
top level of the unzipped package.
Note: some browsers may append a bogus ".txt" to the end of a saved ".pyw" file's name;
delete the ".txt" manually by renaming.
frigcal.py
in the Pydroid 3
app's editor, and pressing the editor's big yellow run
button.
Frigcal's GUI should appear, and work largely the same as it does on
PCs.
Naturally, only this last step must be repeated on later runs.
Also keep the following in mind when using Frigcal on Android:
frigcal.py
source-code file.
Shortcuts look like
this or
this,
and can be made by multiple Android file explorers including the app
here,
but be sure to set the default app or command to Pydroid 3.
Tip: uncheck "Parameters" when making shortcuts in Total Commander 3.0
(details).
On some devices, Pydroid 3 either kills the GUI silently or hangs altogether if the screen is rotated between portrait and landscape orientations while a tkinter GUI is running. Per details here, rotations are known to fail on multiple Samsung devices, but the latest of these rotate correctly if they avoid the Small screen-zoom display setting. If your rotates don't work, change your screen zoom to Medium or Large, apply system updates, or don't rotate.
In the same department as the preceding note: per here, changing phone orientation during a spawned activity (e.g., a Share or program-help browse) may cause the GUI to slide off screen or similarly hang, even on devices that handle rotations in general. Rotate twice to restore the GUI where supported.
Also note that month name may not be visible in some usage modes (per the prior note), and the Footer feature is limited by screen size but not generally useful on Android anyhow without a mouse—stylus hovers (e.g., on Samsung Note devices) are recognized by Android but not dispatched by Pydroid 3's tkinter; Bluetooth mouse hovers are always dispatched; and fingers don't hover.
frigcal-launcher.pyw
,
displays its GUI but does not open the calendar,
because it is not possible to view the windows of a GUI program
started by another GUI program in
Pydroid 3.
Run Frigcal's main script
frigcal.py
directly instead per above.
For the latter option, both Google Gboard and Hacker's Keyboard on-screen keyboards correctly send newlines to Frigcal on return-key presses. The second of these also provides access to PyEdit menu shortcuts, and can be opened on demand for PyPhoto commands.
Ctrl+c
to copy and Ctrl-v
to paste in keyboards that
support these. You'll find support for these keys in both Bluetooth keyboards,
and alternative on-screen keyboards like
Hacker's Keyboard.
Due to Android and Pydroid 3 permission constraints, view-only calendars can
be stored anywhere on your device, but updatable calendars must be in a
folder that either is located anywhere in internal storage (e.g., /sdcard
),
or is nested in Pydroid 3's app-specific folder on removable-media.
To nest on removable media, locate your calendars folder in the following
manually created folder on your drive (the x
s are your drive's Android ID):
/storage/xxxx-xxxx/Android/data/ru.iiec.pydroid3
Updates to any other removable-storage folders will fail, like the sequence here, here, and here. Note that uninstalling an app deletes its app-specific folders, including any user content there.
icspath
in the Frigcal configurations file frigcal_configs.py
—to
the folder you'll use on the phone for calendars shared with PCs.
To make a new calendar file for Android use, run the Frigcal source-code package's
makenewcalendar.py
on either your PC or phone. On your phone, run this script by opening it in
Pydroid 3's IDE
like this
and pressing the yellow run button as usual, and enter a calendar name
like this.
Once created, choose the new calendar in the GUI
like this
You can also run the maker script
in the app's Terminal interface, but it's a lot of typing in a primitive
shell.
For more on Frigcal calendar files in general, see its user guide's coverage. You can also sync shared calendar files back and forth between PCs and phones, but a dedicated Android calendar supports changes more freely (though you should take care to avoid overwriting your Android calendar by to-phone content syncs).
pip install Pillow
in Pydroid 3's Terminal
window opened from its main menu, or use the app's Pip interface. More details
here.
helvetica
,
but its other font limitations described here are still present.
Because some font types cause tkinter GUIs to crash silently in Pydroid 3,
Frigcal's configuration file frigcal_configs.py
was changed to
disable most user font customizations by presetting them to None, which applies
system defaults. Experiment with Frigcal font settings in this file as desired.
In general, font families courier
,
times
, and helvetica
work (and monaco
is
courier
and arial
is helvetica
), but most
others crash the GUI, and italic and bold styles are ignored for courier
.
frigcal_configs.py
: the font of Frigcal's event edit/view
dialog
was preset for readability (system defaults are small); the initial size of
this dialog was preset for use on a phone (though it's resizable in the GUI);
and click mode was changed from double-click mouse
to single-click
touch
to minimize keyboard popups at the expense of inline summary
edits (see the
user guide
for more on the difference).
Tailor any of these for your usage, and see frigcal_configs_base.py
in
your source-code package for the full set of user-configurable options.
See also the smaller-phones fit note ahead for related notes.
webbrowser
module it employs. This required users to open
Frigcal's user guide outside the GUI (the user guide is
available both at the top level of the source-code package and
online).
This program worked around the webbrowser
issues
in April 2019, using techniques described
here and
here.
Hence, Frigcal's
user guide
now opens from within the GUI on Android just as it does on PCs, though
viewer options may be limited, and Android always displays the online
version of help to include recent changes; open the guide manually if
it is subpar in the GUI.
Caution: changing phone orientation during spawned activities can
misplace or hang the GUI; see the earlier rotations note.
frigcal_configs.py
.
to further tailor fonts for fit as desired.
Fine point: this file's new button-font preset is noticeably smaller than the default on
smaller
devices,
but may be no different on
yours;
tweak as you wish.
Despite the recent work, some Frigcal preset configurations may still render better
in landscape orientation and/or larger screens. The event edit/view dialog's 80-character
width, for example, works well in
landscape orientation on screens as small
as
5.5 inches
and handles larger event descriptions (including those you might create
on PCs), but will span off screen in
portrait orientation on many devices.
Like much on smartphones, this is an intractable tradeoff. To make this better fit
portrait mode at the expense of larger-note content, change the
eventdialogtextwidth
setting in
frigcal_configs.py
.
PyEdit—a general-purpose text editor and Python code launcher—can be used on Android to both edit arbitrary text files and run Python code being edited in the GUI. This program runs only as a GUI. The following augments PyEdit's base user guide.
PyEdit's GUI looks like this when run on Android in Pydroid 3:
You can also view these screenshots in slideshow mode starting here.
Due to phone size constraints, PyEdit's GUI may work best in landscape (horizontal) phone orientation, to avoid horizontal slides and toolbar truncation. Per usage notes ahead, rotating the screen after the GUI is running may not work on some devices; where needed and desired, rotate your phone to landscape orientation before running the program.
Because it opens many persistent popup windows and must verify program closes, PyEdit's GUI is better used without Pydroid 3's tkinter maximized viewing mode. This mode automatically resizes for fit, but it overlays persistent popups, and its lack of a window-border exit button encourages silent double-click exits that may discard changes. Maximized mode may be best used in PyEdit only to view, but not change, a single document. Select or disable this mode before running the GUI with "Tkinter: maximize first window" in Pydroid 3's Settings ⇨ System dialog, and use a stylus or mouse for best window move/resize results in non-maximized mode.
Whether you use maximized mode or not, do not exit the GUI with a Pydroid 3 double-back click, or unsaved changes may be lost. Instead, be sure to exit the GUI only by using its Quit toolbar button or File ⇨ Quit menu option available in all modes, or by pressing its window-border's "X" exit button available in non-maximized mode. All three techniques offer you a chance to save edits before the GUI closes.
To run PyEdit on your Android device, follow these steps:
And move them to the top level of your unzipped PyEdit source-code package, replacing their original versions. Download by clicking "save" in the "Raw text" line of these links' pages, and search for "# ANDROID" to see code changes made if desired.
textEditor.py
in the Pydroid 3
app's editor, and pressing the editor's big yellow run
button.
PyEdit's GUI should appear, and work largely the same as it does on
PCs.
Naturally, only this last step must be repeated on later runs.
Also keep the following in mind when using PyEdit on Android:
textEditor.py
source-code file.
Shortcuts look like
this or
this,
and can be made by multiple Android file explorers including the app
here,
but be sure to set the default app or command to Pydroid 3.
Tip: uncheck "Parameters" when making shortcuts in Total Commander 3.0
(details).
On some devices, Pydroid 3 either kills the GUI silently or hangs altogether if the screen is rotated between portrait and landscape orientations while a tkinter GUI is running. Per details here, rotations are known to fail on multiple Samsung devices, but the latest of these rotate correctly if they avoid the Small screen-zoom display setting. If your rotates don't work, change your screen zoom to Medium or Large, apply system updates, or don't rotate.
In the same department as the preceding note: per here, changing phone orientation during a spawned activity (e.g., a Share or program-help browse) may cause the GUI to slide off screen or similarly hang, even on devices that handle rotations in general. Rotate twice to restore the GUI where supported.
Alt
key for menu shortcuts, in keyboards that support this key;
use pulldown-menu or toolbar-button equivalents instead.
For the latter option, both Google Gboard and Hacker's Keyboard on-screen keyboards correctly send newlines to PyEdit on return-key presses. The second of these also has a full set of control and function keys useful for PyEdit menu shortcuts, and an on-demand-open feature useful for PyGadgets' PyPhoto operation (see ahead).
Ctrl+c
to copy and
Ctrl-v
to paste in keyboards that support these. You'll find support for
these keys in both Bluetooth keyboards, and alternative on-screen keyboards like
Hacker's Keyboard.
If the rectangle appears on your device, turning it on and off is easy: to disable, click your phone's back button once and tap the text anywhere on the screen before reusing your keyboard; to enable, click your phone's back button once and start reusing your keyboard without a screen tap. Strange (and undocumented, as far as a web search can tell) but true.
In Pydroid 3, PyEdit can both save (and auto-save) files anywhere in internal
storage (e.g., /sdcard
). On a removable drive, it can save (and auto-save)
files only in the Pydroid 3 app-specific folder, which is the drive's manually
created folder named as follows (the x
s mean your drive's Android ID):
/storage/xxxx-xxxx/Android/data/ru.iiec.pydroid3
Files can be viewed anywhere on your device, but saves are limited this way by Android and Pydroid 3 permission constraints. Note that uninstalling an app deletes its app-specific folders, including any user content there.
textConfig.py
was changed to use
threads instead of the multiprocessing
module for parallel
greps,
because the latter fails on Android due to that platform's lack of required
semaphore support. Threads work well in testing so far, though they cannot
leverage multiple CPU cores (a factor perhaps more important on PCs than phones).
helvetica
,
but its other font limitations described here are still present.
Because some font types cause tkinter GUIs to crash silently in Pydroid 3,
PyEdit's configuration file textConfig.py
was also changed to
disable most user font customizations by adding triple quotes above and
below custom settings.
The default fonts pick list was also changed to remove crashing fonts,
and a text-font preset was coded for readability (the system default is
likely too small for some readers to use).
Experiment with PyEdit font settings in the configuration
file as desired.
In general, font families courier
,
times
, and helvetica
work (and monaco
is
courier
and arial
is helvetica
), but most
others crash the GUI, and italic and bold styles are ignored for courier
.
filechooserstart
user
setting in the textConfig.py
configuration file. When set to
a valid folder (or None, to use the internal-storage root default), the
Open and Save file-chooser dialogs initially start at the folder specified,
instead of the Pydroid 3 app's app-private $HOME
folder nested
in /data/data
.
Later navigations pick up from the last folder selected as before, but the
new setting allows you to avoid a tedious initial navigation up and down to your
content folder. For examples and more details, see the configuration
file.
webbrowser
module it employs. This required users to open
PyEdit's user guide outside the GUI (the user guide is
available both at the top level of the source-code package and
online).
This program worked around the webbrowser
issues
in April 2019, using techniques described
here and
here.
Hence, PyEdit's
user guide
now opens from within the GUI on Android just as it does on PCs, though
viewer options may be limited, and Android always displays the online
version of help to include recent changes; open the guide manually if
it is subpar in the GUI.
Caution: changing phone orientation during spawned activities can
misplace or hang the GUI; see the earlier rotations note.
As noted
here,
this is similar in sprit to running open
and start
command lines on Mac OS and Windows, respectively, but Android's default-apps
model is not nearly as general, and the set of apps available for opening
some files may be limited or unusable (e.g., HTML
options may be
constrained to text
editors).
If "Click" isn't useful for your files, open them
in a file-manager app instead. Also note that "Capture" mode for
running Python code is fully
operational
on Android; "Click" is only a minor convenience for other text.
PyGadgets—a GUI utility "toy box"—is partly operational on Android. Although the program's launcher itself does not run, the programs launched, including a calculator, clock, photo viewer, and simple game, can be run directly on this platform in Pydroid 3. These programs run only as GUIs. The following augments PyGadgets' base release notes.
On Android, the directly runnable utilities of PyGadgets look like this in Pydroid 3:
You can also view these screenshots in slideshow mode starting here.
All these GUIs work in either portrait or landscape orientation; experiment to find the best rotation for each, but note that rotating the screen after a GUI is running may not work on some devices per usage notes ahead.
PyToe tends to render and work best in Pydroid 3's tkinter maximized viewing mode for automatic fill and resizing; select this mode before running the GUI with "Tkinter: maximize first window" in Pydroid 3's Settings ⇨ System dialog, and press your phone's back button twice to exit the GUI in this mode. PyCalc and PyPhoto both open persistent popup windows that can be easily hidden in maximized mode; clear maximized mode for these GUIs, and exit by clicking the GUI's or window's exit button. PyClock works in any viewing mode.
To run PyGadgets utilities on your Android device, follow these steps:
And move the first of these files to the _PyCalc/Calculator
subfolder located at the top level of your unzipped PyGadgets source-code
package, replacing this file's original version. Similarly move the other
two files to the _PyToe/TicTacToe
subfolder at the same
location, replacing their originals too.
Download by clicking "save" in the "Raw text" line of these links'
pages, and search for
"# ANDROID" to see code changes made if desired.
And copy it to all four gadget-script subfolders listed in step 6 below. Download by clicking "save" in the "Raw text" line of this link's page.
PyGadgets.py
and
PyGadgets_configs.py
,
but these are not currently required, as they apply only to the unusable launcher (see Usage
Notes ahead). To experiment with their code, fetch and move these files to the
top level of the unzipped package. If it ever becomes operational, PyGadgets.py
's
folder will also require a copy of
helpmessage.py
for appearance and font-crash avoidance.
_PyCalc/Calculator/calculator.py _PyClock/Clock/clock.py _PyPhoto/PIL/pyphoto.py _PyToe/TicTacToe/tictactoe.py
Once a file is open, press the editor's big yellow run button to run the program, which will work largely the same as it does on PCs. Naturally, only this last step must be repeated on later gadget runs.
Also keep the following in mind when using PyGadgets utilities on Android:
calculator.py
in folder
_PyClock/Clock
for PyCalc).
Shortcuts look like
this or
this,
and can be made by multiple Android file explorers including the app
here,
but be sure to set the default app or command to Pydroid 3.
Tip: uncheck "Parameters" when making shortcuts in Total Commander 3.0
(details).
On some devices, Pydroid 3 either kills the GUI silently or hangs altogether if the screen is rotated between portrait and landscape orientations while a tkinter GUI is running. Per details here, rotations are known to fail on multiple Samsung devices, but the latest of these rotate correctly if they avoid the Small screen-zoom display setting. If your rotates don't work, change your screen zoom to Medium or Large, apply system updates, or don't rotate.
In the same department as the preceding note: per here, changing phone orientation during a spawned activity (e.g., a Share or program-help browse) may cause the GUI to slide off screen or similarly hang, even on devices that handle rotations in general. Rotate twice to restore the GUI where supported.
PyGadgets.py
,
displays its GUI but its gadget buttons do not work,
because GUI programs spawned by GUI programs run but do not
display their windows in
Pydroid 3.
Run gadgets directly instead per above. Note that the launcher requires the new
helpmessage.py
to display its help text
properly.
pip install Pillow
in
Pydroid 3's Terminal window opened from its main menu, or use the app's
Pip interface.
To perform keypresses in PyPhoto, either use a physical Bluetooth keyboard;
click the GUI's Help button and press the text content of its help dialog
to force the on-screen keyboard to appear (a trick to be sure, but it works);
or install the
Hacker's Keyboard
app on your phone and enable its permanent-notification option, which
allows you to pop up its on-screen keyboard on demand by clicking the
app's entry in Android's
notifications pulldown.
Once opened, the keyboard looks
like this.
Bonus: Hacker's
Keyboard also provides arrow keys which scroll PyPhoto indexes and images;
enables newlines and menu shortcuts in PyEdit;
and supports Ctrl-c/v
copy/paste globally.
PyPhoto must be able to store thumbnail cache files when they are updated.
These files are written in the opened images folder, and in Pydroid 3 can be
saved either anywhere in internal storage (e.g., /sdcard
), or on
removable drives only in the following manually created Pydroid 3 app-specific
folder (in which x
s stand for your drive's Android ID):
/storage/xxxx-xxxx/Android/data/ru.iiec.pydroid3
Cache files can be viewed anywhere on your device, but saves are limited by Android and Pydroid 3 permission constraints. Note that uninstalling an app deletes its app-specific folders, including any user content there.
PyPhoto may update its per-folder cache files unexpectedly, if you are using a FAT32 SD card for on-phone storage, and daylight savings time or time zone differs from that used when thumbnails were saved. This is a one-time update. Content managed by Mergeall on removable drives should generally be stored using FAT32 for interoperability (see Mergeall usage notes).
helvetica
,
but its other font limitations described here are still present.
Because some font types cause tkinter GUIs to crash silently in Pydroid 3,
PyGadgets' configuration file PyGadgets_configs.py
was changed
to disable user font customizations by adding triple quotes above and below
custom settings.
At present, this file is unused, because it applies only to gadgets when
they are launched from the currently unusable launcher. Fonts in gadgets run
directly are taken from command-line arguments or else hardcoded defaults.
If the launcher ever comes online, or you wish to specify fonts for gadgets
run directly, be careful to use only supported font names.
In general, font families courier
,
times
, and helvetica
work (and monaco
is
courier
and arial
is helvetica
), but most
others crash the GUI, and italic and bold styles are ignored for courier
.
Similar font fixes were applied to helpmessage.py
; see the note ahead.
The workaround involved changing
the code to use labels instead of buttons as formerly done for Mac OS, at a very
minor cost in
cosmetics.
Labels don't give press feedback (short of adding manual and error-prone
after
timer code), but buttons in Pydroid 3, like those in PyCalc's
lower rows, don't give feedback for quicker taps either.
As an added bonus,
labels also take up slightly less space on cramped phone
displays.
For more details, and a related but rarer button-state issue, read the backstory
here.
+
and *
, typically), on either physical or on-screen
keyboards. The main display supports keyboard input of other keys—including
numbers, backspace, and enter/return to "eval"—but shifted operators must be
input by tapping or mouse-clicking the GUI's buttons instead.
Keyboard backspace and enter/return keys were enabled by patches in April 2019 that work around an issue in Pydroid 3's tkinter, but shifted operator keys remain unusable on Android due to a bug in this tkinter, described further here. This is, however, a minor limitation for a redundant and less-functional usage mode: the "cmd" popup supports all key presses, including backspace and enter/return; using an on-screen keyboard for the main display requires tapping a "cmd" input field or opening an on-demand keyboard like Hacker's Keyboard (see its PyPhoto note above); and the GUI's calculator buttons are usually easier to use than a keyboard in any event.
helvetica
,
but help-dialog patches noted here also improve look and feel.
The help dialogs of all PyGadgets' utility programs crash without the
helpmessage.py
patches noted by the install instructions earlier, because this file's original
code tries to set font type to system
which fails
(see the font-constraints note above for more details).
Other help-dialog upgrades: As of April 2019, the
help dialogs
created by the helpmessage.py
module also include a new "OK"
button for ease of use on Android, where the window-border's exit
button is frustratingly small. In addition,
these dialogs now open smaller initially and use a fixed font for
better fit
on smaller screens (and PyCalc's
history
display copies the idea).
tictactoe_lists.py
was patched to use library call time.perf_counter
wherever
time.clock
is unavailable, because Python rudely removed the
latter in 3.8 after supporting it for some 30 years. This impacts every Python program
that uses time.clock
and isn't unique to Android or Pydroid 3, but Pydroid
3 4.X's automatic bleeding-edge inclusion of Python 3.8 escalates the issue to
immediate necessity for Android tkinter programs.
For more background—and to read the full
diatribe—tap here.
PyMailGUI—a full-featured POP/SMTP email client GUI documented here—has not yet been ported to Android, because its account launcher is rendered unusable by an innate limitation in Pydroid 3's tkinter support.
In short, GUI programs spawned by other GUI programs in the Pydroid 3 app run but do not display their windows. This same limitation cripples launchers in Frigcal and PyGadgets above, but their launched programs can still be run directly with a minor loss in functionality. In PyMailGUI, though, this issue is fatal, because it is impossible to open email accounts as freestanding programs without the launcher.
Though its exact causes are unknown, this constraint may be a limitation inherent in the Pydroid 3 approach: a spawned Linux program may have no notion of running in that app's IDE, and this may be the sole source of tkinter support. A specific import-statement format, for example, is required to enable GUIs at all, and tkinter GUIs fail if run in Pydroid 3's own Terminal instead of its IDE. See this note for another look at this limitation.
On the upside, PyMailGUI's core functionality—including email loads, sends, and views,
and parallel usage of all these with threads—works well on Android after patching its
nested PyEdit code per above, and looks like the following when opening
the single book-example account by directly running file PyMailGui.py
in
folder PyMailGui-PP4E/
(view in slideshow mode
here):
Running the program's main
Launch_PyMailGUI.py
multiple-account launcher, however, does not work.
Barring a workaround for the GUI-spawn issue, PyMailGUI awaits either a major
rewrite to open accounts as in-process tkinter Toplevel
windows,
or an alternative method for opening email accounts' windows without a launcher.
Watch for progress here, but this is complex enough to be filed as very-long-term task.