6
votes

I am attempting to write a cross-platform GUI application that would be deployed to Windows, Mac OS X, and Linux. My requirements are:

  1. Single code base for all three deployment platforms, without a large amount of conditional logic for handling differences between platforms.
  2. Looks as close to "native" as possible on all three platforms.
  3. Easily distributable to all three platforms, in the sense that it could be easily installed by end users and does not suffer from extreme bloat (as discussed in this ArsTechnica article.)

Based on these requirements, I've narrowed down the selection of toolkits to Qt and wxWidgets, since none of the other toolkits that I know about (including Java's Swing and SWT, Flex, AIR, etc.) satisfy the "native-looking" requirement. Among these two final contenders, Qt appears to offer better support for applications that look and feel native on all three of my deployment platforms, but I'm willing to consider opinions to the contrary.

I would prefer not to use C++ as the implementation language, but I'm not sure if there are any practical alternatives. My biggest concern about using an implementation language other than C++ is the deployment problem. As discussed in the Ars Technica article, PyQt does not meet the "easy deployment' requirement in any practical sense, and I suspect that most other language bindings for Qt would suffer from the same deployment problems (at least on Mac OS X). Java (or Scala) with QtJambi? QtRuby? wxPython?

Does anyone know of any combination of language and toolkit that satisfies all three of the above requirements?

8

8 Answers

8
votes
  1. It depends on your needs. But in general Qt Framework (with any language) and Java SE (with any language) is much more better because it has not only cross-OS GUI libraries but also cross-OS networking, threads, ... wxWidgets is GUI only.
  2. Both Qt and wxWidgets are nice. In my experience Qt is better. Swing is... Well, not so nice.
  3. Both Qt and wxWidgets applications written in C++ and Java Swing applications are not so hard to deploy on Windows, Mac and Linux. The rule is that the deployment is simple when you are programming in "native" language. By "native" language I mean the language a framework itself is written in.

PyQt does not meet the "easy deployment' requirement in any practical sense...

Python (and any other language with the default implementation as interpreter) apps is hard to deploy in the usual sense (I mean in form of standalone executables).

So probably you have 2 choices:

  1. C++/Qt or C++/wxWidgets.
  2. Java/Swing if native look & feel is not very strict requirement.
4
votes

wxWidgets is quite good, and does contain some non-GUI code (contrary to what kemiisto said): threads, sockets etc.

The nice thing about wxWidgets is that wxPython actually should be pretty easy to deploy on OS X. There are some other language bindings for wx, but wxPython is probably one of the oldest ones.

3
votes

At my day job I've been developing cross-platform (Windows / MacOS / Linux) using perl and wxWidgets. The combination is pleasant to use for development (I'm a perl hacker) and I rarely have to include specialized code per platform. There are some perl modules that help out with this (e.g. File::HomeDir that knows about the canonical locations for document directories etc on the various platforms).

For release, I don't rely at all on the system perl installation and instead build a perl installation that is included in the release. This way I can completely control the runtime environment of the app. I ship a windows installer package via innosetup, an mac os .dmg file with a .app included that the user can just drag to their /Applications, and for linux I build debian and redhat packages.

1
votes

Have you looked at Xojo? It definitely meets all three of your requirements and it is much simpler to learn and use than C++.

1
votes

About a decade ago or so, it was fashionable to model a GUI in a cross-platform flavor of XML (like XUL) and then have a platform-specific rendering engine process that XML-file to display a layout. It is no longer fashionable to do this, however. Today, in 2017, the trend is to build your apps on platforms that allow you to write everything in HTML, CSS and/or JavaScript, no matter what environment your code is supposed to run in.

The "first generation" of this type of tools produced what are basically "hybrid" applications, where web applications run on top of browser-like & platform-specific WebViews. This technique is rather inefficient, however. Your apps don't feel very "native", are rather bloated and they tend to be rather lacking in performance. However, it's relatively easy to have a consistent look-and-feel in different environments. Phonegap / Cordova is the most popular platform for mobile environments and NW.js for desktop environments.

The "second generation" is different : they compile everything to fully "native", platform-specific binaries. Instead of relying on WebViews, "native" widgets are used when possible. This gives your app a more "native" look-and-feel, typically has less bloat and is much better for performance. However, you'll have more differences between the different platforms. Examples are NativeScript, React Native & Tabris.js (all for mobile environments).

Unfortunately, there are no "second generation" tools for desktop just yet. So, right now, if you want to build a cross-platform desktop app, you're stuck with "first generation" tools. NW.js has a longer track record than Electron and has support for various features not present in Electron, but it also comes with its drawbacks. AppJS is still older, but it's not as mature - and not nearly as popular - as the other two.

Anyway, their reliance on WebViews means that your application will feel more like a web app than a desktop app. And bloat and performance drawbacks are inevitable with this kind of solution. This means you'll never get the same performance as code you write directly in Java or C++ nor the same performance you'd get in "second generation" platforms, and it will never feel equally "native". However, it can still be the best solution eg. when a consistent look-and-feel across different platforms is more important or when you have a background as a web developer.

If performance, lack of bloat and your application getting that "native" feel are important criteria, you might want to wait a little longer until the first "second generation" platforms appear for desktop. It's really but a matter of time before platforms for desktop apps follow the same evolutionary path as platforms for mobile apps, although it might actually come in the form of "desktop extensions" to existing mobile platforms.

The way it's currently looking, it looks like you'll soon be able to write "native" apps for desktop & mobile alike with the exact same codebase. With React Native already having plugins that add support for Windows 10 and support for MacOS, I would personally go with React Native and give their dev team some time until they support all desktop environments I need to support and those extensions for desktop are mature enough for production environments.

If you can't wait that long, you don't want to bet on what's to come in the future or if these criteria aren't that important for whatever application you want to build today, you might want to try some of the "first generation" platforms currently available and see which is most suitable for you. Just be aware of the drawbacks!

As always, choose wisely...


Popular platforms

First generation platforms for mobile environments (iOS & Android)

  • Meteor (built on top of Cordova)
  • Ionic (built on top of Cordova)

Second generation platforms for mobile environments (iOS & Android)

Platforms for desktop environments (Windows, Linux or MacOS)

Platforms for smart home and IoT devices

0
votes

.Net (C# or VB.Net) is what I would use for this (in fact, it is what I use for my own application). Thanks to the Mono project, .Net applications can run on Mac and Linux as well as Windows without any modifications to the code (unless you're calling Windows API functions). You don't even have to compile different versions of your program: the same EXE will run on all platforms.

0
votes

Java/SWT is one of the good choices. You can find a lot of information about it here.

0
votes

Java does support "native-looking" applications by using the SystemLookAndFeel. The quickest way to try is to invoke the following at application start up.

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

Take a look at this for more information on the available Look and Feels in Java.

http://java.sun.com/docs/books/tutorial/uiswing/lookandfeel/plaf.html