2015-10-20 4 views
7

मैं अपने आवेदन में किसी बिंदु पर gtk प्रोग्राम, लिख रहा हूं, मैं उपयोगकर्ता से इनपुट प्राप्त करने के लिए gtkdialog को कॉल करता हूं। जो मैं करना चाहता हूं वह वर्तमान संवाद को बंद कर देता है और ठीक बटन क्लिक होने पर एक और संवाद खोलता है, मेरे पास पहले से ही कोई अन्य कार्य करने वाला फ़ंक्शन है, उस फ़ंक्शन में संवाद शुरू करना बहुत अच्छा होगा। यहाँ माता पिता संवाद कोड है:gtk एक संवाद के भीतर से एक संवाद प्रदर्शित करता है

GtkWidget * new_button_dialog = gtk_dialog_new_with_buttons("new button",(GtkWindow *)container,GTK_DIALOG_DESTROY_WITH_PARENT,"OK", GTK_RESPONSE_OK,NULL); 
     GtkWidget * content_area = gtk_dialog_get_content_area (GTK_DIALOG (new_button_dialog)); 
     GtkWidget * button_name_label = gtk_label_new ("Press escape at any time to cancel.\ntype in the button name"); 
     gtk_container_add (GTK_CONTAINER (content_area) , button_name_label); 
     GtkWidget * button_name_entry = gtk_entry_new(); 
     gtk_entry_set_activates_default((GtkEntry*)button_name_entry,TRUE); 
     gtk_container_add(GTK_CONTAINER(content_area), button_name_entry); 
     GtkWidget * button_text_dialog = gtk_dialog_new_with_buttons("new button",(GtkWindow *)container,GTK_DIALOG_DESTROY_WITH_PARENT,"OK", GTK_RESPONSE_OK,NULL); 
     gtk_container_add (GTK_CONTAINER (container), button); 
     g_signal_connect(new_button_dialog,"response",G_CALLBACK (add_new_button),NULL); 
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",GTK_SIGNAL_FUNC (gtk_widget_show_all),(GtkWidget*)new_button_dialog); 
     gtk_widget_show_all((GtkWidget *)container); 

उत्तर

2

एक संवाद की प्रतिक्रिया एक ही समारोह संवाद बनाई गई है कि में संभाला नहीं जा सकता। इसका मतलब है कि एक समारोह में आप एक संवाद नहीं बना सकते हैं, इसके इनपुट को संभाल सकते हैं, उस संवाद को बंद कर सकते हैं और एक नया संवाद खोल सकते हैं। ऐसा तब नहीं किया जा सकता जब से वह कार्य बाहर निकलता है संवाद प्रविष्टि खाली होती है और पहला संवाद अभी दिखाया जाता है।

इसे अलग-अलग ईवेंट हैंडलर की श्रृंखला के रूप में किया जाना चाहिए। सभी आवश्यक चर (डेटा संदर्भ) उन संदर्भों को रखने वाले संरचना के लिए एक सूचक का उपयोग करके उन अलग हैंडलरों के बीच स्थानांतरित किया जाना चाहिए।

नीचे पूर्ण रनने योग्य उदाहरण इस तरह के प्रवाह को प्रदर्शित करता है।

मुट्ठी संवाद हैंडलर में हम मुख्य विंडो और कुछ कंटेनर ऑब्जेक्ट के साथ कुछ करना चाहते हैं और शायद हम उस मुख्य विंडो के विजेट्स के बीच साझा किया गया कुछ अन्य डेटा चाहते हैं। इस तरह के संदर्भ के लिए संरचना window_ctx_t घोषित किया गया है। सक्रिय संवाद बंद करने से पहले नई संवाद श्रृंखलाओं पर निर्माण को लॉक करने के लिए उस संदर्भ में एक बुलियन ध्वज है।

फ़ंक्शन first_dialog_create टेक्स्ट एंट्री फ़ील्ड के साथ पहला संवाद बनाता है। यह window_ctx_t प्राप्त करता है, जहां मुख्य विंडो पॉइंटर संग्रहीत किया जाता है जिसका उपयोग संवाद निर्माण के लिए किया जाता है। अब हमें उस संवाद प्रतिक्रिया हैंडलर से अटैचमेंट करने की आवश्यकता है और इसके कार्यक्षमता के लिए हैंडलर पर्याप्त डेटा प्रदान करना होगा। उस उदाहरण में हम टेक्स्ट एंट्री को पॉइंटर प्रदान करते हैं जिसका उपयोग टेक्स्ट पढ़ने के लिए किया जाता है।

प्रदत्त डेटा का उपयोग करते हुए प्रतिक्रिया हैंडलर add_new_button मुख्य प्रविष्टि से जुड़ा एक नया संवाद बनाने के लिए और प्रदान किए गए कंटेनर के साथ कुछ करने के लिए टेक्स्ट एंट्री पढ़ने में सक्षम है।

जब पहली संवाद डेटा संदर्भ की आवश्यकता नहीं है तो इसे नष्ट हो चुके हैंडलर में g_free() पर कॉल करके इसे मुक्त किया जाता है।

उदाहरण बिल्ड:

