GTK+ 2.0 教學-顏色選擇 Color Selection

顏色選擇(color selection)元件是一個用來互動式地選擇顏色的元件。這個組合元件讓用戶通過操縱RGB值(紅綠藍)和HSV值(色度、飽和度、純度)來選擇顏色。這是通過調整滾軸(sliders)的值或者文字輸入元件的值,或者從一個色度/飽和度/純度條上選擇相應的顏色來實現的。你還可以通過它來設置顏色的不透明度(opacity)。

目前,顏色選擇元件只能引發一種信號: color_changed。它是在元件裡的顏色值發生變化時,或者通過 gtk_color_selection_set_color() 函式顯示設置元件的顏色值時引發。

現在可以看一下顏色選擇元件能夠為我們提供一些什麼。這個元件有兩種風格:GtkColorSelection 和 GtkColorSelectionDialog。

GtkWidget *gtk_color_selection_new( void );

你可能不能直接使用這個函式。它創建一個孤立的顏色選擇元件,並需要將其放在某個視窗上。顏色選擇元件是從VBox元件衍生的。

GtkWidget *gtk_color_selection_dialog_new( const gchar *title );

這是最常用的顏色選擇元件的構建函式,它創建一個顏色選擇對話框。它內部有一個框架元件,框架元件中包含了一個顏色選擇元件、一個垂直分隔線元件、一個包含 了Ok、Cancel、Help三個按鈕的橫向盒(HBox)。你可以透過存取顏色選擇對話框元件結構中的”ok_button”、”cancel_button”和”help_button”元件來存取它們(例如:GTK_COLOR_SELECTION_DIALOG (colorseldialog)->ok_button))。

void gtk_color_selection_set_has_opacity_control( GtkColorSelection *colorsel,
                                                  gboolean           has_opacity );

顏色選擇元件支持調整顏色的不透明度(一般也稱為alpha通道),預設是被停用的。呼叫下面的函式,將has_opacity設置為TRUE啟用該特性。同樣,has_opacity 設置為 FALSE 時將停用此特性。

void gtk_color_selection_set_current_color( GtkColorSelection *colorsel,
                                            GdkColor          *color );

void gtk_color_selection_set_current_alpha( GtkColorSelection *colorsel,
                                            guint16            alpha );

可以呼叫帶有一個指標的 gtk_color_selection_set_current_color() 函式明確地設置顏色選擇元件的目前顏色,其中的color參數是一個指向GdkColor的指標。 gtk_color_selection_set_current_alpha()用來設置不透明度(alpha通道),其中的alpha值應該在0(完全透明)和65636(完全不透明)之間。

void gtk_color_selection_get_current_color( GtkColorSelection *colorsel,
	                                    GdkColor *color );

void gtk_color_selection_get_current_alpha( GtkColorSelection *colorsel,
                                            guint16           *alpha );

當需要查詢目前的顏色值時,一般情況是接收到一個 “color_changed” 信號時,使用這些函式。

下面是一個簡單的範例,它說明了如何使用顏色選擇對話框元件,這個程式顯示了一個包含繪圖區的視窗,點擊它會打開一個顏色選擇對話框,改變顏色選擇對話框中的顏色,會改變繪圖區的背景色。

#include <glib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>

GtkWidget *colorseldlg = NULL;
GtkWidget *drawingarea = NULL;
GdkColor color;

/* 顏色改變信號的處理函式 */

void color_changed_cb( GtkWidget         *widget,
                       GtkColorSelection *colorsel )
{
  GdkColor ncolor;

  gtk_color_selection_get_current_color (colorsel, &ncolor);
  gtk_widget_modify_bg (drawingarea, GTK_STATE_NORMAL, &ncolor);
}

/* 繪圖區事件處理函式 */

static gboolean area_event( GtkWidget *widget,
                            GdkEvent  *event,
                            gpointer   client_data )
{
  gint handled = FALSE;
  gint response;
  GtkColorSelection *colorsel;

/* 檢查是否接收到一個滑鼠按鍵按下事件 */
if (event->type == GDK_BUTTON_PRESS)

{

handled = TRUE;
/* 創建顏色選擇對話框 */

if (colorseldlg == NULL)

colorseldlg = gtk_color_selection_dialog_new ("Select background color");
/* 獲取顏色選擇元件 */

colorsel = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (colorseldlg)->colorsel);
gtk_color_selection_set_previous_color (colorsel, &color);

gtk_color_selection_set_current_color (colorsel, &color);

gtk_color_selection_set_has_palette (colorsel, TRUE);

    /* Connect to the "color_changed" signal, set the client-data
       * to the colorsel widget */
      g_signal_connect (colorsel, "color_changed",
                        G_CALLBACK (color_changed_cb), (gpointer) colorsel);

/* 顯示對話框 */

response = gtk_dialog_run (GTK_DIALOG (colorseldlg));
if (response == GTK_RESPONSE_OK)

gtk_color_selection_get_current_color (colorsel, &color);

else

gtk_widget_modify_bg (drawingarea, GTK_STATE_NORMAL, &color);
gtk_widget_hide (colorseldlg);

}
return handled;

}
/* 關閉、退出的事件處理函式 */

static gboolean destroy_window( GtkWidget *widget,
                                GdkEvent  *event,
                                gpointer   client_data )
{
  gtk_main_quit ();
  return TRUE;
}

/* 主函式 */
gint main( gint argc,

gchar *argv[] )

{

GtkWidget *window;
/* 初始化,處理並刪去跟 gtk 有關的命令參數 */
gtk_init (&argc, &argv);
/* 創建頂級視窗,設置標題,以及視窗是否可縮放 */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

gtk_window_set_title (GTK_WINDOW (window), "Color selection test");

gtk_window_set_resizable ((GTK_WINDOW (window), TRUE);
/* 為 "delete" 和 "destroy" 事件設置回呼函式以便退出 */

g_signal_connect (window, "delete-event",

                    G_CALLBACK (destroy_window), (gpointer) window);

/* 創建繪圖區,設置尺寸,捕獲滑鼠按鍵事件 */
drawingarea = gtk_drawing_area_new ();
color.red = 0;

color.blue = 65535;

color.green = 0;

gtk_widget_modify_bg (drawingarea, GTK_STATE_NORMAL, &color);
gtk_widget_set_size_request (GTK_WIDGET (drawingarea), 200, 200);
gtk_widget_set_events (drawingarea, GDK_BUTTON_PRESS_MASK);

g_signal_connect (GTK_OBJECT (drawingarea), "event",

	            G_CALLBACK (area_event), (gpointer) drawingarea);

/* 將繪圖區添加到視窗中,然後顯示它們 */
gtk_container_add (GTK_CONTAINER (window), drawingarea);
gtk_widget_show (drawingarea);

gtk_widget_show (window);
/* 進入gtk主循環(這個函式從不會返回) */
gtk_main ();
/* 滿足性情暴躁的編譯器 */
return 0;

}

感謝你看到這裡,很快就可以離開了,但最好的獎勵行動就是按一下幫我分享或留言,感恩喔~

點我分享到Facebook

3 則留言


  1. 大大您好,參考您的src我可以操作透明度,但是透明度卻無法改變在背景底色中,似乎Gdkcolor沒辦法操作透明度,請問大大任何建議嗎?謝謝

    1. Author

      不太懂你的敘述,你的意思是要背景可以透明嗎?

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *