天天看點

學習使用GTK+ 4.GTK+常用物件及API(視窗)

學習使用GTK+ 4.GTK+常用物件及API(視窗)

最後的葉子

學習使用GTK+ 系列的第 5 篇 (本系列共6篇) 學習使用GTK+

  • 學習使用GTK+ 0.概述
  • 學習使用GTK+ 1.建構GTK+編譯環境
  • 學習使用GTK+ 2.GTK+“Hello World”——對GTK+運作機制的通俗介紹
  • 學習使用GTK+ 3.使用GtkBuilder、界面設計器Glade和其他GTK+元件
  • 學習使用GTK+ 4.GTK+常用物件及API(視窗)
  • 學習使用GTK+ 5.GTK+常用物件及API(文本)

這一部分内容介紹有關GTK+常用視窗類物件的一些函數。如果對内容有疑問,請在下方留言,謝謝!

GTK+的視窗

視窗是GTK+最基本的物件之一,物件要被放在視窗裡顯示。GTK+裡,常用的視窗包括頂級視窗(GtkWindow)、對話框(GtkDialog)和消息對話框(GtkMessageDialog)等。

GTK+有關視窗的操作很多,絕大多數情況下可以滿足自定義視窗的需求;但有時候還是不可避免要直接通路底層庫GDK。要注意的 是,GdkWindow與GtkWindow有很大差異,GdkWindow指一個顯示區域,每一個可顯示的GTK+物件都對應一個GdkWindow, 閱讀文檔時兩者不可混淆。

視窗類物件在Glade中得到了良好的支援,複雜的視窗建議直接用Glade建立。

簡易消息對話框

消息對話框是最簡易的視窗,如果還在Glade中建立的話,很麻煩且會使Glade檔案變得更大。下面這些函數,可以快速建立一個視窗而不需要Glade。

void
 gtk_show_info(
gpointer window,
 const
 gchar*
 message,
 const
 gchar*
 title)


{


    GtkWidget *
dialog;


    dialog =
 gtk_message_dialog_new_with_markup(
window,


             GTK_DIALOG_DESTROY_WITH_PARENT,


             GTK_MESSAGE_INFO,


             GTK_BUTTONS_OK,


             message)
;


    gtk_window_set_title(
GTK_WINDOW(
dialog)
,
 title)
;


    gtk_dialog_run(
GTK_DIALOG(
dialog)
)
;


    gtk_widget_destroy(
GTK_WIDGET(
dialog)
)
;


}


 

void
 gtk_show_error(
gpointer window,
 const
 gchar*
 message,
 const
 gchar*
 title)


{


    GtkWidget *
dialog;


    dialog =
 gtk_message_dialog_new_with_markup(
window,


             GTK_DIALOG_DESTROY_WITH_PARENT,


             GTK_MESSAGE_ERROR,


             GTK_BUTTONS_OK,


             message)
;


    gtk_window_set_title(
GTK_WINDOW(
dialog)
,
 title)
;


    gtk_dialog_run(
GTK_DIALOG(
dialog)
)
;


    gtk_widget_destroy(
dialog)
;


}


 

gint gtk_show_question(
gpointer window,
 const
 gchar*
 message,
 const
 gchar*
 title)


{


    gint i;


    GtkWidget *
dialog;


 

    dialog =
 gtk_message_dialog_new_with_markup(
window,


             GTK_DIALOG_DESTROY_WITH_PARENT,


             GTK_MESSAGE_QUESTION,


             GTK_BUTTONS_YES_NO,


             message)
;


    gtk_window_set_title(
GTK_WINDOW(
dialog)
,
 title)
;


    i=
gtk_dialog_run(
GTK_DIALOG(
dialog)
)
;


    gtk_widget_destroy(
dialog)
;


 

    if
(
i==
GTK_RESPONSE_YES)


        return
 1
;


    else


        return
 0
;


}


 

void
 gtk_show_warning(
gpointer window,
 const
 gchar*
 message,
 const
 gchar*
 title)


{


    GtkWidget *
dialog;


    dialog =
 gtk_message_dialog_new_with_markup(
window,


             GTK_DIALOG_DESTROY_WITH_PARENT,


             GTK_MESSAGE_WARNING,


             GTK_BUTTONS_OK,


             message)
;


    gtk_window_set_title(
GTK_WINDOW(
dialog)
,
 title)
;


    gtk_dialog_run(
GTK_DIALOG(
dialog)
)
;


    gtk_widget_destroy(
dialog)
;


}
      

以上四個函數分别是一個資訊視窗、錯誤提示視窗、詢問視窗、警告視窗,三個參數分别是母視窗、視窗内文字内容、視窗标題。在程式中直接調用函數即可。

檔案選擇對話框

檔案選擇對話框同樣可以不用Glade建立,而直接調用API友善地建立。下面的函數可以建立檔案打開對話框和檔案儲存對話框。

GtkWidget*
 gtk_show_file_add_filter(
GtkWidget*
 dialog,
 const
 gchar *
description,
 gchar *
pattern)


{


	GtkWidget *
filter;


	filter=
GTK_WIDGET(
gtk_file_filter_new(
)
)
;


	gtk_file_filter_set_name(
GTK_FILE_FILTER(
filter)
,
description)
;


	gtk_file_filter_add_pattern(
GTK_FILE_FILTER(
filter)
,
pattern)
;


	gtk_file_chooser_add_filter(
GTK_FILE_CHOOSER(
dialog)
,
GTK_FILE_FILTER(
filter)
)
;


	return
 filter;


}


 

gchar*
 gtk_show_file_open(
GtkWidget*
 parent_window,
 const
 gchar *
title,
 const
 gchar *
filters)


{


    GtkWidget *
dialog,*
FF[
16
]
;


    gchar *
filename,
des[
256
]
,
pattern[
64
]
;


    long
 i,
j,
FFc=
0
;


 

    dialog =
 gtk_file_chooser_dialog_new (
title,


                                          GTK_WINDOW(
parent_window)
,


                                          GTK_FILE_CHOOSER_ACTION_OPEN,


                                          /*GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,*/


                                          GTK_STOCK_OPEN,
 GTK_RESPONSE_ACCEPT,


                                          NULL)
;


 

    //filters


	for
(
i=
0
;
i<
strlen(
filters)
;
i++
)


	{


		j=
0
;


		while
(
i<
strlen(
filters)
 &&
 filters[
i]
!=
'|'
)


			des[
j++
]
=
filters[
i++
]
;


		if
(
j>=
256
)
break
;


		des[
j]
=
0
;


		j=
0
;


		i++;


		if
(
i>=
strlen(
filters)
)
break
;


		while
(
i<
strlen(
filters)
 &&
 filters[
i]
!=
'|'
)


			pattern[
j++
]
=
filters[
i++
]
;


		if
(
j>=
64
)
break
;


		pattern[
j]
=
0
;


		FF[
FFc++
]
=
gtk_show_file_add_filter(
dialog,
des,
pattern)
;


		if
(
FFc>=
16
)
break
;


	}


 

    if
 (
gtk_dialog_run (
GTK_DIALOG (
dialog)
)
 ==
 GTK_RESPONSE_ACCEPT)


    {


        filename =
 gtk_file_chooser_get_filename (
GTK_FILE_CHOOSER (
dialog)
)
;


        gtk_object_destroy(
GTK_OBJECT(
dialog)
)
;


        return
 filename;


    }


 

    return
 NULL;


}


 

gchar*
 gtk_show_file_save(
GtkWidget*
 parent_window,
 const
 gchar *
title,
 const
 gchar *
default_folder,
 const
 gchar *
default_name,
 const
 gchar *
filters)


{


    GtkWidget *
dialog,*
FF[
16
]
;


    gchar *
filename,
des[
256
]
,
pattern[
64
]
;


    long
 i,
j,
FFc=
0
;


 

    dialog =
 gtk_file_chooser_dialog_new (
title,


                                          GTK_WINDOW(
parent_window)
,


                                          GTK_FILE_CHOOSER_ACTION_SAVE,


                                          /*GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,*/


                                          GTK_STOCK_SAVE,
 GTK_RESPONSE_ACCEPT,


                                          NULL)
;


    gtk_file_chooser_set_do_overwrite_confirmation (
GTK_FILE_CHOOSER (
dialog)
,
 TRUE)
;


    if
(
default_folder[
0
]
!=
0
)
gtk_file_chooser_set_current_folder (
GTK_FILE_CHOOSER (
dialog)
,
 default_folder)
;


    gtk_file_chooser_set_current_name (
GTK_FILE_CHOOSER (
dialog)
,
 default_name)
;


 

    //filters


	for
(
i=
0
;
i<
strlen(
filters)
;
i++
)


	{


		j=
0
;


		while
(
i<
strlen(
filters)
 &&
 filters[
i]
!=
'|'
)


			des[
j++
]
=
filters[
i++
]
;


		if
(
j>=
256
)
break
;


		des[
j]
=
0
;


		j=
0
;


		i++;


		if
(
i>=
strlen(
filters)
)
break
;


		while
(
i<
strlen(
filters)
 &&
 filters[
i]
!=
'|'
)


			pattern[
j++
]
=
filters[
i++
]
;


		if
(
j>=
64
)
break
;


		pattern[
j]
=
0
;


		FF[
FFc++
]
=
gtk_show_file_add_filter(
dialog,
des,
pattern)
;


		if
(
FFc>=
16
)
break
;


	}


 

    if
 (
gtk_dialog_run (
GTK_DIALOG (
dialog)
)
 ==
 GTK_RESPONSE_ACCEPT)


    {


        filename =
 gtk_file_chooser_get_filename (
GTK_FILE_CHOOSER (
dialog)
)
;


        gtk_widget_destroy (
dialog)
;


        return
 filename;


    }


 

    //destroy


    gtk_widget_destroy (
dialog)
;


    for
(
i=
0
;
i<
FFc;
i++
)


    	gtk_object_destroy(
GTK_OBJECT(
FF[
i]
)
)
;


 

    return
 NULL;


}
      

gtk_show_file_open()建立一個檔案打開視窗供使用者選擇檔案,參數依次是母視窗、标題、過濾器。

gtk_show_file_save()建立一個檔案儲存視窗供使用者選擇檔案,參數依次是母視窗、标題、預設檔案夾、預設檔案名、過濾器。

其中“過濾器”是一串字元,字元内用“|”分離,其形式像這樣:檔案類型名稱1|對應通配符1|檔案類型名稱2|對應通配符2|……

使用GDK函數

GTK+提供好了豐富的功能,但也有缺陷——某些常用功能無法直接使用,需要通路GDK庫。下面這個函數,用來确定視窗是不是處于全屏狀态。

gboolean gtk_window_is_fullscreen(
GtkWindow*
 window)


{


	return
 (
gdk_window_get_state(
gtk_widget_get_window(
GTK_WIDGET(
window)
)
)
 &
 GDK_WINDOW_STATE_FULLSCREEN)
 ==
 GDK_WINDOW_STATE_FULLSCREEN;


}
      

其他用法,請參閱GTK+參考。