Hi! I'm new to the Nim community - been working my way through exercises, and through Nim in Action (the book). I've been quite enjoying the language, especially since I'm coming from a Python background.
One standard library/GUI comfort from Python is Tkinter. You can construct very beautiful cross-platform GUIs with it, if you're experienced enough. Now in Python, Tkinter is implemented as a wrapper around a complete Tcl interpreter embedded in the Python interpreter. (Calls to Tkinter are translated into Tcl commands, which go to the embedded interpreter.) So when running Tkinter, you don't really feel that you're running Tcl - it's just part of the whole Python experience.
In contrast, there doesn't appear to be a wrapper for Tkinter in Nim. I've researched/ checked out other GUI offerings (e.g. nimx, NiGui, uing, uip, nimqt, wNim (Windows), nimdow, NimQML, owlkettle, etc). But before I commit to any of that path, I really want to explore the idea of 'Tkinter in Nim', and the idea of being able to translate code from Python's Tkinter to it with ease.
So my question: how could one go about using Tkinter with Nim? Is a wrapper even possible? Some thoughts:
I don't have the programming ability yet to do something like this. But if I wanted to try, how should I set about with it? Would be an interesting project.
Welcome,
There is a wrapper for Tcl which can be used to work with Tk library (that is the name of the GUI library, Tkinter is the name of the Python wrapper ;)): https://github.com/nim-lang/tcl
You could use it as an entry point for creating a binding for Tk.
I have one wrapping for Tk, but it is very low level binding, basically it calls the Tcl commands to create GUI: https://github.com/thindil/steamsky/blob/master/nim/src/tk.nim
It can be used more as an example how to create the binding. ;)
Answer to questions:
While Tkinter interfaces are ok on Windows and maybe macOS (I don't really know), they are IMHO horrible on Linux systems. They have non-standard keyboard bindings, look like they're from the 90s, and just lack many things you expect from a modern desktop UI framework.
My advice would be to look into the Qt framework and QML, if your project can be under a GPL3 license,
https://github.com/filcuc/nimqml
or owlkettle, if GTK is more your thing:
https://github.com/can-lehmann/owlkettle
For other options see https://github.com/ringabout/awesome-nim#gui
There hasn't crystallized one go-to x-platform desktop UI library for Nim yet, but IMHO the world really doesn't need anymore Tkinter apps.
I'm always shortening imports in Python (import tkinter as tk) so one gets used to thinking of both as the same! Thanks for pointing it out.
I checked out your project, and played it a bit. The core logic of the entire game is built in Nim, but you are relying on Tk directly for the game's UI? Did I read the code correctly? And does that mean that you are running Tcl through Nim while the game is ongoing? Your programming abilities are much beyond mine at this point, and it's quite hard to grok the code.
If the Tcl wrapper currently works (I didn't even know that it existed), then bringing over Tk might be a matter of translating calls from Nim to Tcl, or migrating the Python code as Nim code. In your view would it be viable to recreate Tkinter's GUI library in full, if you've ever considered the possibility? If it is, I might attempt that, even if it fails, just to see how far it's possible and as a fun learning quest. If I succeed, who knows, it might help more with Nim's popularity and adoption amongst other Python users (especially since one of the hardest issues in Python is distribution, and we have to rely on things like Nuitka or PyInstaller compared to how almost-effortless distribution/compilation is with Nim).
The game is my pet project, which I started a couple of years ago to learn a different language, Ada. :) When I meet Nim I decided to rewrite the whole project to Nim. For fun, and to see how much work will be needed for it. That work is currently under way. And that is the reason why the code is a complete mess. I strongly recommend to not looking on it or taking it as an example. :D At least until I don't pacify the code.
About binding, depends on if you want to do high or low level of it. For low level, you can even use my file, everything is there. Just then, your code will look like a mix of Nim and Tcl. For high level of binding, you will need to create wrappers for each Tcl call, for example:
proc button(name, label: string) =
Tcl_Eval(interpreter, "button " & name & " -text \"" & label & "\")
I think the best way to find how to implement it, is to look at C documentation related to Tk library.
@SpotlightKid Tk looks outdated on Unix-like systems, because it follows standards. ;) And the current standard graphical library for Unix-like systems is still Motiff. That's why Tk application looks that way on Linux and BSD systems.
Quite the contrary, actually: there's a lot I could learn from your code!
If I do go ahead with the Tkinter for Nim project (need to carve time out in my schedule for this though), would you mind if I ask you occasionally for pointers? I don't shy from hard work, but it'd be nice not to fall down the wrong paths (which is likely, since I'm not a professional programmer by trade). I intend to open source the project as well, as I'm motivated by curiosity rather than profit in this.
With respect @SpotlightKid, I am inclined to defer.
I've seen some beautiful GUIs done with Tkinter; I'd quote from Bryan Oakley, the resident SO guy for it:
I think Tkinter is an absolutely fantastic GUI library, especially combined with the object oriented nature of Python. Many people deride it as old, ugly, and hard to learn. After having used many GUI toolkits spanning more than a couple decades I’ve come to realize that most of that is untrue, and what is untrue doesn’t really matter. I would never use tkinter to create the next photoshop or itunes, but for the vast majority of GUIs most people write, it’s more than good enough.
Tkinter can be a bit hard to work with. But that's not the same as it being unable to handle beautiful GUIs or that it's "from the 90s". Tkinter is not what it used to be, especially with ttk, and v 8.6. I've seen Tk code ported across different platforms and looking native; furthermore 'non-standard keybindings' can be rebound without issue. I find his statement quite accurate as well:
... It has as much "power" as other toolkits (depending on your definition of "power"), it just doesn't do as much hand-holding. It's the difference between building a house with pre-made walls (some other toolkits) or building it from a pile of lumber (Tk). You can pretty much do anything in Tkinter that you can do in other toolkits, you just have to sometimes work a little for it.
To be fair, I've done some work with PyQt. While it may be more "powerful" (a relative term, since power lies in the hand of the sculptor, not necessarily the material) and comes with more widgets, I dislike the licensing mechanism. I like easier licensing models, especially for open source software, which this Tkinter appears to be more aligned with.
Quite the contrary, actually: there's a lot I could learn from your code!
Glad to read that, I hope good things too. :D
About asking, feel free to ask me, I will try to help you as much as I can. It is always a good opportunity to test my own knowledge and to expand it. Especially that I have feeling like the most work with binding Tk and Nim is still before me.