Gtk - objektumok elérése a callback fügvényekben

Fórumok

Sziasztok!

Esemenykezelo callback fuggvenyekben van lehetoseg egy mutato atadasara (gpointer user_data) .

 
g_signal_connect ((gpointer) button_calc, "clicked",
                    G_CALLBACK (on_button_calc_clicked),
                    textview1);

Nekem a fuggvenyben tobb objektumot el kellene ernem.
Van valami egyszerubb modja ennek,minthogy tombbe rakom az obj. cimeket es azt adom at?

Koszonom.

Hozzászólások


typedef struct
 {  type1 param1;
    type2 param2;
    ...
 } clicked_params;

on_button_calc_clicked(GtkWidget *w,gpointer *d)
{
 clicked_params *cp=(clicked_params *)d;
 ...
}

...
clicked_params cp;
cp.param1=textview1;
cp.param2=...
...
g_signal_connect ((gpointer) button_calc, "clicked",
                    G_CALLBACK (on_button_calc_clicked), (gpointer *)&cp);

szoval valahogy igy.

erdemes akkor is egy sajat struct-ot definialni, ha csak egyetlen joldefinialt parameter van, ki tudja, hatha egyszer bo"viteni kell.

A.

Cast hiba.


interface.h 

typedef struct
 {  GtkTextView* param1; //GtkWidget* -el ua.
    GtkWidget* param2;
 } clicked_params;


interface.c

clicked_params cp;
//...........
  textview1 = gtk_text_view_new ();
  cp.param1=textview1; //param1 init

//............

g_signal_connect ((gpointer) button_calc, "clicked",
                    G_CALLBACK (on_button_calc_clicked),
                    (gpointer *)&cp);

callbacks.c
/...

void
on_button_calc_clicked                 (GtkButton       *button,
                                        gpointer         user_data)
{
  GtkTextTagTable* text_tag_table;
  GtkTextBuffer* text_buffer;
  text_tag_table = gtk_text_tag_table_new ();
  text_buffer = gtk_text_buffer_new (text_tag_table); 
  gtk_text_buffer_set_text(text_buffer,"Hello:-)",-1);
  
  clicked_params *cp=(clicked_params *)user_data;
  gtk_text_view_set_buffer (GTK_TEXT_VIEW(cp->param1), text_buffer);

}

terminal, calc-click utan:


anonym:~/th-calc/Thomson-calc/src$ ./thomson-calc

(thomson-calc:10477): GLib-GObject-WARNING **: invalid uninstantiatable type `' in cast to `GtkTextView'

(thomson-calc:10477): Gtk-CRITICAL **: file gtktextview.c: line 1145 (gtk_text_view_set_buffer): assertion `GTK_IS_TEXT_VIEW (text_view)' failed

Bocs,


(gpointer)&cp

e's nem (gpointer *)&cp;

gpointer == void *

kb. szoszerint. es az ilyen transzparens callback parameterek mindig void *-ok, csak a gtk/glib ezt "gpointer"-nek hivja.

(es a callback masodik parametere is gpointer es nem gpointer *).

hm, igy hianyos forras alapjan passz.

viszont mintha memory leak lenne a dologban: csinalsz egy (gtktextview*)-t gtk_text_buffer_new()-val, majd a callbackban ujra letrehozol egyet a new-val, majd az o"s-objektumba belepaszirozod az ujat. lehet hogy az nem tetszik neki, hogy ott ma'r van valami? nem ismerem ezt a gtktextview-widgetet, szoval lehet hogy hulyeseget beszelek, de talan itt erdemes korulnezni.

szerk: megsem igy, bocs, eloszor egy gtk_text_view_new()-et csinalsz, osszekevertem. viszont a gtk_text_buffer_new()-et minden egyes klikkolasnal meghivja, es beleteszi az o"sbe, szoval a leak attol me'g itt fennallhat.

A GTK_AKARMI_IZE(...) tipusu castolas nem csak (es talan kizarolag?) GtkWidget *-eket tud cast-olni? A gtk/gtk*.h alapjan kicsit nehezen kovetheto", de sosem lehet tudni. Ettol fuggetlenul mondjuk GtkAkarmiIze *-ot GtkAkarmiIze*-ra castolni GTK_AKARMI_IZE-vel talan felesleges, barmi is legyen ezutobbi mogott.

Sok mindent kiprobaltam mar...

Ha a struct-ban az adott mezo GtgTextWidget* es ertekadasnal egy GtkTextWidget cimet adom meg akkor elvileg nincs ertelmne itt castolni.Ezt is probaltam,..castolni is probaltam: .mezo = GTK_TEXT_VIEW(textview1).
A callbackben is minden fele modszert kiprobaltam..

Na ide irom mit hogy csinaltam.,szerintem elegge logikus ,nem ertem mi baja van.



interface.h

typedef struct {
GtkTextView *txtview;
//... 
}comp_list;


interface.c

comp_list cl;
//.........
textview1 = gtk_text_view_new ();
cl.txtview = GTK_TEXT_VIEW(textview1);
//.........

g_signal_connect ((gpointer) button_calc, "clicked",
                    G_CALLBACK (on_button_calc_clicked),
                    (gpointer)&cl);

callbacks.c

void
on_button_calc_clicked                 (GtkButton       *button,
                                        gpointer         user_data)
{
  GtkTextTagTable* text_tag_table;
  GtkTextBuffer* text_buffer;
  text_tag_table = gtk_text_tag_table_new ();
  text_buffer = gtk_text_buffer_new (text_tag_table); 
  gtk_text_buffer_set_text(text_buffer,"Hello:-)",-1);
  
  comp_list *p_cl = (comp_list *)user_data;
  GtkTextView *tv = p_cl->txtview; //semmi ertelme,de ...
  gtk_text_view_set_buffer (tv, text_buffer);
  gtk_text_view_set_buffer (GTK_TEXT_VIEW(p_cl->txtview), text_buffer);//castnak semmi ertelme,de...
  gtk_text_view_set_buffer (p_cl->txtview, text_buffer);//...

}

button-click,==> consol:

./thomson-calc

(thomson-calc:3821): Gtk-CRITICAL **: file gtktextview.c: line 1145 (gtk_text_view_set_buffer): assertion `GTK_IS_TEXT_VIEW (text_view)' failed

