On time and in-sync, gtkmm 2.4 is now here. gtkmm provides a C++ interface to GTK+, with comprehensive documentation. gtkmm 2.4 wraps additional API in GTK+ 2.4. gtkmm 2.4 installs in parallel with gtkmm 2.2, so you can have both installed at the same time. glibmm is now a separate module, for use in non-GUI software.
I wanted to get my friend setup with The Gimp andI can’t find any GTK 2.4 for Windows. Isn’t GTK+ a multiplatform toolkit?
Also when i installed it with 2.2 I had to delete various files like Libxml2 from other places in order for GIMP not to give me errors.
Try here: http://www2.arnes.si/~sopjsimo/gimp/stable.html
Installers for GTK+ and the Gimp for Windows. No compilation necessary, works great for me right out of the box.
I never understood why Gnome is not written in C++. GTKmm always come after GTK+ and it is seen as a “ugly duck” by gnome developers.
For me it is a mistake. It is more natural to program GUIs with an object-oriented language and it is a reason why Qt is more easy to program.
“I never understood why Gnome is not written in C++.”
1) Historical reasons. GNOME is based on GTK+, whose primary API was and is for C.
2) C++ does not have a standard ABI, which creates some interesting problems, most notably that it is difficult to make a dynamically-linked C++ binary that will work across different distributions using slightly different versions of g++.
Comparing just the languages, C++ arguably comes out ahead of C. When external issues get taken into account, the issues get murkier.
C++ *did* not have a standard x86 ABI. It does now. It should be noted, of course, there is no standard C-ABI eitheer — it differs from platform to platform.
There are many reasons given on to why Gnome wasn’t written in C++.
Some of them given are that c++ wasn’t a standard and not as portable at the time. That’s a pretty lame excuse. KDE’s choice of c++ didn’t hamper it’s portability.
Another reason is the language bindings. That’s a legitimate one because it is harder to do bindings for alternative languages when C++ is your base.
They had to choose a toolkit or roll their own one. Since rolling your own is a major undertaking in its self the only alternatives were gtk+ or qt. QT had licensing problems for free software back then and why bother with Gnome if you’re going to choose QT – since there was already KDE.
On top of all of that, and IMO the biggest reason is that Miguel de Icaza is not a big fan of C++ and considering that straight C was/is? still the lingua franca of Unix development it made more sense to just do it in C. Many developers, even today, are not big fans of C++.
One of the reasons that Mono was started is to address the issue of normal app development in straight C.
Becuase the advantages of C++ are pretty much overated. The main result is that it makes some things some what simpler, while making somethings more complex… or pretty much personal preference.
On top of all of that, and IMO the biggest reason is that Miguel de Icaza is not a big fan of C++
Heh. Considering what he’s working on these days, that makes a lot of sense.
I had always just figured that Gnome wasn’t written in C++ simply because designing large complex OO systems is, in fact, quite difficult to get right (though, what you eventually implement is easier to maintain and extend later on).
Yep, C++ is overrated and very easy to get wrong. And sometimes you’ve gone way too far in your implementation when you realize you got it wrong. If you do get it right, then it leads to a good extensible system.
I don’t understand why the heck i have to write this kind of code with gtkmm:
m_button.signal_clicked().connect(sigc::mem_fun(*this, &HelloWorld::on_button_clicked));
It’s just ugly. It should/could be something like:
m_button.connect_signal_clicked(this, &HelloWorld::on_button_clicked);
Please, this should be a high-level api… no need to call those sigc::mem directly in my humble opinion….
Victor.
I never understood why Gnome is not written in C++. GTKmm always come after GTK+ and it is seen as a “ugly duck” by gnome developers.
An additional reason often mentioned is that the GCC compiler produced rather slow code from C++ at the time, GNOME was started.
However, GTKmm isn’t seen as an “ugly duck” by GNOME developers. But for historical reasons, a lot of C++ developers have been attracted by KDE and QT first. Thus, they were under-represented in the beginnings of GNOME.
But there is a growing base of C++ lovers within the GNOME community — maybe slowly and quiet but continuously. At least that’s my impression.
What’s indeed needed now are some people to do a proper project lead for a few more reference projects. These may be simple ports of great QT applications, so that they fit better into a GNOME desktop, or implementations of completely new ideas.
Either way, there’s room enought to develop C++ applications within the GNOME development enviroment, and you will be respected for what you do, I’m sure.
Yeah, that is just plain ugly.
I would refine your second example to just
m_button.clicked(this, &HelloWorld::on_button_clicked);
…forget the whole signal business
IMO, C# with delegates is even more elegant. something in C# with GTK# would go something like this
button.Clicked += new EventHandler(HandleClick);
void HandleClick(object o, EventArgs e)
{
Console.WriteLine(“clicked”);
}
I like the way how it acts like a function pointer, but is type safe. Interfaces and Adapter classes in Java are not near as elegant.
I believe in C# 2.0 it’ll be even simpler
button.Clicked += HandleClick;
That’s about as simple as it can get
That looks weird to me. I used libsigc++ in MacOSX and started making a C++ framework to wrap Carbon. All I had to do was have a signal object and call its connect(), passing for parameters the class who’s method I’m connecting, then a pointer to the method. I never had to use sigc::mem_func().
Even when I was using gtkmm in Linux it was just as easy as slots/signal connecting in Qt (minus the meta-object compiler). Actually I prefered gtkmm over Qt because there was no need for a MOC build stage which really got annoying when working with Qt Designer.
use gtk1. please. think of the domokun. its got more than what you’ll ever use and its fast.
let me repeat: you dont need gtk2. use gtk1.
My thoughts exactly
However, GTK+ 2.0 does have *some* nicities. Now if only they could get the memory usage down a bit (lot)…
“Becuase the advantages of C++ are pretty much overated. The main result is that it makes some things some what simpler, while making somethings more complex… or pretty much personal preference.”
Top level components would benefit from c++, using oop for graphical objects like windows, buttons, menus and stuff like that makes a lot of sence IMHO, low level components like the gdk are better left off in plain c.
Because like someone above said, C++ is overrated, complex and hard to do right. At the time GNOME was founded, C++ had no standard ABI, had terrible compilers and wasn’t as mature as C was.
It is so obvious, isn’t it? I wish there was a decent explanation why gtkmm has these ugly apis. It could be simpler, and it’s not even hard to do that!
Makes me feel like implementing my own objects inherited from gtkmm’s. But i really wish i didn’t have to waste time doing that.
Victor.
Wasn’t egcs available when gnome started??
“I wish there was a decent explanation why gtkmm has these ugly apis.”
Well look at Win32 API -> MFC. Personally, I really enjoy working with MFC but I hear a lot of other programmers blasting MFC for being a poorly put together C++ framework that just makes calls into Win32 API.
gtkmm is kinda the same situation, it wraps gtk2 calls. sigc++ was created specifically for the gtkmm project. sigc++ is a C++ callback framework plus it provides classes for slot/signal mechanism. Coming from MFC, I too feel that slots and signals can look weird but it takes some getting use to. Once you really get the hang of it you’ll start to appreciate it, as I’ve started to appreciate slots and signals.
On a final note, you probably should have done:
using namespace sigc;
then you wouldn’t have to write sigc::mem_func(…) instead just write mem_func(…) The same goes for the other namespaces in gtkmm and related add ons.
That’s another reason why the GTK developers chose C language over C++. Namespaces are great for having simplified class names (ex: instead of CWindow or TWindow or XYZWindow your window class can just be called “Window”). But because the class names are simple you’ll run the risk of a conflict of names when using more than one namespace. Last time I was using sigc++ in MacOSX, Carbon lib had an object (keyword, datatype, whatever it was I don’t remember) called “slot” and obviously sigc++ has a class named “slot”. So I couldn’t use the sigc namespace.
So without namespaces the developers have to come up with unique class names. With namespaces there’s a risk of the whole namespace not working becuase another one has an object with the same name in it. That’s why you see really long function names in GTK’s API. They try to fit the function name, a little bit of what it does, and the function’s social security number (JK) into the function name, and you pass around pointers and handles to other objects. The long function names can make your fingers tired but it’s better than getting confused between 2 objects with similar or exact names.
In a small project it might be managable, but I fear for the really big projects that rely on using multiple open source libraries pulled together for functionality. That’s the only big issue I have with OSS development. Sometimes there’s great teamwork, but it’s still not a fun time looking at and working with someone else’s code (only when something breaks).
> The long function names can make your fingers tired
…well, unless your editor has an auto-complete function.
I hear the D programming language is pretty nice
http://www.digitalmars.com/d/
Heh. Anybody know of any desktop environments written in D?
Whoops. Nevermind. There doesn’t seem to be a Free D implementation.
I checked out Digital Mars website and read up on D flat. From what I’m seeing I don’t like it. Function overloading is a bit confusing, just read this page: http://www.digitalmars.com/d/function.html
SNIP:
class A
{
int def() { … }
final int foo() { … }
final private int bar() { … }
private int abc() { … }
}
class B : A
{
int def() { … } // ok, overrides A.def
int foo() { … } // error, A.foo is final
int bar() { … } // ok, A.bar is final private, but not virtual
int abc() { … } // ok, A.abc is not virtual, B.abc is virtual
}
void test(A a)
{
a.def(); // calls B.def
a.foo(); // calls A.foo
a.bar(); // calls A.bar
a.abc(); // calls A.abc
}
In test(), why does it call B.def() if a class A object is left of . ?
I don’t understand why the heck i have to write this kind of code with gtkmm:
m_button.signal_clicked().connect(sigc::mem_fun(*this, &HelloWorld::on_button_clicked));
It’s just ugly. It should/could be something like:
m_button.connect_signal_clicked(this, &HelloWorld::on_button_clicked);
Please, this should be a high-level api… no need to call those sigc::mem directly in my humble opinion….
… and this is why Objective-C is much, much nicer language when you deal with messages between objects and gui stuff.
Here is the same code as yours :
[m_button setAction: @selector(HelloWorld:)];
isn’t it nice ?
explanation :
@selector (method) get the selector of the method — its signature. You then send the message “setAction” to your object “m_button”, calling the method setAction of m_button, and providing the selector as an argument. When the button is clicked, it will call the method corresponding to the action’s selector (that is, the method HelloWorld).
Anyway, you generally don’t bother setting it manually, as developers generally uses GORM (on GNUstep) or InterfaceBuilder (on MacOSX) for creating their User Interface and setting links between objects.
@selector (method) get the selector of the method — its signature. You then send the message “setAction” to your object “m_button”, calling the method setAction of m_button, and providing the selector as an argument. When the button is clicked, it will call the method corresponding to the action’s selector (that is, the method HelloWorld).
Who is the owner of the HelloWorld method?
What I mean is, in C++ (more specifically, in a C++ callback framework) I would pass:
MyClass::Foo()
as the method to assign to a button click event. In your sample code, it’s not as obvious from where the HelloWorld method originated.
> With namespaces there’s a risk of the whole namespace not
> working becuase another one has an object with the same
> name in it.
Nonsense. Namespaces solve this problem – they don’t create it. Sure, if you put “using” statements everywhere, effectively putting everything in to the same namespace, then you’ll get clashes. So don’t do that.
What is harder to deal with is stupidly-named C macros in public headers. Maybe that’s what you had with MacOS X. For instance, Qt #defines “emit”, so you can’t use a C++ method called emit().
Who is the owner of the HelloWorld method?
You could set it with the message setTarget; else it could be determined at runtime :
http://developer.apple.com/documentation/Cocoa/Conceptual/ActionMes…
You can also set the target to nil and allow it to be determined at run time. When the target is nil, the NSApplication object must look for an appropriate receiver. It conducts its search in a prescribed order, by following the responder chain until it finds an object that can respond to the message:
It begins with the first responder in the key window and follows nextResponder links up the responder chain to the NSWindow’s content view.
It tries the NSWindow object and then the NSWindow’s delegate.
If the main window is different from the key window, it then starts over with the first responder in the main window and works its way up the main window’s responder chain to the NSWindow object and its delegate.
Next, the NSApplication object tries to respond itself. If it can’t respond, it tries its own delegate. NSApp and its delegate are the receivers of last resort.