GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Fri Aug 22, 2014 11:37 pm

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: GtkListView with GtkListStore and GdkPixbuf
PostPosted: Sat Oct 13, 2012 4:36 am 
Offline

Joined: Mon Aug 27, 2012 1:57 pm
Posts: 2
Location: Bangalore, India
Dear All,
As it is my frist post so kindly bear with it. I have a task to display the image and two text in listview using liststore widget and I have written some code fot it but giving some problem. so please help or any idea that can help me is appreciate. The view should be as like as in attached picture.

Thanks in advance.
Code:
include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#include <gdk/gdkkeysyms.h>

#include <gtk/gtk.h>

enum
{
        COL_ICON = 0,
        COL_BOX,
        NUM_COLS
};

        GtkListStore *
create_liststore(void)
{
        GtkListStore  *store;
        GtkTreeIter    iter;
        GdkPixbuf     *image;
        GtkWidget *hbox;
        GtkWidget *label1;
        GtkWidget *label2;

        GError        *error = NULL;

        store = gtk_list_store_new(NUM_COLS, GDK_TYPE_PIXBUF, G_TYPE_BOXED);

        image = gdk_pixbuf_new_from_file("user-idle.png", &error);
        if (error)
        {
                g_warning ("Could not load image: %s\n", error->message);
                g_error_free(error);
                error = NULL;
        }
        hbox = gtk_hbox_new(FALSE, 2);
        label1 = gtk_label_new ("text");
        label2 = gtk_label_new ("text1");
        gtk_box_pack_start(GTK_BOX (hbox), label1, FALSE, FALSE, 0);
        gtk_box_pack_start(GTK_BOX (hbox), label2, FALSE, FALSE, 0);

        //adding store into list
        gtk_list_store_append(store, &iter);
        gtk_list_store_set(store, &iter, COL_ICON, icon, COL_BOX, hbox, -1);
        return store;
}

GtkWidget *create_treeview(void)
{
        GtkTreeModel      *model;
        GtkTreeViewColumn *col;
        GtkCellRenderer   *renderer;
        GtkWidget         *view;

        model = GTK_TREE_MODEL(create_liststore());

        view = gtk_tree_view_new_with_model(model);

        col = gtk_tree_view_column_new();
        //gtk_tree_view_column_set_title(col, "Title");

        renderer = gtk_cell_renderer_pixbuf_new();
        gtk_tree_view_column_pack_start(col, renderer, FALSE);
        gtk_tree_view_column_set_attributes(col, renderer, "pixbuf", COL_ICON, NULL);


        renderer = gtk_cell_renderer_text_new();
        gtk_tree_view_column_pack_start(col, renderer, TRUE);
        gtk_tree_view_column_set_attributes(col, renderer, "text", COL_BOX, NULL);

        gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);

        gtk_widget_show_all(view);
        return view;
}

int main (int argc, char **argv)
{
        GtkWidget *window;
        GtkWidget *view;
        gtk_init(&argc, &argv);
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        g_signal_connect(window, "delete_event", gtk_main_quit, NULL); /* dirty */

//      view = create_view_and_model();
        view = create_treeview();

        gtk_container_add(GTK_CONTAINER(window), view);
        gtk_widget_show_all(window);
        gtk_main();
        return 0;
}


Top
 Profile  
 
 Post subject: Re: GtkListView with GtkListStore and GdkPixbuf
PostPosted: Sat Oct 13, 2012 10:21 am 
Offline
Never Seen the Sunlight

Joined: Thu Mar 24, 2011 2:10 pm
Posts: 328
Location: Sydney, Australia
Could you lease tell us what type of problem you are experiencing. I'm happy to offer help, but don't have time to troll through unfamiliar code not knowing what to look for.
One thing I can see is that you are putting your labels in a horizontal box when the desired result indicates it should be vertically oriented (also the text of your labels doesn't match - but I guess you're not after something so trivial).

Beyond that, a few questions:

