How do I quit a gtk application from a button click? - c

Im trying to quit an application from a button click. What I'm currently doing Segfaults.
I have tried calling g_application_quit(G_APPLICATION(app)); in main it still segfaults
Calling gtk_widget_destroy(window); also segfaults
#include <stdlib.h>
#include <gtk/gtk.h>
void activate(GtkApplication* app, gpointer data)
{
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_application_add_window(app, GTK_WINDOW(window));
GtkWidget *button = gtk_button_new_with_label("Button");
void shutdown()
{
g_application_quit(G_APPLICATION(app));
}
g_signal_connect(GTK_BUTTON(button), "clicked", G_CALLBACK(shutdown), NULL);
gtk_container_add(GTK_CONTAINER(window), button);
gtk_widget_show(button);
gtk_window_present(GTK_WINDOW(window));
}
int main (int argc, char *argv[])
{
GApplicationFlags flags = G_APPLICATION_FLAGS_NONE;
GtkApplication *app = gtk_application_new("com.devab.daw", flags);
GApplication *gapp = G_APPLICATION(app);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
g_application_run(gapp, argc, argv);
g_object_unref (app);
//g_application_quit(G_APPLICATION(app));
return 0;
}

I am using gtk3 and this compiles and works for me.
#include <stdlib.h>
#include <gtk/gtk.h>
void activate(GtkApplication* app, gpointer data)
{
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_application_add_window(app, GTK_WINDOW(window));
GtkWidget *button = gtk_button_new_with_label("Button");
g_signal_connect_swapped(GTK_BUTTON(button), "clicked", G_CALLBACK(gtk_widget_destroy), window);
gtk_container_add(GTK_CONTAINER(window), button);
gtk_widget_show(button);
gtk_window_present(GTK_WINDOW(window));
}
int main (int argc, char *argv[])
{
GApplicationFlags flags = G_APPLICATION_FLAGS_NONE;
GtkApplication *app = gtk_application_new("com.devab.daw", flags);
GApplication *gapp = G_APPLICATION(app);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
g_application_run(gapp, argc, argv);
g_object_unref (app);
//g_application_quit(G_APPLICATION(app));
return 0;
}
Move destroy outside activate.
#include <stdlib.h>
#include <gtk/gtk.h>
void destroy (GtkWidget* widget, gpointer data)
{
g_application_quit(G_APPLICATION(data));
}
void activate(GtkApplication* app, gpointer data)
{
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_application_add_window(app, GTK_WINDOW(window));
GtkWidget *button = gtk_button_new_with_label("Button");
g_signal_connect(GTK_BUTTON(button), "clicked", G_CALLBACK(destroy), app);
gtk_container_add(GTK_CONTAINER(window), button);
gtk_widget_show(button);
gtk_window_present(GTK_WINDOW(window));
}
int main (int argc, char *argv[])
{
GApplicationFlags flags = G_APPLICATION_FLAGS_NONE;
GtkApplication *app = gtk_application_new("com.devab.daw", flags);
GApplication *gapp = G_APPLICATION(app);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
g_application_run(gapp, argc, argv);
g_object_unref (app);
//g_application_quit(G_APPLICATION(app));
return 0;
}

Related

How to set fontsize of label with Pango attributes?

