微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

g_signal_connect_swapped 连接失败

如何解决g_signal_connect_swapped 连接失败

过去一个月,我尝试学习将 gtk 用于应用程序并将其代码从 gtk2 迁移到 gtk3。但是,gtk 对话框中的一个按钮似乎不起作用,尽管我选择了对话框关闭而不调用回调函数

int validation_pmu_server (gtkbutton *button,gpointer udata)
{

/* local variables */
int tmp_p;
char *msg;
const char *text1,*text2;

/* Get the text entries filled by user */
text1 = gtk_entry_get_text(GTK_ENTRY(p_port));
text2 = gtk_combo_Box_text_get_active_text(GTK_COMBO_Box_TEXT(p_protocol));

if(!isNumber((char *)text1) && (atoi(text1) < 1500 || (atoi(text1) > 65535)))   /* Check for valid port number */       
{ 
    msg = "\tPlease enter valid value for PMU Server Port\t\n";
    validation_result (msg);        /* Show the unsuccess message to user */
    return 0;
}
else
{
    strncpy(PMUprotocol,text2,3);
    PMUport = atoi(text1);

    if(!strcmp(text2,"UDP"))
        tmp_p = 1;          
    else
        tmp_p = 2;          

    p1 = *ShmPTR;
    p1.cfg_bit_change_info = 0;
    ShmPTR->cfg_bit_change_info = 0;
    ShmPTR->serverProtocol = tmp_p;
    ShmPTR->serverPort = atoi(text1);

    p1.pid = ShmPTR->pid;

    kill(p1.pid,SIGUSR2);
    printf("PORT & Protocol information has sent to PMU Server through signal.\n");

    memset(pmuFilePath,'\0',200);

    gtk_widget_set_sensitive(GTK_WIDGET(pmu_data->start_server),FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(pmu_data->open_cfg),FALSE);

    gtk_widget_set_sensitive(GTK_WIDGET(pmu_data->create_cfg_button),TRUE);                    
    gtk_widget_set_sensitive(GTK_WIDGET(pmu_data->menu_setup_cfg),TRUE);                   

    /* Close/destroy the pmu_server_window */
    gtk_widget_destroy(pmu_server_window);

    return 1;
}
};

void pmu_server ()
{
/* local variables */
GtkWidget *table,*label,*cancel_button;
GtkWidget *valdbutton,*help_button;

/* Create a new dialog window for PMU Server Setup */
pmu_server_window = gtk_dialog_new ();
g_signal_connect (pmu_server_window,"destroy",G_CALLBACK (gtk_widget_destroy),pmu_server_window);
gtk_window_set_title (GTK_WINDOW (pmu_server_window),"PMU Server Setup");
gtk_container_set_border_width (GTK_CONTAINER (pmu_server_window),10);

/* Create a table of 4 by 2 squares. */
table = gtk_grid_new (); // table = gtk_table_new (6,2,FALSE);

/* Set the spacing to 50 on x and 5 on y */
gtk_grid_set_row_spacing (GTK_GRID(table),16); // gtk_table_set_row_spacings (GTK_TABLE  (table),8);
gtk_grid_set_column_spacing (GTK_GRID(table),16); // gtk_table_set_col_spacings (GTK_TABLE  (table),2);

/* Pack the table into the window */
//gtk_Box_pack_start (GTK_Box (GTK_DIALOG(pmu_server_window)->vBox),table,TRUE,0);
gtk_Box_pack_start (GTK_Box (gtk_dialog_get_content_area (GTK_DIALOG(pmu_server_window))),0);
gtk_widget_show (table);

/* Add few buttons to the bottom of the dialog */
valdbutton = gtk_dialog_add_button((GtkDialog *)pmu_server_window,"Run",GTK_RESPONSE_OK); // gtk_button_new_with_label ("Run");
help_button = gtk_dialog_add_button((GtkDialog *)pmu_server_window,"Help",GTK_RESPONSE_APPLY); // gtk_button_new_with_label ("Help");
cancel_button = gtk_dialog_add_button((GtkDialog *)pmu_server_window,"Cancel",GTK_RESPONSE_CLOSE); //gtk_button_new_with_label ("Cancel");

/* This simply creates a grid of toggle buttons on the table */
label = gtk_label_new (" ");
markup = g_markup_printf_escaped ("<span foreground=\"#990033\" font='12'><b>Enter PMU Server Details</b></span>");
gtk_label_set_markup (GTK_LABEL (label),markup);
gtk_grid_attach (GTK_GRID (table),label,1); // gtk_table_attach_defaults (GTK_TABLE (table),1);
gtk_widget_show (label);
g_free (markup);

label = gtk_label_new ("Server Port");
    // gtk_misc_set_alignment (GTK_MISC(label),0);
    gtk_label_set_xalign (GTK_LABEL (label),0);
    gtk_label_set_yalign (GTK_LABEL (label),0);
gtk_grid_attach (GTK_GRID (table),1,3);
gtk_widget_show (label);

label = gtk_label_new ("Protocol");
    // gtk_misc_set_alignment (GTK_MISC(label),3,4);
gtk_widget_show (label);

/* Create text Boxes for user to enter appropriate values */
p_port = gtk_entry_new();
gtk_entry_set_max_length ((GtkEntry *)p_port,5);
gtk_grid_attach (GTK_GRID (table),p_port,3);
gtk_widget_show (p_port);

label = gtk_label_new (" ");
markup = g_markup_printf_escaped ("<span foreground=\"#333333\" font='8'><b>Note : Use the unreserved ports for PMU Server.</b></span>");
gtk_label_set_markup (GTK_LABEL (label),markup);
    // gtk_misc_set_alignment (GTK_MISC(label),5,6);
gtk_widget_show (label);
g_free (markup);

/* Create combo Boxe for user with some fixed values */
p_protocol = gtk_combo_Box_text_new();
gtk_combo_Box_text_append_text(GTK_COMBO_Box_TEXT(p_protocol),"UDP");
gtk_combo_Box_text_append_text(GTK_COMBO_Box_TEXT(p_protocol),"TCP");
gtk_combo_Box_set_active(GTK_COMBO_Box(p_protocol),p_protocol,4);
gtk_widget_show (p_protocol);

/* Signal handling for buttons on PMU Server Setup Window */
g_signal_connect_swapped (valdbutton,"clicked",G_CALLBACK (validation_pmu_server),valdbutton);
g_signal_connect_swapped (help_button,G_CALLBACK (Pmu_Help),NULL);
g_signal_connect_swapped (cancel_button,pmu_server_window);
g_signal_connect_swapped (pmu_server_window,"response",pmu_server_window);

/* This makes it so the button is the default. */
// gtk_Box_pack_start (GTK_Box (GTK_DIALOG (pmu_server_window)->action_area),valdbutton,0);
// gtk_Box_pack_start (GTK_Box (GTK_DIALOG (pmu_server_window)->action_area),help_button,cancel_button,0);        

/* This grabs this button to be the default button. Simply hitting the "Enter" key will cause this button to activate. */
gtk_widget_grab_default (valdbutton);
gtk_widget_show (valdbutton);
gtk_widget_grab_default (help_button);
gtk_widget_show (help_button);
gtk_widget_grab_default (cancel_button);
gtk_widget_show (cancel_button);

/* Finally show the pmu_server_window */
gtk_widget_show (pmu_server_window);
};

