延續基礎視窗範例,本文展示富文本標籤 (Pango Markup)、delete-event 與 destroy 信號的區別、以及如何在回調中獲取元件數據。
#include
static void destroy_cb(GtkWidget *widget, gpointer data) {
GtkLabel *label = GTK_LABEL(data);
g_print("Label text: %s\n", gtk_label_get_text(label));
gtk_main_quit();
}
static gboolean delete_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
g_print("delete-event received\n");
return FALSE; // FALSE 繼續傳播,最終觸發 destroy
}
int main(int argc, char *argv[]) {
GtkWidget *window, *label;
char *markup, *str = "hello, world";
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "你好");
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
gtk_window_set_default_size(GTK_WINDOW(window), 130, 150);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
label = gtk_label_new(NULL);
markup = g_markup_printf_escaped("%s", str);
gtk_label_set_markup(GTK_LABEL(label), markup);
gtk_label_set_selectable(GTK_LABEL(label), TRUE); // 允許選中複製
// 連接 destroy 信號,傳遞 label 作為用戶數據
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy_cb), label);
g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(delete_event_cb), NULL);
gtk_container_add(GTK_CONTAINER(window), label);
gtk_widget_show_all(window);
gtk_main();
g_free(markup);
return 0;
}
g_markup_printf_escaped():安全格式化標記字符串,自動轉義特殊字符。size (xx-small ~ xx-large)、foreground/background、weight (bold)、style (italic)、underline 等。gtk_label_set_selectable():讓用戶可用滑鼠選中複製標籤文字。delete-event vs destroy| 信號 | 觸發時機 | 回調返回值 | 典型用途 |
|---|---|---|---|
delete-event | 用戶點擊關閉按鈕、Alt+F4 等請求關閉視窗 | TRUE:阻止關閉;FALSE:繼續傳播 | 攔截關閉、彈出確認對話框 |
destroy | 視窗實際銷毀前 (若 delete-event 返回 FALSE) | 無返回值 | 釋放資源、退出主循環 |