Using gtk on Raspberry Pi - gtk

I am new to Raspberry Pi (I have a 4B) and to stackoverflow. I am trying to use gtk. I have no trouble compiling and running multiple simple examples from the web. However, while every example creates a window, no other gtk commands (e.g., text, buttons, border width) work. I just get a blank window on every example. An example of such a program, taken from C_GUI_Programming.pdf at raspberrypi.org is:
#include <gtk/gtk.h>
void main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
GtkWidget *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
GtkWidget *btn = gtk_button_new_with_label ("Close window");
gtk_container_add (GTK_CONTAINER (win), btn);
gtk_widget_show_all (win);
gtk_main ();
}
How can I get gtk to do more than create a blank window?

Related

wxTreeCtrl always shows selected item as focused, on GTK2 and GTK3

I'm running Kubuntu 18.04 with the Breeze theme selected for both GTK2 and GTK3. Running the 'treectrl' program from the 'examples' directory on the source distribution creates the window shown below:
The window has a wxTreeCtrl with some items and a text control showing a log. If I click on an item on the tree it's background turns blue, indicating both selection and focus on the wxTreeCtrl. If I them click on the text control the caret appears, indicating that the text control has taken the focus but the selected item on the tree remains with a blue background.
Other (pretty much all other) controls change the background colour of the selection to a different colour to indicate selection without focus.
Why doesn't wxTreeCtrl follow this and can it be reverted back to the normal behaviour?
------ Edit -------
I've build a native GTK3 app using the code :
#include <gtk/gtk.h>
enum {
COLUMN = 0,
NUM_COLS
};
GtkTreeModel *create_and_fill_model(void) {
GtkTreeStore *treestore;
GtkTreeIter toplevel, child;
treestore = gtk_tree_store_new(NUM_COLS,
G_TYPE_STRING);
gtk_tree_store_append(treestore, &toplevel, NULL);
gtk_tree_store_set(treestore, &toplevel,
COLUMN, "Scripting languages",
-1);
gtk_tree_store_append(treestore, &child, &toplevel);
gtk_tree_store_set(treestore, &child,
COLUMN, "Python",
-1);
gtk_tree_store_append(treestore, &child, &toplevel);
gtk_tree_store_set(treestore, &child,
COLUMN, "Perl",
-1);
gtk_tree_store_append(treestore, &child, &toplevel);
gtk_tree_store_set(treestore, &child,
COLUMN, "PHP",
-1);
return GTK_TREE_MODEL(treestore);
}
GtkWidget *create_view_and_model(void) {
GtkTreeViewColumn *col;
GtkCellRenderer *renderer;
GtkWidget *view;
GtkTreeModel *model;
view = gtk_tree_view_new();
col = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(col, "Programming languages");
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(col, renderer, TRUE);
gtk_tree_view_column_add_attribute(col, renderer,
"text", COLUMN);
model = create_and_fill_model();
gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
g_object_unref(model);
return view;
}
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *view;
GtkTreeSelection *selection;
GtkWidget *vbox;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_title(GTK_WINDOW(window), "Tree view");
gtk_widget_set_size_request(window, 350, 300);
vbox = gtk_vbox_new(FALSE, 2);
gtk_container_add(GTK_CONTAINER(window), vbox);
view = create_view_and_model();
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 1);
GtkWidget *entry = gtk_entry_new();
gtk_box_pack_start(GTK_BOX(vbox), entry, TRUE, TRUE, 1);
g_signal_connect (G_OBJECT (window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
that shows a window with a Tree View control on top and a Entry control on bottom. The behaviour is the same, as seen in the picture:

Alternative to deprecated gtk_alignment_new

I used the GtkAlignment widget to control the alignment and size of its child widget. But gtk_alignment_new has been deprecated since version 3.14 and should not be used in newly-written code. What functions should I use as alternatives to let the code be gtk3+ compatible?
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *button;
GtkWidget *halign;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Tooltip");
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
gtk_container_set_border_width(GTK_CONTAINER(window), 15);
button = gtk_button_new_with_label("Button");
gtk_widget_set_tooltip_text(button, "Button widget");
halign = gtk_alignment_new(0, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(halign), button);
gtk_container_add(GTK_CONTAINER(window), halign);
gtk_widget_show_all(window);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
As suggested in the comment, use these two functions instead:
void gtk_widget_set_halign (GtkWidget *widget, GtkAlign align);
Sets the horizontal alignment of widget.
gtk_widget_get_valign (GtkWidget *widget); Sets the vertical alignment of widget.
The enum GtkAlign types are the following:
GTK_ALIGN_START: The 'start' of the layout. Vertically this is the top, horizontally this is left/right according to LTR/RTL
GTK_ALIGN_END: Opposite of GTK_ALIGN_START
GTK_ALIGN_CENTER: The middle of the layout
GTK_ALIGN_FILL : Take all available space
for scaling use GTK_ALIGN_FILL.
So the gtk3+ compatible alternative for your code is the following:
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *button;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Tooltip");
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
gtk_container_set_border_width(GTK_CONTAINER(window), 15);
button = gtk_button_new_with_label("Button");
gtk_widget_set_tooltip_text(button, "Button widget");
gtk_widget_set_halign (button, GTK_ALIGN_START);
gtk_widget_set_valign (button, GTK_ALIGN_START);
gtk_container_add (GTK_CONTAINER (window), button);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}

GtkDrawingArea using Cairo doesn't apply in Windows 7

I work with GTK+ 2.24 in Windows 7 64-bit and Fedora 21 64-bit. I painted a drawing area to white, using Cairo. It works in Fedora, but not in Windows. Does anyone know the reason?
Here is my code:
static gboolean draw_background_cb(GtkWidget *widget _U_, cairo_t *cr, gpointer data _U_)
{
/* Set background color */
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_rectangle(cr, 0, 0, 300, 300);
cairo_paint(cr);
return FALSE;
}
int main(int argc, char *argv[])
{
GtkWidget *window;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "draw", G_CALLBACK (draw_background), NULL);
gtk_widget_show(window);
gtk_main();
return 0;
}
GTK+ 2 uses expose-event instead of draw for drawing. I don't know what the other differences are; sorry.

Displaying toggle button

i am new to gtk and i dont know how to display a toggle button in gtk.
there are no examples of the same for gtk+3.
here is what i did
GtkToolItem *tog;
tog = gtk_toggle_tool_button_new();
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tog), FALSE);
i tried to add toggle button to grid, container. i also tried using gtk_widget_show and pass tog but of no use.
can any one show me the an example code or how to solve this.
PS: not a C++ programmer.
You need to show all your toplevel's widgets:
// cc `pkg-config --cflags --libs gtk+-3.0` main.c
#include <gtk/gtk.h>
int main (int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *grid;
GtkToolItem *tool;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
grid = gtk_grid_new ();
tool = gtk_toggle_tool_button_new ();
gtk_tool_button_set_label (GTK_TOOL_BUTTON (tool), "Hi there");
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_grid_attach (GTK_GRID (grid), GTK_WIDGET (tool), 0, 0, 1, 1);
gtk_container_add (GTK_CONTAINER (window), grid);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}

How to manually draw the GtkTreeView expander

I'm using a GtkTreeView widget and I want to change the appearance of the "expander" icon that opens and closes child rows: I want the icons to be the triangels that we're all familiar with, but they're appearing as boxed "+" and "-" symbols instead.
At first I thought there must be a style enumeration that I can set, but I cannot find one. Then, I thought maybe there's a style property I can set in my theme's gtkrc file, but I don't think there is one. Finally, I resorted to trying to manually override the draw method like so:
GtkWidget *pTreeView = gtk_tree_view_new_with_model((GtkTreeModel *)pTreeModel);
(GTK_STYLE_GET_CLASS(pTreeView->style))->draw_expander = my_draw_expander_override;
But my_draw_expander_override() never gets called and the expanders are still the boxed "+" and "-" icons.
Does anyone know how can I change the appearance of the GtkTreeView expander icons or just draw them myself?
Thanks a bunch in advance!
Here the sample code of how to overwrite draw_expander. You'll definetely have to take a look in the manual to get all the parameters right.
#include <gtk/gtk.h>
#include <cairo.h>
enum {
COL_1,
N_COLS
};
void draw_expander (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
GdkRectangle *area,
GtkWidget *widget,
const gchar *detail,
gint x,
gint y,
GtkExpanderStyle expander_style) {
cairo_t *cr;
cr = gdk_cairo_create (window);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_move_to (cr, 0, 0);
cairo_line_to (cr, 0, 10);
cairo_line_to (cr, 10, 5);
cairo_close_path (cr);
cairo_stroke (cr);
}
GtkWidget *build_view (); /* just supply your own */
int main (int argc, char *argv[]) {
gtk_init (&argc, &argv);
GtkWidget *window;
GtkWidget *view;
window = g_object_new (GTK_TYPE_WINDOW, NULL);
view = build_view ();
gtk_container_add (GTK_CONTAINER (window), view);
GtkStyle *style = gtk_widget_get_style (view);
GtkStyleClass *klass = GTK_STYLE_GET_CLASS (style);
klass->draw_expander = draw_expander;
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
Maybe you should just try to switch to a theme that draws expanders the way you want them to be displayed, as I am quite sure some of your users might find it a little rude if you "force" them to approve that triangles are the one and only way to draw expanders and deny them any chance to change this.
That's especially what themes were made for - such that everybody can have the look she wants.
Well, anyway unfortunately actually GTK is in a transition from version 2 to version 3, so depending on the version you are using you would have to overwrite another signal.
It should be a little bit easier in GTK 3 since you already get your cairo context in the "draw" signal, but it's also possible in GTK 2, here you would have to use the "expose-event" signal.
Here as an example here a snippet of how to do it with GTK version 2. As I am no real artist it might not look too nice, but I'm sure you will come up with a nice design.
... ah, and don't forget to change the way it's painted depedning on its state ...
#include <gtk/gtk.h>
#include <cairo.h>
gboolean draw (GtkWidget *widget, GdkEventExpose *event, gpointer data) {
cairo_t *cr;
cr = gdk_cairo_create (widget->window);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_move_to (cr, 0, 0);
cairo_line_to (cr, 0, 10);
cairo_line_to (cr, 10, 5);
cairo_close_path (cr);
cairo_stroke (cr);
return TRUE;
}
int main (int argc, char *argv[]) {
gtk_init (&argc, &argv);
GtkWidget *window;
GtkWidget *expander;
window = g_object_new (GTK_TYPE_WINDOW, NULL);
expander = g_object_new (GTK_TYPE_EXPANDER, NULL);
gtk_container_add (GTK_CONTAINER (window), expander);
g_signal_connect (expander, "expose-event", draw, NULL);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
EDIT:
As I saw you don't seem to want to change the appearance for just one instance, but for ALL expanders. To accomplish this you would have to overwrite the default handler like this:
#include <gtk/gtk.h>
#include <cairo.h>
gboolean draw (GtkWidget *widget, GdkEventExpose *event) {
cairo_t *cr;
cr = gdk_cairo_create (widget->window);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_move_to (cr, 0, 0);
cairo_line_to (cr, 0, 10);
cairo_line_to (cr, 10, 5);
cairo_close_path (cr);
cairo_stroke (cr);
return TRUE;
}
int main (int argc, char *argv[]) {
gtk_init (&argc, &argv);
GtkWidget *window;
GtkWidget *expander;
GtkWidgetClass *klass;
window = g_object_new (GTK_TYPE_WINDOW, NULL);
expander = g_object_new (GTK_TYPE_EXPANDER, NULL);
gtk_container_add (GTK_CONTAINER (window), expander);
klass = g_type_class_peek (GTK_TYPE_EXPANDER);
klass->expose_event = draw;
gtk_widget_show_all (window);
gtk_main ();
return 0;
}