I am trying to add a label to a GTK3 window and then set the font size of the label. Here is my attempt:
#include <gtk/gtk.h>
static void
add_label (GtkWidget* window, gchar *text)
{
GtkWidget *label = gtk_label_new(text);
PangoAttrList *attrlist = pango_attr_list_new();
PangoAttribute *attr = pango_attr_size_new_absolute(20);
pango_attr_list_insert(attrlist, attr);
gtk_label_set_attributes(GTK_LABEL(label), attrlist);
pango_attr_list_unref(attrlist);
gtk_container_add (GTK_CONTAINER (window), label);
}
static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window1");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
add_label( window, "Hello world" );
gtk_widget_show_all (window);
}
int
main (int argc, char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ( "org.gtk.example", G_APPLICATION_FLAGS_NONE );
g_signal_connect( app, "activate", G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref (app);
return status;
}
This does not produce any label at all. If I comment out the line:
gtk_label_set_attributes(GTK_LABEL(label), attrlist);
the label shows up, but the font size is not set.
I think PANGO_SCALE is missing here.
PangoAttribute *attr = pango_attr_size_new_absolute(20 * PANGO_SCALE);
This should give you the desired result:

How can I create new window in GTK after click?

I'm new at GTK, and I was wondering how can I create a new window after a click button. I've got this function
void cb_create_entry(GtkWidget *, gpointer);
int create_window(int argc, char *argv[]){
GtkWidget *p_window = NULL;
GtkWidget *p_main_box = NULL;
GtkWidget *p_button[5];
gtk_init (&argc, &argv);
//Create window
p_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(p_window), "Hello");
gtk_window_set_default_size(GTK_WINDOW(p_window), 320, 200);
p_main_box = gtk_vbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(p_window), p_main_box);
{
p_button[0] = gtk_button_new_with_label("Create entry");
g_signal_connect(G_OBJECT(p_button[0]), "clicked",
G_CALLBACK(cb_create_entry), NULL);
gtk_box_pack_start(GTK_BOX(p_main_box), p_button[0], FALSE, FALSE, 0);
}
gtk_widget_show_all(p_window);
gtk_main ();
return EXIT_SUCCESS;
and callback.h
#ifndef CALLBACK_H_INCLUDED
#define CALLBACK_H_INCLUDED
#include <gtk/gtk.h>
void cb_create_entry(GtkWidget *p_widget, gpointer user_data){
gtk_button_released(p_widget);
GtkWidget *p_window;
GtkWidget *p_v_box;
GtkWidget *p_entry;
p_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(p_window), "Create DB");
gtk_window_set_default_size(GTK_WINDOW(p_window), 320, 200);
p_v_box = gtk_vbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(p_window), p_v_box);
p_entry = gtk_entry_new();
gtk_box_pack_start(GTK_BOX(p_v_box), p_entry, TRUE, FALSE, 0);
}
and main
int main(int argc, char const *argv[]) {
create_window(argc, argv);
return 0;
}
But it doesn't work. I'd like to create a new window with an input. But when I click on button, nothing happens.
I'm a bit confused on how you laid out your file structure. Since there's no input on that I'll assume that the file with create_window function is the same where you have main. Then, callback.h should not have implementation code.
Nevertheless, i don't see any gtk_widget_show or gtk_widget_show_all calls and not sure you suppressed or just missed them. I'll assume the later because by your description it seems that you can see the initial window.
It's also missing a call to gtk_main.
Adding GtkWidget show functions and gtk_main to your code, it does work like expected:
Lets call the first file main.c :
#include <gtk/gtk.h>
#include "callback.h"
void cb_create_entry(GtkWidget *, gpointer);
int create_window(int argc, char *argv[]){
GtkWidget *p_window = NULL;
GtkWidget *p_main_box = NULL;
GtkWidget *p_button[5];
gtk_init (&argc, &argv);
//Create window
p_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(p_window), "Hello");
gtk_window_set_default_size(GTK_WINDOW(p_window), 320, 200);
p_main_box = gtk_vbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(p_window), p_main_box);
p_button[0] = gtk_button_new_with_label("Create entry");
g_signal_connect(G_OBJECT(p_button[0]), "clicked",
G_CALLBACK(cb_create_entry), NULL);
gtk_box_pack_start(GTK_BOX(p_main_box), p_button[0], FALSE, FALSE, 0);
gtk_widget_show_all(p_window);
}
int main (int argc, char *argv[]) {
create_window(argc, argv);
gtk_main ();
return 0;
}
And the other file callbacks.h :
#include <gtk/gtk.h>
void cb_create_entry(GtkWidget *p_widget, gpointer user_data){
gtk_button_released(p_widget);
GtkWidget *p_window;
GtkWidget *p_v_box;
GtkWidget *p_entry;
p_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(p_window), "Create DB");
gtk_window_set_default_size(GTK_WINDOW(p_window), 320, 200);
p_v_box = gtk_vbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(p_window), p_v_box);
p_entry = gtk_entry_new();
gtk_box_pack_start(GTK_BOX(p_v_box), p_entry, TRUE, FALSE, 0);
gtk_widget_show_all(p_window);
}
Then compiling with:
gcc -o test main.c callback.h `pkg-config --cflags --libs gtk+-3.0`
will result in a window with a button, which after being pressed will create and show a new window with a GtkEntry:
now callback.h looks like that :
int cb_create_entry(GtkWidget *p_widget, gpointer user_data){
GtkWidget *p_window = NULL;
GtkWidget *p_entry = NULL;
GtkWidget *p_button = NULL;
GtkWidget *p_main_box = NULL;
GtkWidget *p_label = NULL;
p_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(p_window), "Create entry");
gtk_window_set_default_size(GTK_WINDOW(p_window), 320, 200);
g_signal_connect (G_OBJECT (p_window), "destroy", G_CALLBACK (cb_quit), NULL);
p_main_box = gtk_vbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(p_window), p_main_box);
p_label = gtk_label_new("Please, name your DB");
gtk_container_add(GTK_CONTAINER(p_main_box), p_label);
p_entry = gtk_entry_new();
gtk_container_add(GTK_CONTAINER(p_main_box), p_entry);
p_button = gtk_button_new_with_label("Create !");
gtk_container_add(GTK_CONTAINER(p_main_box), p_button);
{
GtkWidget *p_quit = NULL;
p_quit = gtk_button_new_with_label("Quit");
g_signal_connect(G_OBJECT(p_quit), "clicked", G_CALLBACK(cb_quit), NULL);
gtk_box_pack_start(GTK_BOX(p_main_box), p_quit, FALSE, FALSE, 0);
}
//gtk_widget_show(p_entry);
gtk_widget_show_all(p_window);
return EXIT_SUCCESS;}

