Hacker News new | past | comments | ask | show | jobs | submit login
Toga: A Python native, OS native GUI toolkit (pybee.org)
149 points by samf on Aug 9, 2014 | hide | past | favorite | 69 comments

This project appears to be quite early stage (many missing APIs, no stable Windows support, poor documentation, etc) but very promising. If it had integration with a GUI designer and was feature complete, I'd start using it on projects.

I've explored the options for Python GUI toolkits quite extensively. They're a real challenge to get running conveniently (by conveniently, I mean a simple PIP install away with no external C/C++ library dependencies) on OS X with native looks, and that is a nice advantage of this one IMHO.

Thanks for the kind words.

Yes, the project is very early stage - I've been tinkering for 6 months in my spare time (and it's not like I had a whole lot of that to start with). Getting cross platform on 4 platforms has, as you might expect, taken a bit of effort.

I started down this path because the existing options didn't satisfy me. When my initial couple of weeks of tinkering proved that it was possible to get widgets without binary dependencies, that gave me the momentum to get to the point that I've publicly announced. There's plenty left to do, but I've got high hopes.

"No external C/C++ library dependencies" is simply impossible. Given that the host OS is not implemented in Python, some kind of bridge to its native libraries is necessary for a GUI library. Such libraries can be either compiled during the pip installation, or required as an external dependency installed using the package manager of the OS, Either way it's never going to be hassle free due to all the different OSes and package managers.

>"No external C/C++ library dependencies" is simply impossible. Given that the host OS is not implemented in Python, some kind of bridge to its native libraries is necessary for a GUI library.

Not true. Python provides facilities for dealing with dynamic link libraries from native Python code. These can be used to interface with the OS directly, without necessitating writing a C/C++ wrapper.

OK then it's a terminological confusion, because I would say that gives you a dependency on said "dynamic link libraries". Whether you need to write a C/C++ wrapper only determines if the dependency is in runtime or also compile time.

You have zero dependencies aside from the OS.

On Windows or Mac this may be true, but with Linux the GTK or Qt libraries are not part of the OS, but are used in desktop environments which may or may not be installed, and there are different version etc. so things are more messy and it's definitely a dependency which has to be fulfilled (at least at runtime).

From the conversations I had with the creator of Toga at PyCon AU 2014 and before its release, this is understood, and the current dev was towards 'it works on ubuntu', and more will come. The system is extensible so down the track the issue will be more "which do i pick" not "i can't find a way to render" ... since nothing stops this using some kind of text mode terminal UI rendering library, or a raw frame buffer one, its very awesome.

Another toolkit that uses Python, but with Qt (and previously also wxWidgets) is enaml - it has a cassowary solver, a Visual Studio docking system, and very interesting approach to connecting that to visual elements.



Having developed several advanced apps in enaml over last 2 years, i commend enaml. It encourages MVC and provides clean observer-style bindings (Atom).

The framework is used internally by at least one fortune 50 corp for a large app suite.

Project author here; Thanks for the heads up - I haven't come across Enaml before. I'll take a look.

The Mac screenshot I see on the home page looks about as non-native as the average Qt app.

It's using native Cocoa controls, so I'm not sure why you don't think it looks native.

Because the layout that's presented is not native. Actual mac apps don't have tabs and toolbars pushed together like that, and the margins are different.

wxWidgets can use the platform native controls, but the apps rarely look native because the layouts and behaviors are non-native. Mac/GNOME/Windows all have different ideal metrics for spacings, control placement and labeling (OK/Cancel vs Cancel/"Do Thing") -- being native means getting all of those details correct.

