Juce vs Qt


#1

Hi there !

It’s time I start writing a GUI for rubyk (open source osc/network based patcher). I decided long ago that I wanted to use Juce for the following reasons (prioritized):

  • cross-platform
  • C++
  • clean, consistent UI
  • introductory (bedside) documentation
  • no scripting

All is nice except… I cannot find a book on juce and it’s a huge library to swallow in one shot. So I looked at alternatives and thought of Qt. Pros for Qt:

  • cross-platform
  • C++
  • books
  • IDE
  • scripting
  • not so nice UI
  • not so nice community :wink:

The scripting is needed so that devices can upload a custom interface (sliders, buttons arrangement). But I could write some lua bindings and that’s not such a big deal.

Here comes the questions:

  1. What was your experience when starting with juce (learning curve, etc) ?
  2. What is your advice ?

Gaspard


#2

If you know C++ I don’t think there should be any problem working with juce and If you have any problem you can get back to this forum.

You can try this link for tutorial.

http://code.google.com/p/juced/wiki/JuceTutorial

I normally write platform specific code for running scripts.


#3

I did not know about the wiki and tutorial. Great work ! That looks exactly like what I needed to get me started.


#4

If you choice is only based on the points you’ve listed, then go for Qt.
Qt UI is fully skinnable, and have a considerable community.
Qt is usable in commercial product for free while Juce isn’t (at least, not if you don’t GPL it). Qt has a standard native browser (webkit based) while Juce use the system’s browser component.

However, I’ve worked with both (and such awful stuff called MFC / wxWidgets), and I can tell you juce is easier to bootstrap and follow.

With Qt, you have signal/slot mechanism that requires an extra build step (going through a preprocessor tool), so while it’s very great for runtime dynamism, it is a pain to follow.

In Juce, the signal / slot idea is using a much more obvious Broadcaster / Listener pattern based on callback (understand inheritance), so you don’t have to read the actual source code to understand the code logic.

What I trying to convince you, is that if you work on a project periodically, then Juce is easier to get back to the whole understanding.

Even then, the Juce code logic seems more familiar to me.

What is also interesting, is that Juce is federating a lot of sideprojects, like ejuce (jucetice) (a juce on steroids), angelscript (scripting & ide for juce), etc. You’ll find all of this in these forums.

To conclude, Juce is attracting very talented people, with a high level in aesthetics, and as such the (side)code is clear.

You’ll bootstrap from a demo, and you’ll see by yourself what you prefer


#5

Well there is always the general “feeling” of the project/code/community and Juce stands out to me.

And even if Qt is skinnable, when you look at the applications using it and running on Mac OS, they really don’t have the same level of polish found in applications made with juce (I discovered juce by opening the new max/msp in gdb).

I printed the 34/2 = 17 pages of the tutorial so I have by bedside book now.

Gaspard


#6

Talking of “skinnablility”, I’ve got some interesting plans in that direction that should go beyond anything I’ve seen in Qt or other toolkits. I should do a post explaining them when I get a moment…


#7

This tutorial is one of the simplest way to learn juce. But there are lots of things it doesn’t deal with. It would be well worth if you give juce demo a try.

I have been active in this forum for about a year now and the best part of this forum is that help is always available.

I haven’t used QT, so can’t talk much about it. :frowning:


#8

I looked hard at Qt too. Here’s what put me off:

  • Some semi-arcane solutions to the classic MVC problem - signals and slots are elegant but make nasty looking code and take some deciphering. The juce solution is probably less ‘correct’ as a design, but works the way it seems to me C++ should work.

  • Qt apps don’t look like native apps, even though they’re meant too (as a Mac users, that’s a huge deal). Juce apps look like juce apps, and are easy to put your own look and feel on.

  • Qt required me to write code, design UI, and pass it all through some weird translator. The extra level didn’t feel right to me. Juce code is just standard.

  • At the time, for commercial use, it was thousands of dollars per year.

But in the end, it came down to juce, not Qt - it makes sense to me, is readable, well designed, you feel very connected to the creator, it looks great and runs fast.

Bruce


#9

Yes please! Hopefully the post will include the phrase ‘OpenGL’ lots?

Bruce


#10

No, but… now that I’ve refactored the way graphics contexts work, it’d no longer be at all difficult to replace the software renderer with a GL-based one. If you have a look at the CoreGraphicsContext class and imagine a similar thing called OpenGLContext, that’d be all that’s required.


#11

Will do, thanks.


#12

[quote=“Bruce Wheaton”]I looked hard at Qt too. Here’s what put me off:

  • Some semi-arcane solutions to the classic MVC problem - signals and slots are elegant but make nasty looking code and take some deciphering. The juce solution is probably less ‘correct’ as a design, but works the way it seems to me C++ should work.

  • Qt apps don’t look like native apps, even though they’re meant too (as a Mac users, that’s a huge deal). Juce apps look like juce apps, and are easy to put your own look and feel on.

  • Qt required me to write code, design UI, and pass it all through some weird translator. The extra level didn’t feel right to me. Juce code is just standard.

  • At the time, for commercial use, it was thousands of dollars per year.

But in the end, it came down to juce, not Qt - it makes sense to me, is readable, well designed, you feel very connected to the creator, it looks great and runs fast.

