Проблема с обработкой сигнала GtkNoteBook

Я создал один виджет GTK+ для ноутбука и пытаюсь установить обратные вызовы для некоторых событий следующим образом:

m_notebook = gtk_notebook_new();
g_signal_connect( GTK_OBJECT(m_notebook), "move-focus-out", G_CALLBACK( on_notebook_move_focus_out ), NULL );
g_signal_connect( GTK_OBJECT(m_notebook), "focus-tab", G_CALLBACK( on_notebook_focus_tab ), NULL );
g_signal_connect( GTK_OBJECT(m_notebook), "change-current-page", G_CALLBACK( on_notebook_change_current_page ), NULL );
gtk_container_add(GTK_CONTAINER (m_window), m_notebook);

А это прототипы функций обратного вызова:

G_MODULE_EXPORT gboolean on_notebook_move_focus_out( GtkNotebook *notebook, GtkNotebookTab arg1, gpointer user_data );
G_MODULE_EXPORT gboolean on_notebook_focus_tab( GtkNotebook *notebook, GtkNotebookTab arg1, gpointer user_data );
G_MODULE_EXPORT gboolean on_notebook_change_current_page( GtkNotebook *notebook, gint arg1, gpointer user_data );

Я добавляю страницы в блокнот во время выполнения, используя этот вызов функции:

gtk_notebook_append_page( GTK_NOTEBOOK(m_notebook), msg_vbox, label );

Но я не получаю ни одного из вышеперечисленных событий. Что я делаю неправильно?

Соответствующий код выглядит следующим образом:

    /*
 * Compile me with:

 gcc -o notebook notebook.c $(pkg-config --cflags --libs gtk+-2.0 gmodule-2.0)
*/

#include <gtk/gtk.h>

static gboolean on_m_notebook_move_focus_out( GtkNotebook *notebook, GtkDirectionType arg1, gpointer user_data );
static gboolean on_m_notebook_focus_tab( GtkNotebook *notebook, GtkNotebookTab arg1, gpointer user_data );
static gboolean on_m_notebook_change_current_page( GtkNotebook *notebook, gint arg1, gpointer user_data );

int main (int argc, char *argv[])
{
    GtkWidget *m_window;
    GtkWidget *m_notebook;

    gtk_init (&argc, &argv);

    m_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position(GTK_WINDOW(m_window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(m_window), 350, 500);

    m_notebook = gtk_notebook_new();
    g_signal_connect( GTK_OBJECT(m_notebook), "move-focus-out", G_CALLBACK( on_m_notebook_move_focus_out ), NULL );
    g_signal_connect( GTK_OBJECT(m_notebook), "focus-tab", G_CALLBACK( on_m_notebook_focus_tab ), NULL );
    g_signal_connect( GTK_OBJECT(m_notebook), "change-current-page", G_CALLBACK( on_m_notebook_change_current_page ), NULL );

    gtk_container_add(GTK_CONTAINER (m_window), m_notebook);

    GtkWidget *button;

    button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
    gtk_notebook_append_page(GTK_NOTEBOOK(m_notebook), button, NULL);

    button = gtk_button_new_from_stock (GTK_STOCK_ADD);
    gtk_notebook_append_page(GTK_NOTEBOOK(m_notebook), button, NULL);

    button = gtk_button_new_from_stock (GTK_STOCK_DELETE);
    gtk_notebook_append_page(GTK_NOTEBOOK(m_notebook), button, NULL);

    button = gtk_button_new_from_stock (GTK_STOCK_DIALOG_INFO);
    gtk_notebook_append_page(GTK_NOTEBOOK(m_notebook), button, NULL);

    gtk_widget_show_all( m_window );

    gtk_main ();
    return 0;
}

gboolean on_m_notebook_move_focus_out( GtkNotebook *notebook, GtkDirectionType arg1, gpointer user_data )
{
    printf("on_m_notebook_move_focus_out\n");
    return FALSE;
}

gboolean on_m_notebook_focus_tab( GtkNotebook *notebook, GtkNotebookTab arg1, gpointer user_data )
{
    printf("on_m_notebook_focus_tab []\n");
    return FALSE;
}

gboolean on_m_notebook_change_current_page( GtkNotebook *notebook, gint arg1, gpointer user_data )
{
    printf("on_m_notebook_change_current_page\n");
    return FALSE;
}

c gtk
person kbalar    schedule 23.11.2009    source источник


Ответы (2)


Вы подключаетесь к неправильным сигналам. Те, которые вы используете, являются сигналами привязки клавиш. Они испускаются, когда вы нажимаете клавиши на клавиатуре, которые перемещают фокус, фокусируют вкладку или изменяют текущую страницу — например, Page Up, Page Down и т. д. К сожалению, вы действительно не могли знать об этом, потому что эти сигналы не задокументированы в документации GTK.

Вместо change-current-page используйте switch-page. И вместо сигналов фокусировки подключитесь к различным сигналам фокусировки GtkWidget.

person ptomato    schedule 24.11.2009
comment
Да, я могу запустить сигнал переключения страницы. - person kbalar; 25.11.2009

Обычно страницы после добавления невидимы, поэтому блокнот не реагирует. Попробуйте также вызвать gtk_widget_show_all(GTK_WIDGET(msg_vbox)), чтобы сделать его видимым, и посмотрите, вызовет ли это какие-либо события.

ОБНОВЛЕНИЕ: когда вы добавляете новые страницы, если текущий фокус блокнота на самом деле не меняется так, чтобы отображалась новая страница, я бы не ожидал, что она будет излучать упомянутые вами сигналы. Конечно, вы можете заставить его показать только что добавленную страницу, вызвав gtk_notebook_set_current_page(). Номер страницы возвращается gtk_notebook_append_page() и друзьями.

ОБНОВЛЕНИЕ 2: это второстепенная проблема, но вы должны приводить свои объекты, используя G_OBJECT(), а не GTK_OBJECT(), поскольку функция g_signal_connect() — это функция glib, которая действует на объекты GObject.

person unwind    schedule 23.11.2009
comment
Здесь страницы видны после добавления. Добавлен вызов функции gtk_widget_show_all(GTK_WIDGET(msg_vbox)). Это не помогает запускать события. - person kbalar; 23.11.2009
comment
Я не получил никаких предупреждений, изменив имена сигналов. Пока я не могу инициировать события. - person kbalar; 23.11.2009
comment
Дефисы и подчеркивания не имеют значения, если вы не смешиваете их в одном имени сигнала. - person ptomato; 24.11.2009
comment
@ptomato: Спасибо, я никогда не знал. Тогда я удалю эту часть своего ответа, так как это не имеет значения. - person unwind; 24.11.2009
comment
Приведение к G_OBJECT() не помогает. Я могу активировать сигнал переключения страниц. - person kbalar; 25.11.2009