Fair point. The spacing and margins are totally wrong, for sure. But that's just spacing & margins, and I assume that's easily adjusted (and they should do that, so their demo doesn't look ugly). But nonetheless, the widgets are native Cocoa widgets, so they not only look native, they feel and behave native, something you can't say about Qt (at least not to the same degree — although I develop with Qt, love Qt, and have zero issues with the way Qt applications look and feel on Mac).

The spacing and margins are all manually specified (or, in the case of the example, aren't specified at all, so they default to 0). If you cared to do so, this spacing could be manually adjusted.

Under the hood, it's 100% native widgets (i.e., on OSX, the code is actually instantiating an NSButton, adding it to an NSView, set as content on an NSWindow; on Ubuntu, it uses Gtk.Button etc), so the look and feel of the widgets themselves are exactly as the platform dictates.

"100% native widgets" is the easy part and wxWidgets/wxPython is doing just that (and always have been). Providing higher-level API is harder and again, wx does that too.

But the devil is in the detail. The reason why many wx apps don't look very well on OS X is because getting all the tiny details like spacing, behavior, layout etc. right for all supported platforms, with (mostly) same code base is hard - and it has nothing to do with the look of individual widgets.

But well, you'll learn that during the journey ;)

That's a matter of design, not an observation based on technical merits.

Maybe I'm missing something, but isn't the main 'hook' for this library that it looks native? Looks like it uses GTK+, so from a technical standpoint it would be as "native" as Qt.

Project author here; let me confirm that Toga only uses GTK+ under Ubuntu/Linux. On OS/X, it uses Cocoa. I've just clarified the text in that section of the website. Thanks for the heads up.

Thank you for the clarification.

It does not use GTK+ on a Mac, it uses Cocoa, so it is fully native. Read the docs.

Hmm, they should update their front page than. It is pretty clear in stating "Toga uses the system native python GTK+3 bindings for display purposes."

That sentence you quote is immediately underneath the heading "Problems using virtualenv under Ubuntu" — it applies only to Ubuntu, where they do use GTK. But on Mac, they use Cocoa, as stated in several places in the docs.

There are probably quite a few Qt apps you haven't noticed because they look perfectly native. What you mean is "a badly designed Qt app".

i highly, highly doubt that, but i'd love to be proven wrong. what's the best example of an OS X-native-looking Qt app you know of?

Spotify isn't bad.

Spotify's UI is many things, but it doesn't even begin to appear system native.

Nor is I even Qt! It's a web view.

The application is Qt.

For a project like this where there are many other potential options (wxPython etc.) the first question I'm thinking is 'why do I care about this new one'. I.e. What does this do better/differently/more conveniently. I assume the answer here us the native Python aspect and not needing big compiled libraries. Might be worth selling it a bit more on your homepage and making that advantage clearer?

It may be that everyone else picked up on Python native quicker than I did, I'm reading this in bed during a lie in so am a bit sleepy!

Thanks for the feedback! I cover some of the "why" in the docs, but I agree the homepage could do a better job of making the case for a new UI toolkit.

The short version:

* System native widgets, not themes

* Installable via "pip install" - no third party or binary dependencies

* Not just naïve wrappers around widgets - capture the underlying use case and provide an API wrapper.

* Genuinely Python native. This means exploiting language specific features (like generators and context managers)

"Python native" is an oxymoron, given the language's interpreted nature. "Python-idiomatic" would probably be a more correct choice of words. But that's just me.

I think that is typically called "pythonic".

wxPython has system native widgets in every platform. wxWidgets has system native widgets in every platform, and it is the only one I know that provides that.

May be you are thinking about some other toolkit that's not wxWidgets.

This looks promising. It would be better if the documentation was a bit more exhaustive[0]


I'll completely agree. This is a project that has been built in the last 6 months of my spare time from all my other projects, and most of that time has been spent getting things to a point where they work. The APIs aren't yet stable enough to warrant me spending a bunch of time formalising them, but I absolutely want to document them as soon as the ground stops moving :-)

I was really confused when I read "the constrain() call takes expressions that define the relationships you want to impose" (emphasis mine) and saw this code:

  container.constrain(button.TOP == container.TOP + 50)
Python doesn't let you pass expressions! Why isn't that just getting evaluated to true or false? Is this not vanilla Python? Is there a pre-processor?

I dove into the code and found the answer here[1]. button.TOP and container.TOP are both Toga Attributes, which have their equality operators redefined.

Very interesting and clever use of operator overloading.

[1] https://github.com/pybee/toga/blob/master/toga/constraint.py

I am very conflicted about that trick. On the one hand it is a neat bit of syntax to express what you want, but it goes completely against your expectations of how Python syntax is parsed. 'Clever use of operator overloading' historically has always meant 'confusing use of operator overloading' - something the C++ community took some time to learn.

Python is very good at behaving as you expect it to, despite the fact that you can implement pretty much any magic. This is down to library design more than it is language design.

At least it's less magic than puLP:

  prob += x*2 + y, "foo"
This sets the objective function of prob to (2x+y), and assigns it a name of "foo".

  prob += x*2 + y > 3, "abcd"
That puts a constraint that 2x + y > 3, called "abcd".

On both of these the string is optional.

I'm also conflicted. On one hand, it's about the most compact syntax you can get for something like this - when similar libraries in languages without operator overloading resort to passing strings into functions... On the other hand, it can be utterly incomprehensible if you haven't gone through the documentation.

FWIW, I've seen the double-equals syntax in GSS as well. It's a common idiom in the constraint programming community; it's supposed to symbolize that the two sides change in sync -- container.TOP can change button.TOP or vice-versa.

I see your argument about overloaded operators being dangerous for newcomers, but the syntax isn't completely fabricated.

Thanks for the compliment. As others have pointed out, this isn't an idea of my own creation - others (e.g., SQLAlchemy) have taken similar approaches in other APIs. I'm just exploiting a pattern that I've seen used to good effect elsewhere.

some ORMs do operator overloading too, i.e. SQLAlchemy http://docs.sqlalchemy.org/en/rel_0_9/core/sqlelement.html

Google use operator overloading in their appengine stuff.

  left_container = toga.OptionContainer()
  AttributeError: 'module' object has no attribute 'OptionContainer'
Frustrating when things that are supposed to work out of the box, don't. Initial search yields no help.

Sounds like you're on Windows. Unfortunately, Windows support is pretty primitive at this point (reflecting my own priorities - OSX, Unix and mobile support is a more pressing concern). I'll update the homepage and docs to better reflect the current project status.

Longer term, I definitely want to support Windows to the same level as other platforms; any assistance on this front would be gratefully accepted.

What version of toga are you running? I'm on Ubuntu with Python 2.7.6, toga v 0.1.0 and cassowary 0.5 and your oneliner works fine.

Edit: In fact, OptionContainer is just 15 days old, so I think you've got an old version: https://github.com/pybee/toga/commit/262efbfc00fae0a96e09666...

either than or you're on windows, where unfortunately next to nothing is implemented

Very interesting. They have other tools which are rather useful looking as well: http://pybee.org/ (debugger, test runner, coverage visualiser etc)

Thanks for the promotion :-)

