Skip to content

From Tkinter to Android

A Tkinter script cannot be packaged as an Android app as it is. Tkinter draws its windows through Tk, which needs a desktop windowing system, and Android does not have one. That is why "convert my Tkinter app to an APK" has no one-click answer, whichever tool you try.

What does carry over is most of your Python. With ApkPy you keep the logic, the functions, conditions, loops, calculations and f-strings, and rewrite the window part with calls that look a lot like Tkinter's. ApkPy then translates the file into an Android app with Android's own views. On the desktop you even keep a Tk window: the Previewer that shows your app while you work is built on Tkinter.

The same converter, twice

A Celsius-to-Fahrenheit converter in Tkinter:

import tkinter as tk

root = tk.Tk()
root.title("Converter")

celsius = tk.Entry(root)
celsius.pack(padx=24, pady=8)

result = tk.Label(root, text="", font=("Arial", 20))
result.pack(pady=8)


def convert():
    text = celsius.get()
    if text == "":
        result.config(text="Type a number first")
        return
    fahrenheit = float(text) * 9 / 5 + 32
    result.config(text=f"{fahrenheit:.1f} °F")


tk.Button(root, text="Convert", command=convert).pack(pady=8)

root.mainloop()

The same app in ApkPy. The function convert() barely changes:

from apkpy_lib import Screen, button, inputs, label, run

home = Screen(id="home")
celsius = inputs("Degrees Celsius", id="celsius", type="number", screen=home)
result = label("", id="result", screen=home)


def convert():
    text = celsius.get_value()
    if text == "":
        result.set_value("Type a number first")
        return
    fahrenheit = float(text) * 9 / 5 + 32
    result.set_value(f"{fahrenheit:.1f} °F")


button("Convert", id="convert", command=convert, screen=home)

style = """
home {
    padding: 24px;
    gap: 16px;
}

result {
    font-size: 28px;
}
"""

if __name__ == "__main__":
    run(start_screen=home)

python writehere.py opens it in the Previewer, a Tk window on your desktop. apkpy run builds the APK: the field becomes an Android EditText with the numeric keyboard (type="number"), and convert() becomes a Java method.

What maps to what

In Tkinter In ApkPy
tk.Tk(), root.mainloop() Screen(id=...), run(start_screen=home)
root.title(...) name in apkpy.toml (the name under the icon), or app_bar(title) on the screen
tk.Label, label.config(text=...) label("..."), set_value(...)
tk.Button(command=...) button("...", command=...)
tk.Entry, entry.get() inputs("placeholder"), get_value()
tk.Text inputs(type="textarea")
tk.Checkbutton inputs(type="checkbox")
tk.Radiobutton segmented(options)
tk.Scale inputs(type="range")
tk.Listbox list_view(items=...)
tk.PhotoImage in a label image(src)
tk.Frame with pack() or grid() components stack in their screen; row(), column() and container() group them; gap and padding in the stylesheet
font=, bg=, fg= font-size, background-color, color in the stylesheet
StringVar, IntVar get_value() and set_value(), or a state value
messagebox.showinfo(...) toast(...) or snackbar(...)
messagebox.askyesno(...) confirm(title, message, on_result=...)
tk.Toplevel (a second window) a second Screen, opened with on_click_navigate(screen), closed with back()
root.after(1000, fn) timer.after(1, fn): seconds, not milliseconds
filedialog.asksaveasfilename(...) files.save_as(...)

A few habits change:

  • Values from fields are text. As with entry.get(), convert before you calculate: float(text) * 2, not text * 2. ApkPy stops the build when it sees arithmetic on text it cannot type, and says which line.
  • One screen at a time. A phone shows one screen; a second Tk window becomes a second Screen that opens on top, and Back returns.
  • The look is a stylesheet. Instead of options on each widget, sizes, colours and spacing go in one CSS-like block. See Themes and styling.

What has to change

Said once, as the price of an app with no interpreter inside:

  • Classes. A Tkinter app written as a class (class App(tk.Frame)) is rewritten as functions and names at the top of the file. ApkPy translates a listed vocabulary of Python, functions, control flow, lists, dicts, f-strings, try/except, math and common re patterns, and classes are not in it. Anything outside the list stops the build at its line and says what to write instead. Compatibility and limits has the list.
  • Packages from pip. requests, numpy, pandas or pillow need an interpreter on the phone, and there is none. ApkPy has its own calls for network requests, data and storage, files and the device. An app built around one of those libraries fits Kivy or BeeWare better.
  • The Canvas widget. Free drawing has no counterpart; interfaces are made from Android's components, with charts for data.

In exchange the phone gets a small APK, about 1.5 MB signed and shrunk for a small app, with Android's own scrolling, keyboard and dark mode.

Building it

On Windows, ApkPy needs no WSL and no Android Studio: Python to APK on Windows goes from pip install apkpy to the APK on your phone.

Next: the Installation page, or the end-to-end tutorial.