C - creating a menu with gtk3

I'm trying to make a simple menu in gtk3. I was looking at the official documentation and other code I found in the web, but still I am not able to get it to work. The menu does not appear.
I would appreciate any help. Thank you.
This is the code I have so far:
#include <stdio.h>
#include <gtk/gtk.h>
//#include "minefield.h"
enum difficulty {BEGINNER, ADVANCED, EXPERT};
static void activate(GtkApplication* app, gpointer user_data);
GdkPixbuf *create_pixbuf(const gchar * filename);
void newGame();
void openSetupDialog();
void openOptionDialog();
int main(int argc, char *argv[]) {
GtkApplication *app;
int status;
app = gtk_application_new("my.ne.sweeper", G_APPLICATION_FLAGS_NONE);
g_signal_connect(app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run(G_APPLICATION (app), argc, argv);
g_object_unref(app);
return status;
}
static void activate(GtkApplication* app, gpointer user_data) {
GdkPixbuf *app_icon;
GtkWidget *app_window;
GtkWidget *app_box;
GtkWidget *menubar;
GtkWidget *gameMenu;
GtkWidget *gameMenu_game;
GtkWidget *gameMenu_newGame;
GtkWidget *gameMenu_setup;
GtkWidget *gameMenu_options;
GtkWidget *gameMenu_quit;
GtkWidget *sep;
// App_window
app_window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(app_window), "Minesweeper");
gtk_window_set_default_size(GTK_WINDOW(app_window), 600, 400);
gtk_window_set_position(GTK_WINDOW(app_window), GTK_WIN_POS_CENTER);
// App_box
app_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add(GTK_CONTAINER(app_window), app_box);
// App_icon
app_icon = create_pixbuf("../img/app_icon.svg");
gtk_window_set_icon(GTK_WINDOW(app_window), app_icon);
// Menubar
menubar = gtk_menu_bar_new();
gtk_box_pack_start(GTK_BOX(app_box), menubar, FALSE, FALSE, 0);
// Start menu
gameMenu = gtk_menu_new();
gameMenu_game = gtk_menu_item_new_with_label("Game");
gameMenu_newGame = gtk_menu_item_new_with_label("New Game");
gameMenu_setup = gtk_menu_item_new_with_label("Setup");
gameMenu_options = gtk_menu_item_new_with_label("Options");
gameMenu_quit = gtk_menu_item_new_with_label("Quit");
sep = gtk_separator_menu_item_new();
gtk_menu_item_set_submenu(GTK_MENU_ITEM(gameMenu_game), gameMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), gameMenu_game);
gtk_menu_shell_append(GTK_MENU_SHELL(gameMenu), gameMenu_newGame);
gtk_menu_shell_append(GTK_MENU_SHELL(gameMenu), gameMenu_setup);
gtk_menu_shell_append(GTK_MENU_SHELL(gameMenu), gameMenu_options);
gtk_menu_shell_append(GTK_MENU_SHELL(gameMenu), sep);
gtk_menu_shell_append(GTK_MENU_SHELL(gameMenu), gameMenu_quit);
gtk_widget_show_all(app_window);
// Signalhandlers
g_signal_connect(app_window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(gameMenu_newGame, "activate", G_CALLBACK(newGame), NULL);
g_signal_connect(gameMenu_setup, "activate", G_CALLBACK(openSetupDialog), NULL);
g_signal_connect(gameMenu_options, "activate", G_CALLBACK(openOptionDialog), NULL);
g_signal_connect(gameMenu_quit, "activate", G_CALLBACK(gtk_main_quit), NULL);
g_object_unref(app_icon);
}
GdkPixbuf *create_pixbuf(const gchar * filename) {
GdkPixbuf *pixbuf;
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_file(filename, &error);
if (!pixbuf) {
fprintf(stderr, "[!] %s\n", error->message);
g_error_free(error);
}
return pixbuf;
}
void newGame() {
fprintf(stdout, "[*] %s\n", "new game..");
}
void openSetupDialog() {
fprintf(stdout, "[*] %s\n", "open setup..");
}
void openOptionDialog() {
fprintf(stdout, "[*] %s\n", "open options..");
}

How to set placeholder text in GtkEntry