Of those tools, the test runner (cricket) is the most mature; the debugger isn't much more than a proof of concept. Those tools are also based in Tkinter at the moment; I started Toga because I've started to hit the limits of Tkinter.

The intention is to port the other PyBee tools to Toga as soon as they get mature enough.

Does anyone know of any similar GUI toolkits, for languages other than Python? That is, cross-platform GUI toolkits that use true OS-native widgets, and ideally, also abstract away platform-specific details such as the placement of the Quit/Exit menu items and the order of OK/Cancel buttons. Toga is actually the first library with those features that I’ve heard of.

I think you're looking for phoenix: http://byuu.org/programming/phoenix/

An example application using it, with the GTK backend: https://i.imgur.com/pW2Jl9q.png

and the Qt backend: https://i.imgur.com/z6cC3rM.png

The author (byuu) posts here, he might be able to answer questions.

The most famous such library is wxWidgets; it supports "Python, Perl, Ruby, and many other languages":


wxWidgets has been doing that for more than a decade.

Well, may be some very platform specific guidelines have to be added by hand, but the actual widgets used are native.

The use of constraints to let the user specify where to put things but still allow enough flexibility to do OS-dependant things is interesting (and possibly novel?):


Cassowary ( http://constraints.cs.washington.edu/cassowary/ ) is used by Apple for this.

FYI, Toga uses Cassowary as well - natively through Apple's implementation on OSX and iOS, and via a Python implementation of the algorithm (http://pybee.org/cassowary/) for GTK and Windows.

Not really novel[1], just not used enough

[1]: https://en.wikipedia.org/wiki/Sketchpad

It's similar to the sizer concept in wxWidgets:


I think that's basically the same as Cocoa's Autolayout, which is also constraint-based. It's a good model, though.

Neither of those are constraint based.

This toolkit seems extremely simple and user-friendly, might have to give it a try

loutish/lazy Debian/"testing" system here:

   ~> apt-cache search toga
   toga2 - computer chess engine, calculates chess moves
(hm... wake me when it hits testing)

Given that the project was announced publicly 1 week ago, I wouldn't expect to see it in Debian (testing or otherwise) for a little while.

As a Python library, the package would be called python-toga.

Android compatible?

Not yet. Android support is on the todo list once I've processed all the feedback that has come as a result of the initial release.

They say it would be nice, but not yet, no.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact