GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Sat Aug 30, 2014 4:13 pm

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: How to add a close button for a tab ?
PostPosted: Thu Jul 09, 2009 1:10 am 
Offline
GTK+ Geek

Joined: Mon Nov 10, 2008 6:54 am
Posts: 64
I tried this example :
Code:
#include <gtk/gtk.h>

static void destroy (GtkWidget*, gpointer);
static void switch_page (GtkButton*, GtkNotebook*);

int main (int argc,
          char *argv[])
{
  GtkWidget *window, *notebook;
  GtkWidget *label1, *label2, *child1, *child2;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Notebook");
  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
  gtk_widget_set_size_request (window, 250, 100);

  g_signal_connect (G_OBJECT (window), "destroy",
                    G_CALLBACK (destroy), NULL);

  notebook = gtk_notebook_new ();
  label1 = gtk_label_new ("Page One");
  label2 = gtk_label_new ("Page Two");
  child1 = gtk_button_new_with_label ("Go to page 2 to find the answer.");
  child2 = gtk_button_new_with_label ("Go to page 1 to find the answer.");
 
  /* Notice that two widgets were connected to the same callback function! */
  g_signal_connect (G_OBJECT (child1), "clicked",
                    G_CALLBACK (switch_page),
                    (gpointer) notebook);
  g_signal_connect (G_OBJECT (child2), "clicked",
                    G_CALLBACK (switch_page),
                    (gpointer) notebook);

  /* Append to pages to the notebook container. */
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), child1, label1);
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), child2, label2);

  gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_BOTTOM);
 
  gtk_container_add (GTK_CONTAINER (window), notebook);
  gtk_widget_show_all (window);

  gtk_main ();
  return 0;
}

/* Switch between the current GtkNotebook page. */
static void
switch_page (GtkButton *button,
             GtkNotebook *notebook)
{
  gint page = gtk_notebook_get_current_page (notebook);
 
  if (page == 0)
    gtk_notebook_set_current_page (notebook, 1);
  else
    gtk_notebook_set_current_page (notebook, 0);
}

static void
destroy (GtkWidget *window,
         gpointer data)
{
  gtk_main_quit ();
}

This is a notebook with 2 tabs, suppose that I want to have a little "x"( close button ) on the top-right of the tab so that I can either view the tab detail or close it. Just like open 2 files in a text-editor but I don't know how :( ! Anyone could give me a hint ?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 15, 2009 8:41 am 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hello.

I modified your code a bit to accommodate that additional close button on tab. Current results aren't the most beautiful ones, but you should be able to tweak them to suit your needs.

Code:
#include <gtk/gtk.h>

static void destroy (GtkWidget*, gpointer);
static void switch_page (GtkButton*, GtkNotebook*);

static GtkWidget *
create_notebook_label( const gchar *text,
                  GtkWidget   *notebook,
                  gint         page );
static void
cb_close_tab( GtkButton   *button,
           GtkNotebook *notebook );


int main (int argc,
          char *argv[])
{
  GtkWidget *window, *notebook;
  GtkWidget *label1, *label2, *child1, *child2;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Notebook");
  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
  gtk_widget_set_size_request (window, 250, 100);

  g_signal_connect (G_OBJECT (window), "destroy",
                    G_CALLBACK (destroy), NULL);

  notebook = gtk_notebook_new ();

  /* TB: Create composed tab widget for first tab */
  label1 = create_notebook_label( "Page One", notebook, 0 );
  label2 = create_notebook_label( "Page Two", notebook, 1 );
  child1 = gtk_button_new_with_label ("Go to page 2 to find the answer.");
  child2 = gtk_button_new_with_label ("Go to page 1 to find the answer.");

  /* Notice that two widgets were connected to the same callback function! */
  g_signal_connect (G_OBJECT (child1), "clicked",
                    G_CALLBACK (switch_page),
                    (gpointer) notebook);
  g_signal_connect (G_OBJECT (child2), "clicked",
                    G_CALLBACK (switch_page),
                    (gpointer) notebook);

  /* Append to pages to the notebook container. */
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), child1, label1);
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), child2, label2);

  gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_BOTTOM);

  gtk_container_add (GTK_CONTAINER (window), notebook);
  gtk_widget_show_all (window);

  gtk_main ();
  return 0;
}

/* Switch between the current GtkNotebook page. */
static void
switch_page (GtkButton *button,
             GtkNotebook *notebook)
{
  gint page = gtk_notebook_get_current_page (notebook);

  if (page == 0)
    gtk_notebook_set_current_page (notebook, 1);
  else
    gtk_notebook_set_current_page (notebook, 0);
}