函数pmu_server创建一个对话框,如图in this image

根据我的代码,当点击运行按钮时 validation_pmu_server 应该被调用,但对话框只是简单地关闭,就像 gtk_widget_destroy调用一样。一些注释代码是我迁移到 gtk3 的旧 gtk2 代码

PS : 上面代码从 gtk2 到 gtk3 的变化是使用 this reference 虽然我能够以某种方式使我的代码工作,但我请任何有知识的人帮助我理解为什么会发生这种情况。

解决方法

显然问题是由于下面的行

g_signal_connect_swapped (pmu_server_window,"response",G_CALLBACK (gtk_widget_destroy),pmu_server_window);

一旦我删除了上面的行或将其更改为下面的代码,一切似乎都正常,但我仍然不确定为什么,我猜是发送“响应”作为详细信号导致了问题。

g_signal_connect_swapped (pmu_server_window,"destroy",pmu_server_window);
,

您面临的问题是由 response 信号引起的。每当单击任何操作小部件(在您的情况下为对话框按钮)时,响应信号都会在任何其他信号(单击信号)之前发出。因此,与信号 response 关联的函数回调将首先执行,然后是与 clicked 信号关联的回调。因此,gtk_widget_destroy 将首先被调用并且您的对话框正在关闭。

您可以更改与 response 关联的回调或使用任何其他信号。

我使用以下独立代码来重现该问题。

#include<stdio.h>
#include <gtk/gtk.h>


void Pmu_Help(){
    printf("Pmu_Help");
    fflush(stdout);
}
void validation_pmu_server(){
    printf("validation_pmu_server");
    fflush(stdout);
}
void response(){
    printf("response");
    fflush(stdout);
}


int main(int argc,char *argv[]) {

    GtkWidget *window;
    GtkWidget * pmu_server_window;

    gtk_init(&argc,&argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_show(window);
  
    g_signal_connect(window,G_CALLBACK(gtk_main_quit),NULL);

    pmu_server_window = gtk_dialog_new ();
    g_signal_connect (pmu_server_window,pmu_server_window);
    gtk_window_set_title (GTK_WINDOW (pmu_server_window),"PMU Server Setup");
    gtk_container_set_border_width (GTK_CONTAINER (pmu_server_window),10);

    GtkWidget *table,*label,*cancel_button;
    GtkWidget *valdbutton,*help_button;

    valdbutton = gtk_dialog_add_button((GtkDialog *)pmu_server_window,"Run",GTK_RESPONSE_OK); // gtk_button_new_with_label ("Run");
    help_button = gtk_dialog_add_button((GtkDialog *)pmu_server_window,"Help",GTK_RESPONSE_APPLY); // gtk_button_new_with_label ("Help");
    cancel_button = gtk_dialog_add_button((GtkDialog *)pmu_server_window,"Cancel",GTK_RESPONSE_CLOSE); //gtk_button_new_with_label ("Cancel");

    g_signal_connect_swapped (valdbutton,"clicked",G_CALLBACK (validation_pmu_server),valdbutton);
    g_signal_connect_swapped (help_button,G_CALLBACK (Pmu_Help),NULL);
    g_signal_connect_swapped (cancel_button,pmu_server_window);
    g_signal_connect_swapped (pmu_server_window,G_CALLBACK (response),pmu_server_window);
    //g_signal_connect_swapped (pmu_server_window,pmu_server_window);
    gtk_widget_show(pmu_server_window);

    gtk_main();

  return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。