gcc -Wall -g dialogs.c -o dialogs `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0` 

उदाहरण "dialogs.c"

#include <gtk/gtk.h> 

typedef struct { 
    GtkWidget *container; 
    GtkWindow *window; 
    gboolean dialogs_created; 
} window_ctx_t; 

typedef struct { 
    GtkEntry *entry; 
    window_ctx_t *window_ctx; 
} first_dialog_data_t; 

static void first_dialog_create(gpointer context); 

static void another_dialog_response(GtkWidget *dialog, gint response_id, 
    gpointer ctx) 
{ 
    window_ctx_t *win_ctx = ctx; 

    gtk_widget_destroy(dialog); 
    win_ctx->dialogs_created = FALSE; 
} 

static void cleanup_first_dialog(GtkWidget *widget, gpointer data) 
{ 
    g_free(data); 
} 

/* response callback of the first dialog */ 
static void add_new_button(GtkWidget *dialog, gint response_id, 
    gpointer ctx) 
{ 
    GtkWidget *button; 
    GtkWidget *button_text_dialog; 
    first_dialog_data_t *data = ctx; 

    if (response_id != GTK_RESPONSE_OK) { 
     data->window_ctx->dialogs_created = FALSE; 
     goto Exit; 
    } 

    /* Create a new button with the label from text entry */ 
    button = gtk_button_new_with_label(gtk_entry_get_text(data->entry)); 
    /* When the button receives the "clicked" signal, it will again open 
    * "new button" dialog */ 
    g_signal_connect_swapped(button, "clicked", G_CALLBACK(first_dialog_create), 
     data->window_ctx); 
    /* add button to the container */ 
    gtk_container_add(GTK_CONTAINER(data->window_ctx->container), button); 
    /* show button */ 
    gtk_widget_show(button); 

    /* create another dialog */ 
    button_text_dialog = gtk_dialog_new_with_buttons("new button", 
     data->window_ctx->window, GTK_DIALOG_DESTROY_WITH_PARENT, "OK", 
     GTK_RESPONSE_OK, NULL); 
    g_signal_connect(button_text_dialog, "response", 
     G_CALLBACK(another_dialog_response), (gpointer)data->window_ctx); 

    gtk_widget_show_all(button_text_dialog); 

Exit: 
    gtk_widget_destroy(dialog); 
} 

static void first_dialog_create(gpointer context) 
{ 
    first_dialog_data_t *data; 
    window_ctx_t *win_ctx = context; 

    if (win_ctx->dialogs_created) 
     return; 

    /* lock buttons handler */ 
    win_ctx->dialogs_created = TRUE; 

    /* allocate structure for dialog context */ 
    data = g_new0(first_dialog_data_t, 1); 

    /* create first dialog, its label and text entry */ 
    GtkWidget *new_button_dialog = gtk_dialog_new_with_buttons("new button", 
     win_ctx->window, GTK_DIALOG_DESTROY_WITH_PARENT,"OK", 
     GTK_RESPONSE_OK, NULL); 

    GtkWidget *content_area = gtk_dialog_get_content_area(
    GTK_DIALOG(new_button_dialog)); 
    GtkWidget *button_name_label = gtk_label_new("Press escape at any time to " 
     "cancel.\ntype in the button name"); 
    gtk_container_add(GTK_CONTAINER(content_area), button_name_label); 

    GtkWidget * button_name_entry = gtk_entry_new(); 
    gtk_entry_set_activates_default((GtkEntry*)button_name_entry,TRUE); 
    gtk_container_add(GTK_CONTAINER(content_area), button_name_entry); 

    /* provide data to response handler */ 
    data->entry = (GtkEntry *)button_name_entry; 
    data->window_ctx = win_ctx; 
    g_signal_connect(new_button_dialog, "response", G_CALLBACK(add_new_button), 
     data); 

    /* handler to free dialog context 'data' when destroed */ 
    g_signal_connect(new_button_dialog, "destroy", 
     G_CALLBACK(cleanup_first_dialog), data); 

    /* show first dialog */ 
    gtk_widget_show_all(new_button_dialog); 
} 

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

int main(int argc, char *argv[]) 
{ 
    GtkWidget *window; 
    GtkWidget *box1; 
    GtkWidget *button; 
    window_ctx_t win_ctx; 

    gtk_init (&argc, &argv); 
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 

    box1 = gtk_hbox_new(FALSE, 0); 
    gtk_container_add(GTK_CONTAINER(window), box1); 

    /* set window context */ 
    win_ctx.window = (GtkWindow *)window; 
    win_ctx.container = box1; 
    win_ctx.dialogs_created = FALSE; 

    g_signal_connect (window, "destroy", G_CALLBACK(destroy), NULL); 
    gtk_container_set_border_width(GTK_CONTAINER(window), 10); 

    button = gtk_button_new_with_label("Start"); 
    g_signal_connect_swapped(button, "clicked", G_CALLBACK(first_dialog_create), 
     &win_ctx); 
    gtk_container_add(GTK_CONTAINER(box1), button); 

    gtk_widget_show_all(window); 

    gtk_main(); 

    return 0; 
} 
संबंधित मुद्दे