Bruce[/quote]

This was basically my thought process also!

I’ve also come to appreciate the speed with which I can create random UI components with JUCE. The main components are generally flexible enough that they can be extended/abused for a range of tasks without resorting to extreme hackiness, and the component foundation is very easy to build upon.


#13

I didn’t get very far with Qt, but the thing that put me off even trying was that it seems to be very difficult to use it for a VST plugin. Then I discovered Juce and lived happily ever after…


#14

For me Qt stay hard to use. I agree that Qt is more complete API but in some point Juce is better. Juce, for example, is more oriented Audio application, and this part of the API is Perfect. The plugin abstraction allow that produce virtual effect or instrument with minimum of effort. Juce is the perfect way at this level.

I hate to have difficult pre-developpement procedure, like the Qt compilation and difficulty to use it with VS2008 express (the integration plugin is only for the commercial version). With juce, not more that 15 minutes to procudes the .lib, one include file to use it (juce.h).

The skinnability of Qt is not better that the Juce one. The CSS (Cascade Style Sheet) and the Look’n’Feel is approximatly the same (cascade/tree method), Qt respect the CSS norm but you can produce very nice skins with Juce too. Maybe the only problem is that Juce don’t provide OS-spectific look’n’feel by default.

In all case, for modest developper like me, that are more comfortable with a high-level programmation (object programming) than the low-level consideration (configuration, qmake, compilation problem … command-line expert …), Juce is for you !


#15

Just resurrecting this thread as I am starting on a new desktop application to interface with some data acquisition hardware and ran across a Juce mention in another forum. How applicable is the above 3 years later?

This is a non-audio, data analysis application so I will have to display a number of graphs (2D and 3D) with some real-time support.

Does Juce provide ( either intrinsically or via 3rd party add-ons ):

  1. a docking manager (VS 2010 style or similar)
  2. sqlite support
  3. chart/graph package
  4. skinning

Thanks!

John


#16

[quote=“embedded_guy”]Does Juce provide ( either intrinsically or via 3rd party add-ons ):

2. sqlite support[/quote]

JUCE doesn’t provide SQLite support (nor should it) but you can use my soci-based wrapper which makes using SQLite easy:

It operates very similarly to soci so you can use the soci documentation (http://soci.sourceforge.net/doc/).

I have added some type conversion so that you can work with JUCE objects like String and Time.


#17

Thanks for the sqlite stuff TheVinn! I wasn’t aware of SOCI.


#18
  1. Yes, thanks for maxprod, IIRC, search for “Adobe” in the plugin section of the forum
  2. Yes, look at the plugin section in the forum. In all case using sqlite3 only requires 10mn learning, it’s so easy that any wrapper are just for lazy people.
  3. Not that I’m aware of. Juce has a very good OpenGL component now, if you need 3D. For 2D, I guess you’ll have to find a library somewhere, or hack your own.
  4. Yes. Currently, it’s quite good for this, but could be better (probably in the next iterations of code)

#19

No, that’s not true at all. Is a wrapper for the Lua API for lazy people as well? Is std::vector for people who are too lazy to use malloc and free? No in all cases. The soci / VFLib sqlite database wrapper takes advantage of C++ templates to allow for concise notation for serializing database information, especially into user defined types like structs (or JUCE types such as juce::Time or juce::String). The alternative is to write functions that are many lines long for binding variables, manually keeping track of parameter and bind indices, and implementing your own wrappers for non standard types.

SQLite users most certainly benefit from a well written wrapper. Compare:

With wrapper:

sql << "select first_name, last_name, date_of_birth " "from persons where id = " << id, into(p);

Without wrapper:

sqlite3_stmt* st;
char const* tail;
sqlite3_prepare (db, "select first_name, last_name, date_of_birth "
                 " from persons where id = %%1", -1, &st, &tail);
sqlite3_bind_int(st, 1, id);
sqlite3_step (db);
p.first_name = sqlite3_column_text (st, 1);
p.last_name = sqlite3_column_text (st, 2);
p.date_of_birth = int64_to_time (sqlite3_column_int64 (st, 3));
sqlite3_finalize (st);

If you add or reorder the binds and/or parameter, then you need to manually renumber all of the column indexes (SQLite does this for you). If you change any of the data types you need to change the function used to bind or extract columns. Any custom data structures (like trying to bind a Time field, or a juce::String) you’d need to write your own functions for.

I completely disagree that the wrapper is extraneous. It’s almost essential. In fact, in the SQLite literature they make it clear that the typical use-case for SQLite is to roll your own wrapper for it, and even provide a page listing all of the available wrappers:

http://www.sqlite.org/cvstrac/wiki?p=SqliteWrappers


#20

[quote=“TheVinn”]
I completely disagree that the wrapper is extraneous. It’s almost essential. In fact, in the SQLite literature they make it clear that the typical use-case for SQLite is to roll your own wrapper for it, and even provide a page listing all of the available wrappers:

http://www.sqlite.org/cvstrac/wiki?p=SqliteWrappers[/quote]

Agree with all the above, but would go further and say that a proper abstracted interface (CoreData, or ADO for example) is just good design as i: a) reduces the likelihood of bugs and maintenance issues, and b) makes it trivial to switch between storage sub-systems as needs change.