static void
destroy (GtkWidget *window,
         gpointer data)
{
  gtk_main_quit ();
}

static GtkWidget *
create_notebook_label( const gchar *text,
                  GtkWidget   *notebook,
                  gint         page )
{
  GtkWidget *hbox,
         *label,
         *button,
         *image;

  hbox = gtk_hbox_new (FALSE, 3);

  label = gtk_label_new (text);
  gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);

  button = gtk_button_new();
  g_object_set_data( G_OBJECT( button ), "page", GINT_TO_POINTER( page ) );
  g_signal_connect( G_OBJECT( button ), "clicked",
               G_CALLBACK( cb_close_tab ),
               GTK_NOTEBOOK( notebook ) );
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);

  image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
  gtk_container_add (GTK_CONTAINER (button), image);

  gtk_widget_show_all( hbox );

  return( hbox );
}

static void
cb_close_tab( GtkButton   *button,
           GtkNotebook *notebook )
{
  gint page;

  page = GPOINTER_TO_INT( g_object_get_data( G_OBJECT( button ), "page" ) );
  gtk_notebook_remove_page( notebook, page );
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 15, 2009 1:34 pm 
Offline
GTK+ Geek

Joined: Mon Nov 10, 2008 6:54 am
Posts: 64
Thanks a lot tadeboro ! Although I posted this question for a while but I really appreciate it :D !
ps : really smart solution ! I thought of this idea but I didn't think it could go right into the upper right corner of the label perfectly like this. Great solution !


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 26, 2010 10:36 pm 
Offline
Familiar Face

Joined: Thu Feb 11, 2010 9:56 am
Posts: 28
HI this code has helped me close tabs, but what if i wanted to create a new tab every time a user ran a function?

How could i achieve that?

Thanks in advance


Top
 Profile  
 
 Post subject: Re:
PostPosted: Tue Jun 19, 2012 10:08 am 
Offline
Familiar Face

Joined: Fri Mar 25, 2011 7:55 am
Posts: 35
Location: romania
tadeboro wrote:
Hello.

I modified your code a bit to accommodate that additional close button on tab. Current results aren't the most beautiful ones, but you should be able to tweak them to suit your needs.

Code:
#include <gtk/gtk.h>

static void destroy (GtkWidget*, gpointer);
static void switch_page (GtkButton*, GtkNotebook*);

static GtkWidget *
create_notebook_label( const gchar *text,
                  GtkWidget   *notebook,
                  gint         page );
static void
cb_close_tab( GtkButton   *button,
           GtkNotebook *notebook );


int main (int argc,
          char *argv[])
{
  GtkWidget *window, *notebook;
  GtkWidget *label1, *label2, *child1, *child2;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Notebook");
  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
  gtk_widget_set_size_request (window, 250, 100);

  g_signal_connect (G_OBJECT (window), "destroy",
                    G_CALLBACK (destroy), NULL);

  notebook = gtk_notebook_new ();

  /* TB: Create composed tab widget for first tab */
  label1 = create_notebook_label( "Page One", notebook, 0 );
  label2 = create_notebook_label( "Page Two", notebook, 1 );
  child1 = gtk_button_new_with_label ("Go to page 2 to find the answer.");
  child2 = gtk_button_new_with_label ("Go to page 1 to find the answer.");

  /* Notice that two widgets were connected to the same callback function! */
  g_signal_connect (G_OBJECT (child1), "clicked",
                    G_CALLBACK (switch_page),
                    (gpointer) notebook);
  g_signal_connect (G_OBJECT (child2), "clicked",
                    G_CALLBACK (switch_page),
                    (gpointer) notebook);

  /* Append to pages to the notebook container. */
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), child1, label1);
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), child2, label2);

  gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_BOTTOM);

  gtk_container_add (GTK_CONTAINER (window), notebook);
  gtk_widget_show_all (window);

  gtk_main ();
  return 0;
}

/* Switch between the current GtkNotebook page. */
static void
switch_page (GtkButton *button,
             GtkNotebook *notebook)
{
  gint page = gtk_notebook_get_current_page (notebook);

  if (page == 0)
    gtk_notebook_set_current_page (notebook, 1);
  else
    gtk_notebook_set_current_page (notebook, 0);
}

static void
destroy (GtkWidget *window,
         gpointer data)
{
  gtk_main_quit ();
}