What version of GTK are you using? (I'm guessing 2.something)
Do you get a result and if so what does it look like?
Do you have any errors when compiling (and also how are you compiling it)?
Do you have any errors when running the program from the command line?

Excepting the first of these questions, they all will give answers that give good direction as to why you are not getting what you are wanting.

Also What is this for:
include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
You don't seem to be using anything from these libraries (which is good because it means you are coding well for portability) so why are they included?


Top
 Profile  
 
 Post subject: Re: GtkListView with GtkListStore and GdkPixbuf
PostPosted: Sun Oct 14, 2012 3:59 am 
Offline

Joined: Mon Aug 27, 2012 1:57 pm
Posts: 2
Location: Bangalore, India
Hi,
At frist I would like to thanks to Paul Childs for reading, reply and advising me for a better post. I will follow those rules before applying my topics.

and second, about my topic, I wanted to show one image in one column and two text in another column in one row of GtkListView. So for that I created GtkListStore with following definition.
Code:
store = gtk_list_store_new(NUM_COLS, GDK_TYPE_PIXBUF, G_TYPE_BOXED);

G_TYPE_BOXED as in third parameter because I took two label and box. I configured box with labels in column and passed to liststore. I tried to set liststore with following
Code:
gtk_list_store_set(store, &iter, COL_ICON, image, COL_BOX, hbox, -1);

and I'm getting following error after compiling
Quote:
(a.out:2997): Gtk-WARNING **: gtkliststore.c:449: Invalid type GBoxed
(a.out:2997): Gtk-CRITICAL **: gtk_list_store_append: assertion `GTK_IS_LIST_STORE (list_store)' failed
(a.out:2997): Gtk-CRITICAL **: gtk_list_store_set_valist: assertion `GTK_IS_LIST_STORE (list_store)' failed

I guess the error in coming because I could not able to set the attribute in following code.
Code:
gtk_tree_view_column_set_attributes(col, renderer, "text", COL_BOX, NULL);

so please help me to do this and if you have any other idea to show the data easily apart from my complicated one.

For your reference I'm using: Fedora 16, gcc 4.6.2 and gtk 3

Thanks


Top
 Profile  
 
 Post subject: Re: GtkListView with GtkListStore and GdkPixbuf
PostPosted: Sun Oct 14, 2012 5:30 am 
Offline
GTK+ Guru

Joined: Fri Mar 25, 2011 5:16 pm
Posts: 177
Location: USA
It's not enough that you've listed gtk+3 as your version. You need to indicate the subversion as well because there are differences between them.
Quote:
gtk_hbox_new has been deprecated since version 3.2 and should not be used in newly-written code. You can use gtk_box_new() with GTK_ORIENTATION_HORIZONTAL instead, which is a very quick and easy change. But the recommendation is to switch to GtkGrid, since GtkBox is going to go away eventually. See Migrating from other containers to GtkGrid.
http://developer.gnome.org/gtk3/3.1/GtkHBox.html#gtk-hbox-new

Notice it says "since gtk+3.2" but it's in the documentation for gtk+-3.1.
This is, I'm sure, not causing your main problem but I just wanted to point it out.


Top
 Profile  
 
 Post subject: Re: GtkListView with GtkListStore and GdkPixbuf
PostPosted: Sun Oct 14, 2012 10:07 am 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hello and welcome to the GTK+ forums!

You're having troubles because you don't fully understand how tree view works. Tree view can be seen as a empty piece of paper that is divided vertically into columns (column is represented by GtkTreeViewColumn) and horizontally into rows (you then actually get a grid). The actual content of tree view is then directly drawn on this paper by cell renderer. Cell renderer functions like rubber stamp where you set the attributes and then paint one cell of the grid. So it's operation can be described in pseudo-code like this:
  1. set proper attributes on cell renderer
  2. stamp contents into proper place
  3. move to next cell
  4. repeat from 1

It should be clear now that you cannot use widgets (or widget trees) when it comes to tree view.

Now, to solve your problem. There are three solutions available to this problem. The easiest one is to simply store the complete text in one column in your data store and embed a newline character directly inside it. This is really simply to implement, but complexity comes if you need to update just the second line, since now you'll need to hammer the string into something reasonable.

Second option is to store upper and lower strings in separate columns inside data store and then use cell data function to combine them at render time. This is a bit more complex to set up and will tax the performance of your application a bit, but now it's easy to modify only upper or lower text.

Third (and the best option) would be to create custom cell renderer, but this requires some work and knowledge of GObject and GType. I don't think this is feasible to achieve with your level of knowledge right now, but with a little hard work this can be changed.

Now, just to give you a quick boost, I created a sample app for the second approach (implementations of the first and third one are left as a practice/learning opportunity ) that demo's how to use cell data functions.

Code:
#include <gtk/gtk.h>

enum
{
  C_PIXBUF = 0,
  C_UP_TEXT,
  C_DOWN_TEXT,
  NO_COLS
};


static void
glue_text (GtkTreeViewColumn *col,
           GtkCellRenderer   *cell,
           GtkTreeModel      *model,
           GtkTreeIter       *iter)
{
  char *title, *text;
  char *markup;

  gtk_tree_model_get (model, iter, C_UP_TEXT, &title,
                      C_DOWN_TEXT, &text, -1);
  markup = g_strdup_printf ("<b><big>%s</big></b>\n%s", title, text);
  g_object_set (cell, "markup", markup, NULL);

  g_free (title);
  g_free (text);
  g_free (markup);
}

int
main (int    argc,
      char **argv)
{
  GtkWidget *window,
            *treeview;
  GtkListStore *store;
  GtkCellRenderer *cell;
  int i;


  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  g_signal_connect (window, "destroy", gtk_main_quit, NULL);


  store = gtk_list_store_new (NO_COLS, GDK_TYPE_PIXBUF,
                              G_TYPE_STRING, G_TYPE_STRING);
  for (i = 1; i < 10; i++)
    {
      GtkTreeIter iter;
      char line1[] = "Title in row  ";
      char line2[] = "Text in row  ";
      GdkPixbuf *pbuf;

      line1[13] = line2[12] = '0' + i;
      pbuf = gtk_widget_render_icon_pixbuf (window,
                                            GTK_STOCK_DIALOG_INFO,
                                            GTK_ICON_SIZE_DIALOG);

      gtk_list_store_append (store, &iter);
      gtk_list_store_set (store, &iter, C_PIXBUF, pbuf,
                          C_UP_TEXT, line1, C_DOWN_TEXT, line2, -1);

      g_object_unref (pbuf);
    }

  treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
  gtk_container_add (GTK_CONTAINER (window), treeview);
  g_object_unref (store);

  cell = gtk_cell_renderer_pixbuf_new ();
  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
                                               -1, "Image", cell,
                                               "pixbuf", C_PIXBUF,
                                               NULL);

  cell = gtk_cell_renderer_text_new ();
  gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview),
                                              -1, "Text", cell,
                                              (GtkTreeCellDataFunc)glue_text,
                                              NULL, NULL);

  gtk_widget_show_all (window);
  gtk_main ();
  return 0;
}

