[英]Signal Handlers for Message Dialogs in GTK+ using Glade (and C)
我在弄清楚如何在C代碼中為在GLADE中創建的消息對話框編寫信號處理程序時遇到麻煩。 如果我不使用GLADE,則信號處理程序將包含必要的信息以構造消息對話框本身。 例如,“您確定要退出嗎?” 消息對話框的形式為:
void show_question(GtkWidget *widget, gpointer window) {
GtkWidget *dialog;
dialog = gtk_message_dialog_new(GTK_WINDOW(window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_YES_NO,
"Are you sure to quit?");
gtk_window_set_title(GTK_WINDOW(dialog), "Question");
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
同樣,“關於窗口”的格式為:
void show_about(GtkWidget *widget, gpointer data) {
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file("battery.png", NULL);
GtkWidget *dialog = gtk_about_dialog_new();
gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(dialog), "Battery");
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), "0.9");
gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog), "(c) Jan Bodnar");
gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog), "Battery is a simple tool for battery checking.");
gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog), "http://www.batteryhq.net");
gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), pixbuf);
g_object_unref(pixbuf), pixbuf = NULL;
gtk_dialog_run(GTK_DIALOG (dialog));
gtk_widget_destroy(dialog);
}
現在,我已經在GLADE中完全創建了這些窗口,現在我不確定信號處理程序應采用哪種形式(以C語言表示)以進行連接,例如,單擊“幫助”->“關於”到在GLADE中創建的about窗口,或單擊“文件”進行連接->使用在GLADE中創建的“確定要退出”消息對話框退出。 我對GTK +和Glade都是陌生的,而且似乎找不到解決此問題的有用方法。 任何幫助將不勝感激。
編輯:下面是一個示例林間空XML文件,其中包含兩個頂級窗口。 第一個是主窗口,帶有一個包含菜單欄的框。 第二個是關於對話框。 我正在尋找的是編寫信號處理程序的幫助,該處理程序在菜單欄中單擊文件->關於后將打開關於窗口。
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkMenuBar" id="menubar1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_File</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem1">
<property name="label">gtk-new</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem2">
<property name="label">gtk-open</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem3">
<property name="label">gtk-save</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem4">
<property name="label">gtk-save-as</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="separatormenuitem1">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem5">
<property name="label">gtk-quit</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Edit</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem6">
<property name="label">gtk-cut</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem7">
<property name="label">gtk-copy</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem8">
<property name="label">gtk-paste</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem9">
<property name="label">gtk-delete</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_View</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Help</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem10">
<property name="label">gtk-about</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkAboutDialog" id="window_about">
<property name="can_focus">False</property>
<property name="type_hint">dialog</property>
<property name="program_name">Glade</property>
<property name="logo_icon_name">image-missing</property>
<child internal-child="vbox">
<object class="GtkBox" id="aboutdialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="aboutdialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</interface>
如果理解正確,則不是通過編程方式創建對話框,而是要通過glade創建對話框。
通過使用林間空地,您必須使用GtkBuilder 。
假設您使用林間空地( yesno_dialog.ui )創建一個簡單的“是,否”對話框:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkDialog" id="dialog1">
<property name="can_focus">False</property>
<property name="modal">True</property>
<property name="default_width">275</property>
<property name="default_height">130</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="layout_style">spread</property>
<child>
<object class="GtkButton" id="button1">
<property name="label">gtk-yes</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button2">
<property name="label">gtk-no</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="label" translatable="yes">Are you sure to quit?</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="1">button1</action-widget>
<action-widget response="2">button2</action-widget>
</action-widgets>
<child>
<placeholder/>
</child>
</object>
</interface>
看起來應該像這樣:
請注意response_id為1,以供以后參考。
讓我們用按鈕測試一個簡單的窗口,該按鈕將通過其單擊的信號處理程序/回調觸發對話框:
#include <gtk/gtk.h>
void on_button_clicked (GtkButton *button, gpointer user_data) {
int response;
GtkWidget *dialog;
GtkBuilder *builder;
g_return_if_fail (user_data != NULL);
builder = gtk_builder_new_from_file("yesno_dialog.ui");
dialog = GTK_WIDGET(gtk_builder_get_object (builder, "dialog1"));
gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(user_data));
gtk_widget_show_all(dialog);
response = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
g_object_unref(G_OBJECT(builder));
g_print ("Response is %s\n", response == 1 ? "Yes" : "No");
}
int main(int argc, char *argv[]) {
GtkWidget *button;
GtkWidget *window;
gtk_init(&argc,&argv);
button = gtk_button_new_with_label("Press for dialog");
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_add(GTK_CONTAINER(window), button);
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_button_clicked), window);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
當您使用標准響應ID以編程方式構造對話框時,可以使用預定義的枚舉器檢查響應。 使用glade,即使我們已經定義了Stock按鈕,也必須定義(用戶定義的)響應ID,以便gtk_dialog_run函數可以理解用戶已選擇了響應。
編譯:
gcc -o dialog main.c `pkg-config --cflags --libs gtk+-3.0`
應導致類似於以下內容:
與@Jose Fonte討論后,我的問題的解決方案如下:
// Signal Handler for Clicking File -> Quit
void file_quit_clicked (__attribute__((unused)) GtkMenuItem *item, gpointer user_data)
{
GtkBuilder *builder = (GtkBuilder *) user_data;
GtkDialog *dialog = GTK_DIALOG(gtk_builder_get_object(builder, "quit_dialog"));
gtk_widget_show_all(GTK_WIDGET(dialog));
// This switch statement and gtk_widget_hide is needed so that the dialog window can be closed
// and reopened again without causing errors (i.e. if the user clicks "no" when asked "are you
// sure you want to quit." Without these, the window errors out the second time opened.
gint result = gtk_dialog_run (dialog);
switch (result)
{
case GTK_RESPONSE_ACCEPT:
// do_application_specific_something (); - Nothing Required
break;
default:
// do_nothing_since_dialog_was_cancelled (); - Nothing Required
break;
}
gtk_widget_hide(GTK_WIDGET(dialog));
}
將以下代碼段插入到main函數中:
// So the "Are you sure you want to quit?" Dialog Box is hidden after clicking "x"
GtkDialog *quit_dialog = GTK_DIALOG(gtk_builder_get_object(builder, "quit_dialog"));
gtk_widget_hide_on_delete (GTK_WIDGET(quit_dialog));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.