The first starting point would be to read the
GTK reference
GTK+ Overview > Getting Started with GTK+ > Building applications
There you will find C examples with increasing complexity.
Beginning with GTK3 all examples use GtkApplication. To reduce complexity and in order to run my examples on GTK2 and GTK3 I don't use the recommended way with GtkApplication.
A simple example to display a window in PureBasic using only GTK functions:
Code: Select all
ProcedureC WindowCloseHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
gtk_main_quit_()
EndProcedure
gtk_init_(0, 0)
Window = gtk_window_new_(#GTK_WINDOW_TOPLEVEL)
If Window
gtk_window_set_default_size_(Window, 200, 110)
gtk_window_set_title_(Window, "API Window")
gtk_window_set_position_(Window, #GTK_WIN_POS_NONE)
gtk_window_move_(Window, 270, 100)
g_signal_connect_(Window, "delete-event", @WindowCloseHandler(), 0)
g_signal_connect_(Window, "destroy", @WindowCloseHandler(), 0)
gtk_widget_show_(Window)
gtk_main_()
EndIf
A simple example to display a Window and an image in PureBasic using only GTK functions:
Code: Select all
ProcedureC WindowCloseHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
gtk_main_quit_()
EndProcedure
If LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/Geebee2.bmp")
gtk_init_(0, 0)
Window = gtk_window_new_(#GTK_WINDOW_TOPLEVEL)
If Window
gtk_window_set_default_size_(Window, ImageWidth(0), ImageHeight(0))
gtk_window_set_title_(Window, "API")
gtk_window_set_position_(Window, #GTK_WIN_POS_NONE)
gtk_window_move_(Window, 100, 100)
Layout = gtk_layout_new_(0, 0)
gtk_container_add_(Window, Layout)
gtk_widget_show_(Layout)
gtk_layout_put_(Layout, gtk_image_new_from_pixbuf_(ImageID(0)), 0, 0)
gtk_widget_show_all_(Window)
g_signal_connect_(Window, "delete-event", @WindowCloseHandler(), 0)
g_signal_connect_(Window, "destroy", @WindowCloseHandler(), 0)
gtk_widget_show_(Window)
gtk_main_()
EndIf
EndIf
In order to create complex dialogs, you may use strings or files containing XML to describe the widgets. In this case you need the
GtkBuilder, an interface builder which interprets the XML UI. The following example uses XML definitions and GtkBuilder to display a window with a GtkButton. When clicking the button, a PureBasic MessageRequester will be displayed:
Code: Select all
; Converted from C source code:
; https://de.wikibooks.org/wiki/GTK_mit_Builder:_Builder
EnableExplicit
#GUI = "" +
~"<interface>" + #CR$ +
~" <object class=\"GtkWindow\" id=\"Window\">" + #CR$ +
~" <property name=\"title\">Demo</property>" + #CR$ +
~" <child>" + #CR$ +
~" <object class=\"GtkButton\" id=\"Button\">" + #CR$ +
~" <property name=\"label\">Click me!</property>" + #CR$ +
~" </object>" + #CR$ +
~" </child>" + #CR$ +
~" </object>" + #CR$ +
~"</interface>"
ImportC ""
gtk_builder_add_from_string(*GtkBuilder, Text.P-UTF8, TextLength.L,
*Error.GError)
gtk_builder_get_object(*GtkBuilder, ObjectName.P-UTF8)
gtk_builder_new()
EndImport
Define Button.I
Define *Error.GError
Define GtkBuilder.I
Define Window.I
ProcedureC WindowDestroyedCallback()
gtk_main_quit_()
EndProcedure
ProcedureC ButtonClickedCallback(*Widget.GtkWidget, *UserData)
MessageRequester("Info",
"Hello world!")
EndProcedure
; ----- Initialize GTK
gtk_init_(0, 0)
; ----- Load XML definition string
GtkBuilder = gtk_builder_new()
gtk_builder_add_from_string(GtkBuilder, #GUI, Len(#GUI), @*Error)
; ----- Get window from XML string
Window = gtk_builder_get_object(GtkBuilder, "Window")
; ----- Connect signal "destroy" to be able to quit GTK event loop
g_signal_connect_(Window, "destroy", @WindowDestroyedCallback(), 0)
; ----- Get button from XML string
Button = gtk_builder_get_object(GtkBuilder, "Button")
; ----- Connect signal "clicked" to button
g_signal_connect_(Button, "clicked", @ButtonClickedCallback(), 0)
; ----- Remove reference to GtkBuilder
g_object_unref_(GtkBuilder)
; ----- Display window defined in XML string
gtk_widget_show_all_(Window)
; ----- Move window to position x = 200 and y = 100
gtk_window_move_(Window, 200, 100)
; ----- Start GTK event loop
gtk_main_()
To ease the use of creating complex dialogs, you may try the user interface designer
Glade. For a simple example I have created a ComboBox with Glade. This is the generated XML which I have saved in my home folder as ComboBoxDemo.glade:
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkWindow" id="Window">
<property name="can_focus">False</property>
<property name="title" translatable="yes">ComboBox Demo</property>
<property name="default_width">220</property>
<property name="default_height">100</property>
<child>
<object class="GtkFixed" id="FixedFrame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkComboBox" id="ComboBox">
<property name="width_request">100</property>
<property name="height_request">30</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="x">60</property>
<property name="y">30</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
And this is the example displaying the window and ComboBox generated with Glade:
Code: Select all
; C example for creating a simple Window with Glade:
; https://prognotes.net/2015/06/gtk-3-c-program-using-glade-3/
; C example for adding entries to a GtkComboBox
; http://blog.borovsak.si/2009/04/as-promised-im-back-with-second-part-of.html
EnableExplicit
#G_TYPE_STRING = 16 << 2 ; = 64
#GladeFile = "ComboBoxDemo.glade"
ImportC ""
gtk_builder_get_object(*GtkBuilder, ObjectName.P-UTF8)
gtk_builder_new_from_file(Filename.P-UTF8)
EndImport
Define CellRenderer.I
Define ComboBox.I
Define GtkBuilder.I
Define i.I
Define ItemText.GValue
Define Iter.I
Define ListStore.I
Define Window.I
ProcedureC WindowDestroyedCallback()
gtk_main_quit_()
EndProcedure
; ----- Initialize GTK
gtk_init_(0, 0)
; ----- Load Glade definition file
If FileSize(#GladeFile) < 1
MessageRequester("Error",
"Unable to find Glade definition file!")
End
EndIf
GtkBuilder = gtk_builder_new_from_file(#GladeFile)
; ----- Get Window from Glade definition
Window = gtk_builder_get_object(GtkBuilder, "Window")
; ----- Get ComboBox from Glade definition
ComboBox = gtk_builder_get_object(GtkBuilder, "ComboBox")
; ----- Remove reference to GtkBuilder
g_object_unref_(GtkBuilder)
; ----- Create ListStore and fill it with ComboBox items
ListStore = gtk_list_store_new_(1, #G_TYPE_STRING)
ItemText\g_type = #G_TYPE_STRING
For i = 1 To 7
g_value_set_string_(@ItemText, "Item " + Str(i))
gtk_list_store_append_(ListStore, @Iter)
gtk_list_store_set_value_(ListStore, @Iter, 0, @ItemText)
Next i
; ----- Connect ComboBox with ListStore
gtk_combo_box_set_model_(ComboBox, ListStore)
; ----- Remove reference to ListStore
g_object_unref_(ListStore)
; ----- Create cell renderer and pack it into ComboBox
CellRenderer = gtk_cell_renderer_text_new_()
gtk_cell_layout_pack_start_(ComboBox, CellRenderer, #True)
; ----- Connect renderer to data source
gtk_cell_layout_add_attribute_(ComboBox, CellRenderer, "text", 0)
; ----- Display "Item 4" in ComboBox
gtk_combo_box_set_active_(ComboBox, 3)
; ----- Connect destroy signal to be able to quit GTK event loop
g_signal_connect_(Window, "destroy", @WindowDestroyedCallback(), 0)
; ----- Display window defined in Glade file
gtk_widget_show_(Window)
; ----- Move window to position x = 200 and y = 100
gtk_window_move_(Window, 200, 100)
; ----- Start GTK event loop
gtk_main_()
I have tested all examples successfully on Linux Mint 19.3 x64 'Tricia' with Cinnamon and PB 5.73 x64 with GTK2 and GTK3.