Van egy programom, amelyben feldolgozom az alkalmazás főablakára irányuló delete_event szignált:
gboolean main_window_delete_event (GtkWidget * widget, GdkEvent * event, gpointer user_data) {
g_print ("delete-event\n");
return FALSE;
}
A szigálkezelő függvény a FALSE visszatérési értékkel jelzi, hogy az alkalmazás kiléphet, ha pedig a visszatérési érték TRUE, akkor az alkalmazás fut tovább.
Azt szerettem volna, hogy ha a program menűjéből kiválaszták a kilépés menűpontot, akkor egyszerűen küldje el a főablaknak a "delete-event" szignált, így az egész kilépési folyamatot csak egyszer kell megírnom, és a lehetőségekhez képest még szabályos is maradok:
void menuitem_quit_activate (GtkMenuItem * menuitem, gpointer user_data) {
/* a foablaknak kuldunk egy "delete_event" szignalt */
gboolean teszt;
g_signal_emit_by_name (G_OBJECT(main_window), "delete_event", G_TYPE_NONE, &teszt);
g_print ("eredmeny: %d\n", teszt);
}
Ha ez a szignálkezelő függvény végrehajtódik, akkor sikeresen elküldi a főablaknak a szignált (vagyis kiíródik a "delete-event" szöveg), a "teszt" változóban visszakapom annak a szignálkezelő függvénynek a visszatérési értékét, de a program nem lép ki, hanem továbbfut. Hiába játszadoztam a "delete-event" szignál visszatérési értékével, nem jutottam tovább.
Mi lehet a hiba, és a helyes megoldás?
- 1303 megtekintés
Hozzászólások
g_signal_emit_by_name
helyett ezzel?:
g_signal_connect_swapped(G_OBJECT(menu_item), "activate", G_CALLBACK(main_window_delete_event), G_OBJECT(main_window));
- A hozzászóláshoz be kell jelentkezni
Megnézem, bevallom, erre nem is gondoltam, pedig az általad írt függvényt régebben használtam már.
Bevallom, némelyik esetben annyira sokféle lehetőség van, hogy az már zavarbaejtő. :)
- A hozzászóláshoz be kell jelentkezni
a main_window delete_event -jere van g_signal_connect?
gboolean main_window_delete_event (GtkWidget * widget, GdkEvent * event, gpointer user_data) {
g_print ("delete-event\n");
return FALSE;
}
g_signal_connect(G_OBJECT(main_window), "delete_event", G_CALLBACK(main_window_delete_event), NULL);
void menuitem_quit_activate (GtkMenuItem * menuitem, gpointer user_data) {
/* a foablaknak kuldunk egy "delete_event" szignalt */
gboolean teszt;
g_signal_emit_by_name (G_OBJECT(main_window), "delete_event", G_TYPE_NONE, &teszt);
g_print ("eredmeny: %d\n", teszt);
}
- A hozzászóláshoz be kell jelentkezni
Igen, van rá szignál, vagyis ha be szeretném zárni az ablakot, minden tökéletesen és rendben fut le.
Gond csak akkor van, ha a kilépés menűpontot választva szeretném elküldeni az alkalmazás főablakának a "delete_event" szignált.
- A hozzászóláshoz be kell jelentkezni
Ha csak ennyivel hívod? :
g_signal_emit_by_name (G_OBJECT(main_window), "delete_event");
- A hozzászóláshoz be kell jelentkezni
Ha jól emlékszem, próbáltam, de a "&teszt" paraméter mindenképpen kell neki, hogy tudja hol eltárolni a szignálkezelő függvény visszatérési értékét.
- A hozzászóláshoz be kell jelentkezni
gboolean ret;
g_signal_emit_by_name (G_OBJECT(main_window), "delete_event", main_window, &ret);
Bar ezt most csak emlekezetbol.
vagy ez nem jo?
gtk_widget_destroy (main_window);
- A hozzászóláshoz be kell jelentkezni
Kipróbálom ezt is, holnap jelentkezem.
Köszönöm. :)
- A hozzászóláshoz be kell jelentkezni
A gtk_widget_destroy (main_window) azért nem jó, mert ha a felhasználó nem mentette a munkáját, akkor lehetőséget szeretnék neki adni erre.
Bár, ha jobban belegondolok, akkor amikor az lefut, elméletileg meghívodna a "delete_event" is.
Mindenesetre, talán rosszul gondolom, de úgy lenne igazán szép a megoldás, ha küldenék a main_window -nak szignált, ahogy eredetileg terveztem.
- A hozzászóláshoz be kell jelentkezni
Szep megoldas lenne, ha
GtkActionEntry - GtkActionGroup: igy helyesebb lenne a megoldas.
A GtkActionEntry-nek lehet callbacket allitani.
Megirod a callbacket (a menu nyomasakor meghivodik) itt lekezeled a mentes/valtozas kerdeset, utana mar mehet a destroy.
- A hozzászóláshoz be kell jelentkezni
csinálsz egy cleanup függvényt amiben elvégzed a program kilépés előtti műveleteket, mondjuk így:
gboolean cleanup(GtkWidget *widget, GdkEvent *event, gpointer data)
{
amit akarsz a kilépés előtt;
gtk_widget_destroy(foablakod_neve);
return FALSE;
}
Sima g_signal_connect-tel hozzácsatolod a főablakodhoz a "delete-event" signallal, majd csinálsz még egy csatolást a kilépéshez, pl.:
g_signal_connect(G_OBJECT(foablakod_neve), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
A menüből pedig a cleanup függvényt hívod.
- A hozzászóláshoz be kell jelentkezni
Visszavonok szinte mindent. eleg a gtk_widget_destroy(window);
Ha a destroy signalhoz van callback fuggveny meghivodik. tehat akkor eleg lesz ott elvegezni a dolgokat.
Az menu action-jeben meg csak destroy();
- A hozzászóláshoz be kell jelentkezni
Igen,attól függ mi is pontosan a cél.
A "destroy" mindenképp "kiléptet", de előbb lefuttatja a callback függvényét.
A "delete_event" a visszatérési értékétől függően:
FALSE esetén meghívódik a destroy,
TRUE esetén már nem kerül sor a destroy -ra, (nem záródik az alkalm.)
Tipikusan "Biztos kilépsz ebből a jó programból ?" jellegű dolgok esetén van értelme.
A kiinduló probléma esetében a legegyszerűbb a g_signal_connect_swapped(...)
lenne szerintem.
[...]
gboolean main_window_delete_event (GtkWidget * widget, GdkEvent * event, gpointer user_data) {
g_print ("delete-event\n");
return FALSE;
}
g_signal_connect(G_OBJECT(main_window), "delete_event", G_CALLBACK(main_window_delete_event), NULL);
g_signal_connect_swapped(G_OBJECT(menu_item), "activate", G_CALLBACK(main_window_delete_event), G_OBJECT(main_window));
[...]
Ha olyan eseménykezelésre van szükség amit menüből és toolbarról is hívni kell, akkor inkább az "actionXXX" függvények, ill: libbonobo...
szerk: egy gtk_main_quit(); is jól jöhet
- A hozzászóláshoz be kell jelentkezni
Kipróbáltam tegnap a három dolgot, amiket írtatok, az eredmények:
g_signal_emit_by_name (G_OBJECT(main_window), "delete_event", main_window, &ret);
Nem jó, ugyanazt a hibát produkálja, mint a nyitó hozzászólásban írt megoldásom.
g_signal_connect_swapped(G_OBJECT(menuitem), "activate", G_CALLBACK(main_window_delete_event), G_OBJECT(main_window));
Ha a menűben először kattintok a kilépésre, nem történik semmi, utána való kattintáskor lefut a "delete_event", de nem lép ki a program.
gtk_widget_destroy (main_window);
Nem fut le a "delete_event", hanem szó nélkül kilép a program.
A többi dolgot, amit írtatok, ma tudom kipróbálni.
- A hozzászóláshoz be kell jelentkezni
Esetleg az én megoldásommal? Ott a delete signalt hívod meg és onnan a destroy-t.
- A hozzászóláshoz be kell jelentkezni