I tried this example:
#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
GdkPixbuf *create_pixbuf(const gchar * filename) {
GdkPixbuf *pixbuf;
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_file(filename, &error);
if(!pixbuf) {
fprintf(stderr, "%s\n", error->message); g_error_free(error);
}
return pixbuf;
}
void implement() {
printf("HI");
}
int main( int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *frame;
GtkWidget *label;
GtkWidget *text;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "New Message");
gtk_window_set_default_size(GTK_WINDOW(window), 310, 390);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_icon(GTK_WINDOW(window), create_pixbuf("web.png"));
frame = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window), frame);
text = gtk_entry_new();
gtk_entry_set_max_length (GTK_ENTRY (text), 0);
gtk_entry_set_width_chars (GTK_ENTRY (text), 37);
gtk_entry_set_placeholder_text(GTK_ENTRY (text), "Send a message");
gtk_fixed_put(GTK_FIXED(frame), text, 2, 360);
gtk_widget_show_all(window);
g_signal_connect(window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_main();
return 0;
}
but getting error : undefined reference togtk_entry_set_placeholder_text'`
Make sure your GTK+ version is 3.2 or later, since that's when that particular function was added.

Drag and drop, motion_notify_event, mouse coordinate shaking

Then i start to drag an icon (code below), it starts jumping between 2 positions.
Can anybody help me resolve this shaking problem ?
Code:
#include <stdlib.h>
#include <stdio.h>
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <string.h>
#define ICON_BUFFER 5
struct Icon {
GtkWidget *image;
int x,y,width,height;
};
GtkWidget *window;
GtkWidget *fixed;
struct Icon icons[ICON_BUFFER];
gboolean drag = FALSE;
static gboolean handleMove( GtkWidget *widget, GdkEventButton *event, gpointer data ){
struct Icon *icon = (struct Icon*) data;
icon->x = (int)event->x;
icon->y = (int)event->y;
gtk_fixed_move (GTK_FIXED (fixed), widget, icon->x, icon->y);
printf("move (%d , %d) %d\n", icon->x, icon->y,event->time);
return TRUE;
}
static gboolean handleRelease( GtkWidget *widget, GdkEventButton *event, gpointer data ){
g_signal_handlers_disconnect_by_func(widget, handleMove, data);
printf("%s\n", "disconnect_handleMove");
struct Icon *icon = (struct Icon*) data;
printf("position (%d , %d)\n", icon->x, icon->y);
drag = FALSE;
return TRUE;
}
static gboolean handleClick( GtkWidget *widget, GdkEventButton *event, gpointer data ){
//g_print ("Event box clicked at coordinates %f,%f\n", event->x, event->y);
struct Icon *icon = (struct Icon*) data;
if(!drag){
drag = TRUE;
printf("%s\n", "connect_handleMove");
g_signal_connect (G_OBJECT (widget), "motion_notify_event" ,G_CALLBACK(handleMove), data);
g_signal_connect (G_OBJECT (widget), "button-release-event",G_CALLBACK(handleRelease), data);
printf("position (%d , %d)\n", icon->x, icon->y);
return TRUE;
}else
return TRUE;
}
int main( int argc, char *argv[] ){
/* GtkWidget is the storage type for widgets */
GtkWidget *event;
GtkWidget *image;
GtkWidget *background;
GtkStyle *style;
GdkPixbuf *pixbuf;
gint i;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Fixed Container");
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
fixed = gtk_fixed_new ();
gtk_container_add (GTK_CONTAINER (window), fixed);
gtk_widget_set_size_request(fixed,480,480);
gtk_widget_show (fixed);
for (i = 0 ; i < 4 ; i++) {
event = gtk_event_box_new ();
image = gtk_image_new_from_file("test2.jpg");
icons[i].image = image;
icons[i].x = i*50;
icons[i].y = i*50;
icons[i].width = 50;
icons[i].height = 50;
gtk_container_add (GTK_CONTAINER (event), image);
gtk_fixed_put (GTK_FIXED (fixed), event, i*50, i*50);
gtk_event_box_set_above_child(GTK_EVENT_BOX(event), FALSE);
g_signal_connect (G_OBJECT (event), "button_press_event",
G_CALLBACK (handleClick), (gpointer) &icons[i]);
gtk_event_box_set_visible_window(GTK_EVENT_BOX(event),(gboolean)FALSE);
gtk_widget_show (image);
gtk_widget_show (event);
}
gtk_widget_show (window);
gtk_main ();
return 0;
}
Code can be compiled and run with (or gtk+-2.0 instead of gtk+-3.0):
cc pkg-config --cflags --libs gdk-pixbuf-2.0 gtk+-3.0 FixedDragAndDrop.c -o FixedDragAndDrop.o && ./FixedDragAndDrop.o

Resources