0

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.

Shaï
  • 37
  • 2
  • 7
  • Does this even compile? There's no entry point, such as main. callback.h has implementation details? There's too many things going wrong here before we can even try to answer the question. Please provide an [MVCE](https://stackoverflow.com/help/mcve). – José Fonte Oct 30 '17 at 10:46
  • Oh sorry, I didn't post main, because it's just a function call : create_window(argc, argv); Actually, I can get a menu, with my button "create entry". But nothing happens when I click on it. And that's what I don't understand. I edit post to show more details – Shaï Oct 30 '17 at 20:09

2 Answers2

2

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:

result

WesH
  • 382
  • 2
  • 12
José Fonte
  • 3,711
  • 2
  • 15
  • 26
  • move `gtk_init()` to `main`. – el.pescado Oct 31 '17 at 11:21
  • @el.pescado yes i should but to avoid confusion to lucile i'll wait for her to give some feeback. This code should all be re written. it's a mess – José Fonte Oct 31 '17 at 11:23
  • Sorry about the long time. Well, I finally found an issue, but I'm pretty sure it's not proper and probably not the best way to make it. I post it as an answer because I can't edit with too much code – Shaï Nov 02 '17 at 21:05
  • The proper declarations for `main` are `int main (void)` and `int main (int argc, char **argv)` (which you will see written with the equivalent `char *argv[]`). **note:** `main` is a function of `type int` and it returns a value. See: [C11 Standard §5.1.2.2.1 Program startup (draft n1570)](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf). See also: [See What should main() return in C and C++?](http://stackoverflow.com/questions/204476/) – David C. Rankin Nov 02 '17 at 23:11
0

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;}
Shaï
  • 37
  • 2
  • 7
  • It's not the best way to continuously edit the same question. As said, callbacks.h should not have implementation or at least try to explain, with more effort, how you program is laid out. You did not include gtk.h, did not supply or explain where cb_quit is located and returning EXIT_SUCCESS is not correct. – José Fonte Nov 04 '17 at 12:58