static GtkWidget *
create_notebook_label( const gchar *text,
                  GtkWidget   *notebook,
                  gint         page )
{
  GtkWidget *hbox,
         *label,
         *button,
         *image;

  hbox = gtk_hbox_new (FALSE, 3);

  label = gtk_label_new (text);
  gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);

  button = gtk_button_new();
  g_object_set_data( G_OBJECT( button ), "page", GINT_TO_POINTER( page ) );
  g_signal_connect( G_OBJECT( button ), "clicked",
               G_CALLBACK( cb_close_tab ),
               GTK_NOTEBOOK( notebook ) );
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);

  image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
  gtk_container_add (GTK_CONTAINER (button), image);

  gtk_widget_show_all( hbox );

  return( hbox );
}

static void
cb_close_tab( GtkButton   *button,
           GtkNotebook *notebook )
{
  gint page;

  page = GPOINTER_TO_INT( g_object_get_data( G_OBJECT( button ), "page" ) );
  gtk_notebook_remove_page( notebook, page );
}

-------------------------
I know is 2012, but maybe it help somebody

Code:
/* TB: Create composed tab widget for first tab */
  label1 = create_notebook_label( "Page One", notebook, 0 );
  label2 = create_notebook_label( "Page Two", notebook, 1 );
  child1 = gtk_button_new_with_label ("Go to page 2 to find the answer.");
  child2 = gtk_button_new_with_label ("Go to page 1 to find the answer.");


changed like this:
Code:
  child1 = gtk_button_new_with_label ("Go to page 2 to find the answer.");
  child2 = gtk_button_new_with_label ("Go to page 1 to find the answer.");
  label1 = create_notebook_label( child1, "Page One", notebook );
  label2 = create_notebook_label( child2, "Page Two", notebook );


and:

Code:
static GtkWidget *
create_notebook_label( GtkWidget   *child,
                       const gchar *text,
                       GtkWidget   *notebook )
{
....

  button = gtk_button_new();
  g_object_set_data( G_OBJECT( button ), "child", child );
 
.........
}


and:

Code:
static void
cb_close_tab( GtkButton   *button,
              GtkNotebook *notebook )
{
  GtkWidget *child;
  gint page;

  child = GTK_WIDGET( g_object_get_data( G_OBJECT( button ), "child" ));
  page = gtk_notebook_page_num( notebook, child );
  gtk_notebook_remove_page( notebook, page );
}

_________________
c/c++ for ever


Top
 Profile  
 
 Post subject: Re: How to add a close button for a tab ?
PostPosted: Tue Jun 19, 2012 1:51 pm 
Offline
Never Seen the Sunlight

Joined: Wed Sep 21, 2005 12:07 am
Posts: 563
Location: Portland, OR USA
As long as this post has been revived...

This code is in Python, but, it should at least illustrate the technique of making a close button on a GtkNotebook tab nice and small:

Code:
# close button
self._button = Gtk.Button()
self._button.set_relief(Gtk.ReliefStyle.NONE)
self._button.set_focus_on_click(False)
self._button.set_tooltip_text("Close Document")
image = Gtk.Image.new_from_stock(Gtk.STOCK_CLOSE, Gtk.IconSize.MENU)
self._button.add(image)
self._button.connect("clicked", self._on_close_clicked)

# make button as small as possible
self._button.set_size_request(0, 0)
data =  ".button {\n" \
        "-GtkButton-default-border : 0px;\n" \
        "-GtkButton-default-outside-border : 0px;\n" \
        "-GtkButton-inner-border: 0px;\n" \
        "-GtkWidget-focus-line-width : 0px;\n" \
        "-GtkWidget-focus-padding : 0px;\n" \
        "padding: 0px;\n" \
        "}"
context = self._button.get_style_context()
provider = Gtk.CssProvider()
provider.load_from_data(data)
context.add_provider(provider, 600) # GTK_STYLE_PROVIDER_PRIORITY_APPLICATION

_________________
Micah Carrick - Forum Administrator
http://www.micahcarrick.com


Top
 Profile  
 
 Post subject: Re: How to add a close button for a tab ?
PostPosted: Tue Jun 19, 2012 3:09 pm 
Offline
Familiar Face

Joined: Fri Mar 25, 2011 7:55 am
Posts: 35
Location: romania
thanks, but the problem was variable "gint page" attached to button.
problems when closing random notebook pages, or from down to up.
adding "child" data to button is a solution to identify pages to close when "close" is clicked.
and realy close button is a big button, i don't know how to aply your python code to c code to get a small button close.
i don't know python.

_________________
c/c++ for ever


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group