TimesTables.jl, a fun (😰) app using QML.jl and PackageCompiler.jl

Hi all,

Following the excellent demo of PackageCompiler at JuliaCon, I decided to give it a try for a GUI application using QML. You can find the result at https://github.com/barche/TimesTables.jl

The application itself is quite simple, intended to force my kids to do elementary school math exercises. What is more interesting is how it works, some highlights:

  • It is based on the β€œnew” QML.jl workflow, i.e. everything is linked together using Observables. That should make it easy to replace the GUI with something web-based, for example
  • The QML code (together with Dutch localization for the prompts) is available in a separate artifact, for PackageCompiler compatibility
  • CI (github workflow) is set up so that on release, PackageCompiler is invoked automatically to build an executable for Mac, Linux and Windows

Some caveats:

  • Binaries are not signed, leading to dire warnings on Windows and Mac. It is almost unusable because of this on Mac, since you have to approve each dylib separately (a command line workaround exists, if you feel like messing with your security settings in a bad way).
  • Just compiling the application with PackageCompiler did not result in a lag-free experience, it was necessary to record a β€œtypical” session to generate precompilation statements. You can see the difference between v0.1 and v0.1.1.

All in all, I think the result is quite promising, showing that an easy way to distribute Julia-based interactive applications is just around the corner. It still needs some polishing regarding the signing and maybe auto-generate an installer.


Did you create the precompile_statements.jl file manually or automatically?
Is there a way to create it automatically in a manner which means no compilation actually happens at run time?

I created it using the --trace-compile=precompile_statements.jl option when running Julia, and then used the application for a bit. If you want absolutely no compilation at run time, you have to make sure to trigger all possible methods that can get called.