(thomson-calc:3821): Gtk-CRITICAL **: file gtktextview.c: line 1145 (gtk_text_view_set_buffer): assertion `GTK_IS_TEXT_VIEW (text_view)' failed

(thomson-calc:3821): Gtk-CRITICAL **: file gtktextview.c: line 1145 (gtk_text_view_set_buffer): assertion `GTK_IS_TEXT_VIEW (text_view)' failed

Tiszta h^lye...vagy en..

A GtkTextView *tv... tenyleg semmi ertelme de ha sokat hasznalom, en szeretek egy rovidebb valtozonevet hasznalni.

gtk_text_view_set_buffer (tv, text_buffer);
gtk_text_view_set_buffer (GTK_TEXT_VIEW(p_cl->txtview), text_buffer);//castnak semmi ertelme,de...
gtk_text_view_set_buffer (p_cl->txtview, text_buffer);//...

Mast nem tudok mondani, de probald ki ezeket egyesevel.

"Vegulis sikerult megoldani igy:


//interface.h

long* addr [8];

enum { textview1_addr_indx,
       entry_l_addr_indx, 
       //.........
     };
     

//interface.c

addr[textview1_addr_indx] = (long *)textview1;
addr[entry_l_addr_indx] = (long *)entry_l;
//..........

g_signal_connect ((gpointer) button_exit, "clicked",
                    G_CALLBACK (on_button_exit_clicked),
                    (gpointer)&addr);
//..........		   


//callbacks.c

void
on_radiobutton_f_pressed               (GtkButton       *button,
                                        gpointer         user_data)
{
 gtk_entry_set_text( (GtkEntry *)((long *)user_data)[entry_l_addr_indx],"");
 gtk_entry_set_editable( (GtkEntry *)((long *)user_data)[entry_l_addr_indx],0);
//....
}  

A cimek eltarolasanal explicit cast-ra (long *) csak a warningok elkerulese miatt van szukseg.

A (GtkEntry *) explicit cast-ra (lasd on_radiobutton_f_pressed() -ben)csakis a warning elkerulese miatt van szukseg,amugy teljesen jol mukodik ilyen alakban is : ((long *)user_data)[entry_l_addr_indx] .

ha a param1 GtkTextView*, akkor
cp.param1 = GTK_TEXT_VIEW (textview1);

void
on_button_calc_clicked (GtkButton *button,
gpointer user_data)
{
GtkTextTagTable* text_tag_table;
GtkTextBuffer* text_buffer;
GtkTreeView* tv;
text_tag_table = gtk_text_tag_table_new ();
text_buffer = gtk_text_buffer_new (text_tag_table);
gtk_text_buffer_set_text(text_buffer,"Hello:-)",-1);

clicked_params *cp=(clicked_params *)user_data;
tv = cp->param1;
gtk_text_view_set_buffer (tv, text_buffer);
gtk_text_view_set_buffer (cp->param1), text_buffer);
}

Megoldodott a problema elvileg, de az alaphelyzetet meg nem ertem.

adott:


typedef struct {
    GtkTextView* textview;
} param_list;

vhol main() kornyeken:


param_list pl;
GtkWidget* textview1;

textview1 = gtk_text_view_new ();
pl.textview = GTK_TEXT_VIEW (textview1);

g_signal_connect (button_calc, "clicked",
                    G_CALLBACK (on_button_calc_clicked),
                    (gpointer)&pl);

es a callback fv. :


void
on_button_calc_clicked  (GtkButton       *button,
                                    gpointer         user_data)
{
    param_list* pl = (param_list*) user_data;
    GtkTextView *tv = pl->textview;
    gtk_text_view_set_buffer (tv, text_buffer);

}

A kapott hibauzenet pedig:
(thomson-calc:10477): Gtk-CRITICAL **: file gtktextview.c: line 1145 (gtk_text_view_set_buffer): assertion `GTK_IS_TEXT_VIEW (text_view)' failed

Tehat a gtk_text_view_set_buffer fv dobja a hibat, mert a bekapott valtozo nem GtkTextView.
Szerintem a fent leirtaknak mukodnie kellene.
Biztos itt keletkezik a hiba?
Vagy mar meghulyultem?