Cheers,
Tadej


Top
 Profile  
 
 Post subject: Re: GtkListView with GtkListStore and GdkPixbuf
PostPosted: Sun Oct 14, 2012 12:55 pm 
Offline
Never Seen the Sunlight

Joined: Thu Mar 24, 2011 2:10 pm
Posts: 328
Location: Sydney, Australia
A little follow up all round. Tadej's answer pretty much covers things well and provides a really clever way of customising a View given a simple model. I really don't know much about tree view as I find it quite the complicated widget set and there are many things that confound the beginner who isn't familiar with aspects of contemporary computer science (tree hierarchical data-structures, OOP, etc.).

Re: your error. These are actually run time not compile time errors. The first is the actual error, the rest show the propagation of this error (as gtkliststore isn't defined properly it creates errors later). The issue is that GTK_BOX isn't actually of type G_TYPE_BOXED. Unfortunately the GObject documentation doesn't make this distinction in nomenclature at all clear for anyone except the expert GObject developer. The liststore only takes fundamental types. You could replace G_TYPE_BOXED with G_TYPE_OBJECT but then you don't get all the extra stuff that GtkBoxes add onto GObjects (e.g. setting the text of the labels)

Zerohour's right about hbox/vbox being depreciated. You should have gotten a warning about that but as he says it makes no difference to your particular error. He is right about migrating to GtkGrid instead of Box to which I would add a fourth option to tadej's based on my biases as 4) ditch GtkTreeView entirely and place your widgets in a GtkGrid. Your application doesn't seem to need the particular skills of TreeView from what you've provided; whereas Grid has a much simpler interface for setting up widgets to span multiple columns/rows. Of course; however, if your task is GtkListStore then GtkListStore it is.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 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