Gtk-- Faq
(If you have suggestions of what to add to this page, let me know)
What to watch out when compiling gtk--
You need to compile and install gtk library. For that you've
done something like this:
- configure --prefix=dir
- make
- make install
Gtk-- finds gtk from your hard disk using tool called gtk-config. That
is a shell script generated when you install gtk and knows the rest
needed to compile programs with gtk.
gtk-config is a normal executable, so your shell needs to find
it. Thus check that after installation PATH variable points to the
$prefix/bin -directory. (if you used configure without --prefix, or
used prefix /usr, its very likely that the PATH and LD_LIBRARY_PATH
are already corretly set)
Also there's another issue with linking applications against gtk. Your
linker must be able to find gtk library. Gtk installation will place
the required libraries to $prefix/lib. To fix this, you might either
- edit /etc/ld.config file and run ldconfig -v
or
- set LD_LIBRARY_PATH environment variable
Then you need to install gtk--:
- configure --prefix=dir
- make
- make install
You probably prefer to place gtk-- to same position in your hard disk where
gtk was installed. This way gtk-config will find the include
paths directly, and no additional configuration is needed to compile
your own applications.
How do I compile applications with gtk-- installed?
g++ `gtkmm-config --cflags` -o testme1 testme1.cc `gtkmm-config --libs`
How do I generate the class hierarchy reference?
How do I delete widgets
If you're familiar with how gtk handles deletion of widgets - forget
it now, it does not work the same way in gtk--. All gtk-- objects
should be handled like you'd handle normal C++ objects:
- Remember to hide() the widget before deleting it.
- If you allocate something with new-expression, you need to use delete-expression to get rid of it - otherwise you'll get a memory leak.
- you can place widgets to function local scope or class scope - and they'll work just like integers would work.
- Adding a widget to a container will not move the ownership of widgets to the container. => If you allocate something with new, you need to delete it too.
- "delete this" is a bad idea and gives you sigsegv. Use idle handler instead of delete this. (there'll be convinient function to do this in the future...)
Example of making idle handler: (this forces that you allocate the object using new)
gint deletion_function(Gtk_Widget *w) {
delete w;
return 0;
}
/* put the next lines inside your widget */
hide();
connect_to_function(Gtk_Main::idle(), &deletion_function, this);
Is there a way to override widget's draw method?
There's virtual function table in every widget in gtk and derived
widgets can override methods in their class_init by setting function
pointers to point to new implementation. Gtk-- of course maps this to
C++'s virtual functions and thus for overriding draw method, you just
implement a method with signature(you'll find this information from
gtk-- reference):
// this is inside anything derived from Gtk_Widget
virtual void draw_impl(GdkRectangle* r)
{
/* draw with low level gdk functions */
}
But if it exists, why doesnt everyone use it?
Because there's easier way to do the same thing - in gtk and
thus also in gtk--, you can add other widgets inside almost
everything, like buttons. So there's rarely need to do it in
low level. This does not mean that it isnt possible.
How do I catch selections with clist?
class myclist : public Gtk_CList {
public:
// override select_row virtual function
void select_row(gint x ,gint y,GdkEvent* event) {
// call default implementation
Gtk_CList::select_row(x,y,event);
// handle selecting a row here...
...
}
void unselect_row(gint x ,gint y,GdkEvent* event) {
// call default implementation
Gtk_CList::unselect_row(x,y,event);
// handle selecting a row here...
...
}
};
NOTE that select_row/unselect_row signal signature has been changed in gtk1.1
compared to 1.0 and the code needs changes to work on 1.0 gtk's.
How do I prevent some event from happening?
You can always override some of the *_event signal's default
implementation. This is done under gtk-- like this:
class Entry_with_numbers_only : public Gtk_Entry {
...
virtual gint key_press_event_impl(GdkEventKey* e)
{
gint retval;
if (e->keyval<GDK_0 || e->keyval>GDK_9) {
// do something, usually call virtual function
// to let derived classes trap invalid key presses
retval=0;
} else {
// do what you are doing normally.
retval=Gtk_Entry::key_press_event_impl(e);
}
return retval;
}
...
};
Note, It might be better to override changed_impl() method from Gtk_Entry
to do this. Depends of course what you want to do. Playing with low level
details is usually bad thing.
Why doesnt my expose_event handler get called?
This is because some *_events need to be enabled with
Gtk_Widget::set_events() -call. The flags needed for set_events()
can be found from gdktypes.h/GdkEventMask. For example:
...
set_events(get_events()|GDK_EXPOSURE_MASK);
...
Tero Pulkkinen (terop@modeemi.cs.tut.fi)