2022-04-21 16:53:28 +02:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "utf-8" / >
< meta name = "generator" content = "pandoc" / >
< meta name = "viewport" content = "width=device-width, initial-scale=1" / >
< link href = "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel = "stylesheet" integrity = "sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin = "anonymous" >
2022-12-21 14:31:33 +01:00
< title > GTK 4 tutorial< / title >
2022-04-21 16:53:28 +02:00
< style >
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
pre{overflow: visible;}
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
2022-04-17 13:54:42 +02:00
}
2022-04-21 16:53:28 +02:00
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::after
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
th {padding: 2px 6px; border: 1px solid; background-color: ghostwhite;}
td {padding: 2px 6px; border: 1px solid;}
img {display: block; margin-left: auto; margin-right: auto;}
figcaption {text-align: center;}
< / style >
< / head >
< body style = "padding-top: 70px;" >
< div class = "container" >
< nav class = "navbar fixed-top navbar-expand-lg navbar-dark bg-primary" >
< div class = "container-fluid" >
< span class = "navbar-brand" > Gtk4 tutorial< / span >
< button class = "navbar-toggler" type = "button" data-bs-toggle = "collapse" data-bs-target = "#navbarSupportedContent" aria-controls = "navbarSupportedContent" aria-expanded = "false" aria-label = "Toggle navigation" >
< span class = "navbar-toggler-icon" > < / span >
< / button >
< div class = "collapse navbar-collapse" id = "navbarSupportedContent" >
< ul class = "navbar-nav me-auto mb-2 mb-lg-0" >
< li class = "nav-item" >
< a class = "nav-link" href = "index.html" > Home< / a >
< / li >
< li class = "nav-item" >
< a class = "nav-link" href = "sec6.html" > Prev: section6< / a >
< / li >
< li class = "nav-item" >
< a class = "nav-link" href = "sec8.html" > Next: section8< / a >
< / li >
< / ul >
< / div >
< / div >
< / nav >
2022-04-17 13:54:42 +02:00
< h1 id = "widgets-3" > Widgets (3)< / h1 >
< h2 id = "open-signal" > Open signal< / h2 >
2022-12-21 14:31:33 +01:00
< h3 id = "g_application_handles_open-flag" > G_APPLICATION_HANDLES_OPEN
flag< / h3 >
< p > We made a very simple editor in the previous section with
GtkTextView, GtkTextBuffer and GtkScrolledWindow. We will add
file-reading ability to the program and improve it to a file viewer.< / p >
< p > The easiest way to give a filename is to use a command line
argument.< / p >
2022-04-17 13:54:42 +02:00
< pre > < code > $ ./a.out filename< / code > < / pre >
2022-12-21 14:31:33 +01:00
< p > The program will open the file and insert its contents into the
GtkTextBuffer.< / p >
< p > To do this, we need to know how GtkApplication (or GApplication)
recognizes arguments. This is described in the < a
href="https://docs.gtk.org/gio/class.Application.html">GIO API Reference
– Application< / a > .< / p >
< p > When GtkApplication is created, a flag (GApplicationFlags) is given
as an argument.< / p >
< div class = "sourceCode" id = "cb2" > < pre class = "sourceCode c" > < code class = "sourceCode c" > < span id = "cb2-1" > < a href = "#cb2-1" aria-hidden = "true" tabindex = "-1" > < / a > GtkApplication < span class = "op" > *< / span > < / span >
< span id = "cb2-2" > < a href = "#cb2-2" aria-hidden = "true" tabindex = "-1" > < / a > gtk_application_new < span class = "op" > (< / span > < span class = "dt" > const< / span > gchar < span class = "op" > *< / span > application_id< span class = "op" > ,< / span > GApplicationFlags flags< span class = "op" > );< / span > < / span > < / code > < / pre > < / div >
< p > This tutorial explains only two flags,
< code > G_APPLICATION_DEFAULT_FLAGS< / code > and
< code > G_APPLICATION_HANDLES_OPEN< / code > .
(< code > G_APPLICATION_FLAGS_NONE< / code > was used instead of
< code > G_APPLICATION_DEFAULT_FLAGS< / code > before GIO version2.73.3 (GLib
2.73.3 5/Aug/2022). Some GTK 4 applications still use
< code > G_APPLICATION_FLAGS_NONE< / code > . But now it is deprecated and
< code > G_APPLICATION_DEFAULT_FLAGS< / code > is recommended.) If you want to
handle command line arguments, the
< code > G_APPLICATION_HANDLES_COMMAND_LINE< / code > flag is what you
need.< / p >
< p > For further information, see < a
href="https://docs.gtk.org/gio/flags.ApplicationFlags.html">GIO API
Reference – ApplicationFlags< / a > and < a
href="https://docs.gtk.org/gio/method.Application.run.html">GIO API
Reference – g_application_run< / a > .< / p >
< p > We’ ve already used < code > G_APPLICATION_DEFAULT_FLAGS< / code > , as it is
the simplest option, and no command line arguments are allowed. If you
give arguments, an error will occur.< / p >
< p > The flag < code > G_APPLICATION_HANDLES_OPEN< / code > is the second
simplest option. It allows arguments but only files. The application
assumes all the arguments are filenames.< / p >
< div class = "sourceCode" id = "cb3" > < pre class = "sourceCode c" > < code class = "sourceCode c" > < span id = "cb3-1" > < a href = "#cb3-1" aria-hidden = "true" tabindex = "-1" > < / a > app < span class = "op" > =< / span > gtk_application_new < span class = "op" > (< / span > < span class = "st" > " com.github.ToshioCP.tfv3" < / span > < span class = "op" > ,< / span > G_APPLICATION_HANDLES_OPEN< span class = "op" > );< / span > < / span > < / code > < / pre > < / div >
2022-04-17 13:54:42 +02:00
< h3 id = "open-signal-1" > open signal< / h3 >
2022-12-21 14:31:33 +01:00
< p > When < code > G_APPLICATION_HANDLES_OPEN< / code > flag is given to the
application, two signals are available.< / p >
2022-04-17 13:54:42 +02:00
< ul >
2022-12-21 14:31:33 +01:00
< li > activate signal — This signal is emitted when there’ s no
argument.< / li >
< li > open signal — This signal is emitted when there is at least one
argument.< / li >
2022-04-17 13:54:42 +02:00
< / ul >
< p > The handler of the “open” signal is defined as follows.< / p >
2022-12-21 14:31:33 +01:00
< div class = "sourceCode" id = "cb4" > < pre class = "sourceCode c" > < code class = "sourceCode c" > < span id = "cb4-1" > < a href = "#cb4-1" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "dt" > void< / span > < / span >
< span id = "cb4-2" > < a href = "#cb4-2" aria-hidden = "true" tabindex = "-1" > < / a > open < span class = "op" > (< / span > < / span >
< span id = "cb4-3" > < a href = "#cb4-3" aria-hidden = "true" tabindex = "-1" > < / a > GApplication< span class = "op" > *< / span > self< span class = "op" > ,< / span > < / span >
< span id = "cb4-4" > < a href = "#cb4-4" aria-hidden = "true" tabindex = "-1" > < / a > gpointer files< span class = "op" > ,< / span > < / span >
< span id = "cb4-5" > < a href = "#cb4-5" aria-hidden = "true" tabindex = "-1" > < / a > gint n_files< span class = "op" > ,< / span > < / span >
< span id = "cb4-6" > < a href = "#cb4-6" aria-hidden = "true" tabindex = "-1" > < / a > gchar< span class = "op" > *< / span > hint< span class = "op" > ,< / span > < / span >
< span id = "cb4-7" > < a href = "#cb4-7" aria-hidden = "true" tabindex = "-1" > < / a > gpointer user_data< / span >
< span id = "cb4-8" > < a href = "#cb4-8" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "op" > )< / span > < / span > < / code > < / pre > < / div >
2022-04-17 13:54:42 +02:00
< p > The parameters are:< / p >
< ul >
2022-12-21 14:31:33 +01:00
< li > < code > self< / code > — the application instance (usually
GtkApplication)< / li >
< li > < code > files< / code > — an array of GFiles. [array length=n_files]
[element-type GFile]< / li >
< li > < code > n_files< / code > — the number of the elements of
< code > files< / code > < / li >
< li > < code > hint< / code > — a hint provided by the calling instance (usually
it can be ignored)< / li >
< li > < code > user_data< / code > — user data set when the signal handler was
connected.< / li >
2022-04-17 13:54:42 +02:00
< / ul >
< h2 id = "making-a-file-viewer" > Making a file viewer< / h2 >
< h3 id = "what-is-a-file-viewer" > What is a file viewer?< / h3 >
2022-12-21 14:31:33 +01:00
< p > A file viewer is a program that displays text files. Our file viewer
will work as follows.< / p >
2022-04-17 13:54:42 +02:00
< ul >
2022-12-21 14:31:33 +01:00
< li > When arguments are given, it recognizes the first argument as a
filename and opens it.< / li >
< li > The second argument and after are ignored.< / li >
< li > If there’ s no argument, it shows an error message and quit.< / li >
< li > If it successfully opens the file, it reads the contents of the
file, inserts them to GtkTextBuffer and shows the window.< / li >
< li > If it fails to open the file, it shows an error message and
quit.< / li >
2022-04-17 13:54:42 +02:00
< / ul >
2022-12-21 14:31:33 +01:00
< p > The program is shown below.< / p >
< div class = "sourceCode" id = "cb5" > < pre
class="sourceCode numberSource C numberLines">< code class = "sourceCode c" > < span id = "cb5-1" > < a href = "#cb5-1" > < / a > < span class = "pp" > #include < / span > < span class = "im" > < gtk/gtk.h> < / span > < / span >
< span id = "cb5-2" > < a href = "#cb5-2" > < / a > < / span >
< span id = "cb5-3" > < a href = "#cb5-3" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
< span id = "cb5-4" > < a href = "#cb5-4" > < / a > app_activate < span class = "op" > (< / span > GApplication < span class = "op" > *< / span > app< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb5-5" > < a href = "#cb5-5" > < / a > g_printerr < span class = "op" > (< / span > < span class = "st" > " You need a filename argument.< / span > < span class = "sc" > \n< / span > < span class = "st" > " < / span > < span class = "op" > );< / span > < / span >
< span id = "cb5-6" > < a href = "#cb5-6" > < / a > < span class = "op" > }< / span > < / span >
< span id = "cb5-7" > < a href = "#cb5-7" > < / a > < / span >
< span id = "cb5-8" > < a href = "#cb5-8" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
< span id = "cb5-9" > < a href = "#cb5-9" > < / a > app_open < span class = "op" > (< / span > GApplication < span class = "op" > *< / span > app< span class = "op" > ,< / span > GFile < span class = "op" > **< / span > files< span class = "op" > ,< / span > < span class = "dt" > int< / span > n_files< span class = "op" > ,< / span > < span class = "dt" > char< / span > < span class = "op" > *< / span > hint< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb5-10" > < a href = "#cb5-10" > < / a > GtkWidget < span class = "op" > *< / span > win< span class = "op" > ;< / span > < / span >
< span id = "cb5-11" > < a href = "#cb5-11" > < / a > GtkWidget < span class = "op" > *< / span > scr< span class = "op" > ;< / span > < / span >
< span id = "cb5-12" > < a href = "#cb5-12" > < / a > GtkWidget < span class = "op" > *< / span > tv< span class = "op" > ;< / span > < / span >
< span id = "cb5-13" > < a href = "#cb5-13" > < / a > GtkTextBuffer < span class = "op" > *< / span > tb< span class = "op" > ;< / span > < / span >
< span id = "cb5-14" > < a href = "#cb5-14" > < / a > < span class = "dt" > char< / span > < span class = "op" > *< / span > contents< span class = "op" > ;< / span > < / span >
< span id = "cb5-15" > < a href = "#cb5-15" > < / a > gsize length< span class = "op" > ;< / span > < / span >
< span id = "cb5-16" > < a href = "#cb5-16" > < / a > < span class = "dt" > char< / span > < span class = "op" > *< / span > filename< span class = "op" > ;< / span > < / span >
< span id = "cb5-17" > < a href = "#cb5-17" > < / a > < / span >
< span id = "cb5-18" > < a href = "#cb5-18" > < / a > win < span class = "op" > =< / span > gtk_application_window_new < span class = "op" > (< / span > GTK_APPLICATION < span class = "op" > (< / span > app< span class = "op" > ));< / span > < / span >
< span id = "cb5-19" > < a href = "#cb5-19" > < / a > gtk_window_set_default_size < span class = "op" > (< / span > GTK_WINDOW < span class = "op" > (< / span > win< span class = "op" > ),< / span > < span class = "dv" > 400< / span > < span class = "op" > ,< / span > < span class = "dv" > 300< / span > < span class = "op" > );< / span > < / span >
< span id = "cb5-20" > < a href = "#cb5-20" > < / a > < / span >
< span id = "cb5-21" > < a href = "#cb5-21" > < / a > scr < span class = "op" > =< / span > gtk_scrolled_window_new < span class = "op" > ();< / span > < / span >
< span id = "cb5-22" > < a href = "#cb5-22" > < / a > gtk_window_set_child < span class = "op" > (< / span > GTK_WINDOW < span class = "op" > (< / span > win< span class = "op" > ),< / span > scr< span class = "op" > );< / span > < / span >
< span id = "cb5-23" > < a href = "#cb5-23" > < / a > < / span >
< span id = "cb5-24" > < a href = "#cb5-24" > < / a > tv < span class = "op" > =< / span > gtk_text_view_new < span class = "op" > ();< / span > < / span >
< span id = "cb5-25" > < a href = "#cb5-25" > < / a > tb < span class = "op" > =< / span > gtk_text_view_get_buffer < span class = "op" > (< / span > GTK_TEXT_VIEW < span class = "op" > (< / span > tv< span class = "op" > ));< / span > < / span >
< span id = "cb5-26" > < a href = "#cb5-26" > < / a > gtk_text_view_set_wrap_mode < span class = "op" > (< / span > GTK_TEXT_VIEW < span class = "op" > (< / span > tv< span class = "op" > ),< / span > GTK_WRAP_WORD_CHAR< span class = "op" > );< / span > < / span >
< span id = "cb5-27" > < a href = "#cb5-27" > < / a > gtk_text_view_set_editable < span class = "op" > (< / span > GTK_TEXT_VIEW < span class = "op" > (< / span > tv< span class = "op" > ),< / span > FALSE< span class = "op" > );< / span > < / span >
< span id = "cb5-28" > < a href = "#cb5-28" > < / a > gtk_scrolled_window_set_child < span class = "op" > (< / span > GTK_SCROLLED_WINDOW < span class = "op" > (< / span > scr< span class = "op" > ),< / span > tv< span class = "op" > );< / span > < / span >
< span id = "cb5-29" > < a href = "#cb5-29" > < / a > < / span >
< span id = "cb5-30" > < a href = "#cb5-30" > < / a > < span class = "cf" > if< / span > < span class = "op" > (< / span > g_file_load_contents < span class = "op" > (< / span > files< span class = "op" > [< / span > < span class = "dv" > 0< / span > < span class = "op" > ],< / span > NULL< span class = "op" > ,< / span > < span class = "op" > & < / span > contents< span class = "op" > ,< / span > < span class = "op" > & < / span > length< span class = "op" > ,< / span > NULL< span class = "op" > ,< / span > NULL< span class = "op" > ))< / span > < span class = "op" > {< / span > < / span >
< span id = "cb5-31" > < a href = "#cb5-31" > < / a > gtk_text_buffer_set_text < span class = "op" > (< / span > tb< span class = "op" > ,< / span > contents< span class = "op" > ,< / span > length< span class = "op" > );< / span > < / span >
< span id = "cb5-32" > < a href = "#cb5-32" > < / a > g_free < span class = "op" > (< / span > contents< span class = "op" > );< / span > < / span >
< span id = "cb5-33" > < a href = "#cb5-33" > < / a > < span class = "cf" > if< / span > < span class = "op" > ((< / span > filename < span class = "op" > =< / span > g_file_get_basename < span class = "op" > (< / span > files< span class = "op" > [< / span > < span class = "dv" > 0< / span > < span class = "op" > ]))< / span > < span class = "op" > !=< / span > NULL< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb5-34" > < a href = "#cb5-34" > < / a > gtk_window_set_title < span class = "op" > (< / span > GTK_WINDOW < span class = "op" > (< / span > win< span class = "op" > ),< / span > filename< span class = "op" > );< / span > < / span >
< span id = "cb5-35" > < a href = "#cb5-35" > < / a > g_free < span class = "op" > (< / span > filename< span class = "op" > );< / span > < / span >
< span id = "cb5-36" > < a href = "#cb5-36" > < / a > < span class = "op" > }< / span > < / span >
< span id = "cb5-37" > < a href = "#cb5-37" > < / a > gtk_widget_show < span class = "op" > (< / span > win< span class = "op" > );< / span > < / span >
< span id = "cb5-38" > < a href = "#cb5-38" > < / a > < span class = "op" > }< / span > < span class = "cf" > else< / span > < span class = "op" > {< / span > < / span >
< span id = "cb5-39" > < a href = "#cb5-39" > < / a > < span class = "cf" > if< / span > < span class = "op" > ((< / span > filename < span class = "op" > =< / span > g_file_get_path < span class = "op" > (< / span > files< span class = "op" > [< / span > < span class = "dv" > 0< / span > < span class = "op" > ]))< / span > < span class = "op" > !=< / span > NULL< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb5-40" > < a href = "#cb5-40" > < / a > g_printerr < span class = "op" > (< / span > < span class = "st" > " No such file: %s.< / span > < span class = "sc" > \n< / span > < span class = "st" > " < / span > < span class = "op" > ,< / span > filename< span class = "op" > );< / span > < / span >
< span id = "cb5-41" > < a href = "#cb5-41" > < / a > g_free < span class = "op" > (< / span > filename< span class = "op" > );< / span > < / span >
< span id = "cb5-42" > < a href = "#cb5-42" > < / a > < span class = "op" > }< / span > < span class = "cf" > else< / span > < / span >
< span id = "cb5-43" > < a href = "#cb5-43" > < / a > g_printerr < span class = "op" > (< / span > < span class = "st" > " File can' t be opened.< / span > < span class = "sc" > \n< / span > < span class = "st" > " < / span > < span class = "op" > );< / span > < / span >
< span id = "cb5-44" > < a href = "#cb5-44" > < / a > gtk_window_destroy < span class = "op" > (< / span > GTK_WINDOW < span class = "op" > (< / span > win< span class = "op" > ));< / span > < / span >
< span id = "cb5-45" > < a href = "#cb5-45" > < / a > < span class = "op" > }< / span > < / span >
< span id = "cb5-46" > < a href = "#cb5-46" > < / a > < span class = "op" > }< / span > < / span >
< span id = "cb5-47" > < a href = "#cb5-47" > < / a > < / span >
< span id = "cb5-48" > < a href = "#cb5-48" > < / a > < span class = "dt" > int< / span > < / span >
< span id = "cb5-49" > < a href = "#cb5-49" > < / a > main < span class = "op" > (< / span > < span class = "dt" > int< / span > argc< span class = "op" > ,< / span > < span class = "dt" > char< / span > < span class = "op" > **< / span > argv< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb5-50" > < a href = "#cb5-50" > < / a > GtkApplication < span class = "op" > *< / span > app< span class = "op" > ;< / span > < / span >
< span id = "cb5-51" > < a href = "#cb5-51" > < / a > < span class = "dt" > int< / span > stat< span class = "op" > ;< / span > < / span >
< span id = "cb5-52" > < a href = "#cb5-52" > < / a > < / span >
< span id = "cb5-53" > < a href = "#cb5-53" > < / a > app < span class = "op" > =< / span > gtk_application_new < span class = "op" > (< / span > < span class = "st" > " com.github.ToshioCP.tfv3" < / span > < span class = "op" > ,< / span > G_APPLICATION_HANDLES_OPEN< span class = "op" > );< / span > < / span >
< span id = "cb5-54" > < a href = "#cb5-54" > < / a > g_signal_connect < span class = "op" > (< / span > app< span class = "op" > ,< / span > < span class = "st" > " activate" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > app_activate< span class = "op" > ),< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb5-55" > < a href = "#cb5-55" > < / a > g_signal_connect < span class = "op" > (< / span > app< span class = "op" > ,< / span > < span class = "st" > " open" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > app_open< span class = "op" > ),< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb5-56" > < a href = "#cb5-56" > < / a > stat < span class = "op" > =< / span > g_application_run < span class = "op" > (< / span > G_APPLICATION < span class = "op" > (< / span > app< span class = "op" > ),< / span > argc< span class = "op" > ,< / span > argv< span class = "op" > );< / span > < / span >
< span id = "cb5-57" > < a href = "#cb5-57" > < / a > g_object_unref < span class = "op" > (< / span > app< span class = "op" > );< / span > < / span >
< span id = "cb5-58" > < a href = "#cb5-58" > < / a > < span class = "cf" > return< / span > stat< span class = "op" > ;< / span > < / span >
< span id = "cb5-59" > < a href = "#cb5-59" > < / a > < span class = "op" > }< / span > < / span > < / code > < / pre > < / div >
2022-04-17 13:54:42 +02:00
< p > Save it as < code > tfv3.c< / code > . Then compile and run it.< / p >
< pre > < code > $ comp tfv3
$ ./a.out tfv3.c< / code > < / pre >
< figure >
2022-12-21 14:31:33 +01:00
< img src = "image/screenshot_tfv3.png" alt = "File viewer" / >
< figcaption aria-hidden = "true" > File viewer< / figcaption >
2022-04-17 13:54:42 +02:00
< / figure >
2022-12-21 14:31:33 +01:00
< p > The function < code > main< / code > has only two changes from the previous
version.< / p >
< ul >
< li > < code > G_APPLICATION_DEFAULT_FLAGS< / code > is replaced by
< code > G_APPLICATION_HANDLES_OPEN< / code > < / li >
< li > < code > g_signal_connect (app, "open", G_CALLBACK (app_open), NULL)< / code >
is added.< / li >
< / ul >
< p > When the flag < code > G_APPLICATION_HANDLES_OPEN< / code > is given to
< code > gtk_application_new< / code > function, the application behaves like
this:< / p >
2022-04-17 13:54:42 +02:00
< ul >
2022-12-21 14:31:33 +01:00
< li > If the application is run without command line arguments, it emits
“activate” signal when it is activated.< / li >
< li > If the application is run with command line arguments, it emits
“open” signal when it is activated.< / li >
2022-04-17 13:54:42 +02:00
< / ul >
2022-12-21 14:31:33 +01:00
< p > The handler < code > app_activate< / code > becomes very simple. It just
outputs the error message and return to the caller. Then the application
quits immediately because no window is created.< / p >
< p > The main work is done in the handler < code > app_open< / code > .< / p >
2022-04-17 13:54:42 +02:00
< ul >
2022-12-21 14:31:33 +01:00
< li > Creates GtkApplicationWindow, GtkScrolledWindow, GtkTextView and
GtkTextBuffer and connects them together< / li >
< li > Sets wrap mode to < code > GTK_WRAP_WORD_CHAR< / code > in
GtktextView< / li >
< li > Sets GtkTextView to non-editable because the program isn’ t an editor
but only a viewer< / li >
< li > Reads the file and inserts the text into GtkTextBuffer (this will be
explained later)< / li >
< li > If the file is not opened, outputs an error message and destroys the
window. This makes the application quit.< / li >
2022-04-17 13:54:42 +02:00
< / ul >
2022-12-21 14:31:33 +01:00
< p > The following is the file reading part of the program again.< / p >
< div class = "sourceCode" id = "cb7" > < pre class = "sourceCode c" > < code class = "sourceCode c" > < span id = "cb7-1" > < a href = "#cb7-1" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "cf" > if< / span > < span class = "op" > (< / span > g_file_load_contents < span class = "op" > (< / span > files< span class = "op" > [< / span > < span class = "dv" > 0< / span > < span class = "op" > ],< / span > NULL< span class = "op" > ,< / span > < span class = "op" > & < / span > contents< span class = "op" > ,< / span > < span class = "op" > & < / span > length< span class = "op" > ,< / span > NULL< span class = "op" > ,< / span > NULL< span class = "op" > ))< / span > < span class = "op" > {< / span > < / span >
< span id = "cb7-2" > < a href = "#cb7-2" aria-hidden = "true" tabindex = "-1" > < / a > gtk_text_buffer_set_text < span class = "op" > (< / span > tb< span class = "op" > ,< / span > contents< span class = "op" > ,< / span > length< span class = "op" > );< / span > < / span >
< span id = "cb7-3" > < a href = "#cb7-3" aria-hidden = "true" tabindex = "-1" > < / a > g_free < span class = "op" > (< / span > contents< span class = "op" > );< / span > < / span >
< span id = "cb7-4" > < a href = "#cb7-4" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "cf" > if< / span > < span class = "op" > ((< / span > filename < span class = "op" > =< / span > g_file_get_basename < span class = "op" > (< / span > files< span class = "op" > [< / span > < span class = "dv" > 0< / span > < span class = "op" > ]))< / span > < span class = "op" > !=< / span > NULL< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb7-5" > < a href = "#cb7-5" aria-hidden = "true" tabindex = "-1" > < / a > gtk_window_set_title < span class = "op" > (< / span > GTK_WINDOW < span class = "op" > (< / span > win< span class = "op" > ),< / span > filename< span class = "op" > );< / span > < / span >
< span id = "cb7-6" > < a href = "#cb7-6" aria-hidden = "true" tabindex = "-1" > < / a > g_free < span class = "op" > (< / span > filename< span class = "op" > );< / span > < / span >
< span id = "cb7-7" > < a href = "#cb7-7" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "op" > }< / span > < / span >
< span id = "cb7-8" > < a href = "#cb7-8" aria-hidden = "true" tabindex = "-1" > < / a > gtk_widget_show < span class = "op" > (< / span > win< span class = "op" > );< / span > < / span >
< span id = "cb7-9" > < a href = "#cb7-9" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "op" > }< / span > < span class = "cf" > else< / span > < span class = "op" > {< / span > < / span >
< span id = "cb7-10" > < a href = "#cb7-10" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "cf" > if< / span > < span class = "op" > ((< / span > filename < span class = "op" > =< / span > g_file_get_path < span class = "op" > (< / span > files< span class = "op" > [< / span > < span class = "dv" > 0< / span > < span class = "op" > ]))< / span > < span class = "op" > !=< / span > NULL< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb7-11" > < a href = "#cb7-11" aria-hidden = "true" tabindex = "-1" > < / a > g_printerr < span class = "op" > (< / span > < span class = "st" > " No such file: %s.< / span > < span class = "sc" > \n< / span > < span class = "st" > " < / span > < span class = "op" > ,< / span > filename< span class = "op" > );< / span > < / span >
< span id = "cb7-12" > < a href = "#cb7-12" aria-hidden = "true" tabindex = "-1" > < / a > g_free < span class = "op" > (< / span > filename< span class = "op" > );< / span > < / span >
< span id = "cb7-13" > < a href = "#cb7-13" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "op" > }< / span > < span class = "cf" > else< / span > < / span >
< span id = "cb7-14" > < a href = "#cb7-14" aria-hidden = "true" tabindex = "-1" > < / a > g_printerr < span class = "op" > (< / span > < span class = "st" > " File can' t be opened.< / span > < span class = "sc" > \n< / span > < span class = "st" > " < / span > < span class = "op" > );< / span > < / span >
< span id = "cb7-15" > < a href = "#cb7-15" aria-hidden = "true" tabindex = "-1" > < / a > gtk_window_destroy < span class = "op" > (< / span > GTK_WINDOW < span class = "op" > (< / span > win< span class = "op" > ));< / span > < / span >
< span id = "cb7-16" > < a href = "#cb7-16" aria-hidden = "true" tabindex = "-1" > < / a > < span class = "op" > }< / span > < / span > < / code > < / pre > < / div >
< p > The function < code > g_file_load_contents< / code > loads the file
contents into a temporary buffer, which is automatically allocated and
sets < code > contents< / code > to point the buffer. The length of the buffer
is assigned to < code > length< / code > . It returns < code > TRUE< / code > if the
file’ s contents are successfully loaded or < code > FALSE< / code > if an
error occurs. If you want to know the details about
g_file_load_contents, see < a
href="https://docs.gtk.org/gio/method.File.load_contents.html">g file
load contents< / a > .< / p >
< p > If it has successfully read the file, it inserts the contents into
GtkTextBuffer, frees the temporary buffer pointed by
< code > contents< / code > , sets the title of the window, frees the memories
pointed by < code > filename< / code > and then shows the window. If it fails,
it outputs an error message and destroys the window and finally make the
program quit.< / p >
2022-04-17 13:54:42 +02:00
< h2 id = "gtknotebook" > GtkNotebook< / h2 >
2022-12-21 14:31:33 +01:00
< p > GtkNotebook is a container widget that contains multiple widgets with
tabs. It shows only one child at a time. Another child will be shown
when its tab is clicked.< / p >
2022-04-17 13:54:42 +02:00
< figure >
2022-12-21 14:31:33 +01:00
< img src = "image/screenshot_gtk_notebook.png" alt = "GtkNotebook" / >
< figcaption aria-hidden = "true" > GtkNotebook< / figcaption >
2022-04-17 13:54:42 +02:00
< / figure >
2022-12-21 14:31:33 +01:00
< p > The left image is the window at the startup. The file
< code > pr1.c< / code > is shown and its filename is in the left tab. After
clicking on the right tab, the contents of the file < code > tfv1.c< / code >
is shown. The right image is the screenshot.< / p >
< p > The following is < code > tfv4.c< / code > . It has GtkNoteBook widget. It
is inserted as a child of GtkApplicationWindow and contains multiple
GtkScrolledWindow.< / p >
< div class = "sourceCode" id = "cb8" > < pre
class="sourceCode numberSource C numberLines">< code class = "sourceCode c" > < span id = "cb8-1" > < a href = "#cb8-1" > < / a > < span class = "pp" > #include < / span > < span class = "im" > < gtk/gtk.h> < / span > < / span >
< span id = "cb8-2" > < a href = "#cb8-2" > < / a > < / span >
< span id = "cb8-3" > < a href = "#cb8-3" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
< span id = "cb8-4" > < a href = "#cb8-4" > < / a > app_activate < span class = "op" > (< / span > GApplication < span class = "op" > *< / span > app< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb8-5" > < a href = "#cb8-5" > < / a > g_printerr < span class = "op" > (< / span > < span class = "st" > " You need a filename argument.< / span > < span class = "sc" > \n< / span > < span class = "st" > " < / span > < span class = "op" > );< / span > < / span >
< span id = "cb8-6" > < a href = "#cb8-6" > < / a > < span class = "op" > }< / span > < / span >
< span id = "cb8-7" > < a href = "#cb8-7" > < / a > < / span >
< span id = "cb8-8" > < a href = "#cb8-8" > < / a > < span class = "dt" > static< / span > < span class = "dt" > void< / span > < / span >
< span id = "cb8-9" > < a href = "#cb8-9" > < / a > app_open < span class = "op" > (< / span > GApplication < span class = "op" > *< / span > app< span class = "op" > ,< / span > GFile < span class = "op" > **< / span > files< span class = "op" > ,< / span > gint n_files< span class = "op" > ,< / span > gchar < span class = "op" > *< / span > hint< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb8-10" > < a href = "#cb8-10" > < / a > GtkWidget < span class = "op" > *< / span > win< span class = "op" > ;< / span > < / span >
< span id = "cb8-11" > < a href = "#cb8-11" > < / a > GtkWidget < span class = "op" > *< / span > nb< span class = "op" > ;< / span > < / span >
< span id = "cb8-12" > < a href = "#cb8-12" > < / a > GtkWidget < span class = "op" > *< / span > lab< span class = "op" > ;< / span > < / span >
< span id = "cb8-13" > < a href = "#cb8-13" > < / a > GtkNotebookPage < span class = "op" > *< / span > nbp< span class = "op" > ;< / span > < / span >
< span id = "cb8-14" > < a href = "#cb8-14" > < / a > GtkWidget < span class = "op" > *< / span > scr< span class = "op" > ;< / span > < / span >
< span id = "cb8-15" > < a href = "#cb8-15" > < / a > GtkWidget < span class = "op" > *< / span > tv< span class = "op" > ;< / span > < / span >
< span id = "cb8-16" > < a href = "#cb8-16" > < / a > GtkTextBuffer < span class = "op" > *< / span > tb< span class = "op" > ;< / span > < / span >
< span id = "cb8-17" > < a href = "#cb8-17" > < / a > < span class = "dt" > char< / span > < span class = "op" > *< / span > contents< span class = "op" > ;< / span > < / span >
< span id = "cb8-18" > < a href = "#cb8-18" > < / a > gsize length< span class = "op" > ;< / span > < / span >
< span id = "cb8-19" > < a href = "#cb8-19" > < / a > < span class = "dt" > char< / span > < span class = "op" > *< / span > filename< span class = "op" > ;< / span > < / span >
< span id = "cb8-20" > < a href = "#cb8-20" > < / a > < span class = "dt" > int< / span > i< span class = "op" > ;< / span > < / span >
< span id = "cb8-21" > < a href = "#cb8-21" > < / a > < / span >
< span id = "cb8-22" > < a href = "#cb8-22" > < / a > win < span class = "op" > =< / span > gtk_application_window_new < span class = "op" > (< / span > GTK_APPLICATION < span class = "op" > (< / span > app< span class = "op" > ));< / span > < / span >
< span id = "cb8-23" > < a href = "#cb8-23" > < / a > gtk_window_set_title < span class = "op" > (< / span > GTK_WINDOW < span class = "op" > (< / span > win< span class = "op" > ),< / span > < span class = "st" > " file viewer" < / span > < span class = "op" > );< / span > < / span >
< span id = "cb8-24" > < a href = "#cb8-24" > < / a > gtk_window_set_default_size < span class = "op" > (< / span > GTK_WINDOW < span class = "op" > (< / span > win< span class = "op" > ),< / span > < span class = "dv" > 600< / span > < span class = "op" > ,< / span > < span class = "dv" > 400< / span > < span class = "op" > );< / span > < / span >
< span id = "cb8-25" > < a href = "#cb8-25" > < / a > < / span >
< span id = "cb8-26" > < a href = "#cb8-26" > < / a > nb < span class = "op" > =< / span > gtk_notebook_new < span class = "op" > ();< / span > < / span >
< span id = "cb8-27" > < a href = "#cb8-27" > < / a > gtk_window_set_child < span class = "op" > (< / span > GTK_WINDOW < span class = "op" > (< / span > win< span class = "op" > ),< / span > nb< span class = "op" > );< / span > < / span >
< span id = "cb8-28" > < a href = "#cb8-28" > < / a > < / span >
< span id = "cb8-29" > < a href = "#cb8-29" > < / a > < span class = "cf" > for< / span > < span class = "op" > (< / span > i < span class = "op" > =< / span > < span class = "dv" > 0< / span > < span class = "op" > ;< / span > i < span class = "op" > < < / span > n_files< span class = "op" > ;< / span > i< span class = "op" > ++)< / span > < span class = "op" > {< / span > < / span >
< span id = "cb8-30" > < a href = "#cb8-30" > < / a > < span class = "cf" > if< / span > < span class = "op" > (< / span > g_file_load_contents < span class = "op" > (< / span > files< span class = "op" > [< / span > i< span class = "op" > ],< / span > NULL< span class = "op" > ,< / span > < span class = "op" > & < / span > contents< span class = "op" > ,< / span > < span class = "op" > & < / span > length< span class = "op" > ,< / span > NULL< span class = "op" > ,< / span > NULL< span class = "op" > ))< / span > < span class = "op" > {< / span > < / span >
< span id = "cb8-31" > < a href = "#cb8-31" > < / a > scr < span class = "op" > =< / span > gtk_scrolled_window_new < span class = "op" > ();< / span > < / span >
< span id = "cb8-32" > < a href = "#cb8-32" > < / a > tv < span class = "op" > =< / span > gtk_text_view_new < span class = "op" > ();< / span > < / span >
< span id = "cb8-33" > < a href = "#cb8-33" > < / a > tb < span class = "op" > =< / span > gtk_text_view_get_buffer < span class = "op" > (< / span > GTK_TEXT_VIEW < span class = "op" > (< / span > tv< span class = "op" > ));< / span > < / span >
< span id = "cb8-34" > < a href = "#cb8-34" > < / a > gtk_text_view_set_wrap_mode < span class = "op" > (< / span > GTK_TEXT_VIEW < span class = "op" > (< / span > tv< span class = "op" > ),< / span > GTK_WRAP_WORD_CHAR< span class = "op" > );< / span > < / span >
< span id = "cb8-35" > < a href = "#cb8-35" > < / a > gtk_text_view_set_editable < span class = "op" > (< / span > GTK_TEXT_VIEW < span class = "op" > (< / span > tv< span class = "op" > ),< / span > FALSE< span class = "op" > );< / span > < / span >
< span id = "cb8-36" > < a href = "#cb8-36" > < / a > gtk_scrolled_window_set_child < span class = "op" > (< / span > GTK_SCROLLED_WINDOW < span class = "op" > (< / span > scr< span class = "op" > ),< / span > tv< span class = "op" > );< / span > < / span >
< span id = "cb8-37" > < a href = "#cb8-37" > < / a > < / span >
< span id = "cb8-38" > < a href = "#cb8-38" > < / a > gtk_text_buffer_set_text < span class = "op" > (< / span > tb< span class = "op" > ,< / span > contents< span class = "op" > ,< / span > length< span class = "op" > );< / span > < / span >
< span id = "cb8-39" > < a href = "#cb8-39" > < / a > g_free < span class = "op" > (< / span > contents< span class = "op" > );< / span > < / span >
< span id = "cb8-40" > < a href = "#cb8-40" > < / a > < span class = "cf" > if< / span > < span class = "op" > ((< / span > filename < span class = "op" > =< / span > g_file_get_basename < span class = "op" > (< / span > files< span class = "op" > [< / span > i< span class = "op" > ]))< / span > < span class = "op" > !=< / span > NULL< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb8-41" > < a href = "#cb8-41" > < / a > lab < span class = "op" > =< / span > gtk_label_new < span class = "op" > (< / span > filename< span class = "op" > );< / span > < / span >
< span id = "cb8-42" > < a href = "#cb8-42" > < / a > g_free < span class = "op" > (< / span > filename< span class = "op" > );< / span > < / span >
< span id = "cb8-43" > < a href = "#cb8-43" > < / a > < span class = "op" > }< / span > < span class = "cf" > else< / span > < / span >
< span id = "cb8-44" > < a href = "#cb8-44" > < / a > lab < span class = "op" > =< / span > gtk_label_new < span class = "op" > (< / span > < span class = "st" > " " < / span > < span class = "op" > );< / span > < / span >
< span id = "cb8-45" > < a href = "#cb8-45" > < / a > gtk_notebook_append_page < span class = "op" > (< / span > GTK_NOTEBOOK < span class = "op" > (< / span > nb< span class = "op" > ),< / span > scr< span class = "op" > ,< / span > lab< span class = "op" > );< / span > < / span >
< span id = "cb8-46" > < a href = "#cb8-46" > < / a > nbp < span class = "op" > =< / span > gtk_notebook_get_page < span class = "op" > (< / span > GTK_NOTEBOOK < span class = "op" > (< / span > nb< span class = "op" > ),< / span > scr< span class = "op" > );< / span > < / span >
< span id = "cb8-47" > < a href = "#cb8-47" > < / a > g_object_set < span class = "op" > (< / span > nbp< span class = "op" > ,< / span > < span class = "st" > " tab-expand" < / span > < span class = "op" > ,< / span > TRUE< span class = "op" > ,< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb8-48" > < a href = "#cb8-48" > < / a > < span class = "op" > }< / span > < span class = "cf" > else< / span > < span class = "cf" > if< / span > < span class = "op" > ((< / span > filename < span class = "op" > =< / span > g_file_get_path < span class = "op" > (< / span > files< span class = "op" > [< / span > i< span class = "op" > ]))< / span > < span class = "op" > !=< / span > NULL< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb8-49" > < a href = "#cb8-49" > < / a > g_printerr < span class = "op" > (< / span > < span class = "st" > " No such file: %s.< / span > < span class = "sc" > \n< / span > < span class = "st" > " < / span > < span class = "op" > ,< / span > filename< span class = "op" > );< / span > < / span >
< span id = "cb8-50" > < a href = "#cb8-50" > < / a > g_free < span class = "op" > (< / span > filename< span class = "op" > );< / span > < / span >
< span id = "cb8-51" > < a href = "#cb8-51" > < / a > < span class = "op" > }< / span > < span class = "cf" > else< / span > < / span >
< span id = "cb8-52" > < a href = "#cb8-52" > < / a > g_printerr < span class = "op" > (< / span > < span class = "st" > " No valid file is given< / span > < span class = "sc" > \n< / span > < span class = "st" > " < / span > < span class = "op" > );< / span > < / span >
< span id = "cb8-53" > < a href = "#cb8-53" > < / a > < span class = "op" > }< / span > < / span >
< span id = "cb8-54" > < a href = "#cb8-54" > < / a > < span class = "cf" > if< / span > < span class = "op" > (< / span > gtk_notebook_get_n_pages < span class = "op" > (< / span > GTK_NOTEBOOK < span class = "op" > (< / span > nb< span class = "op" > ))< / span > < span class = "op" > > < / span > < span class = "dv" > 0< / span > < span class = "op" > )< / span > < / span >
< span id = "cb8-55" > < a href = "#cb8-55" > < / a > gtk_widget_show < span class = "op" > (< / span > win< span class = "op" > );< / span > < / span >
< span id = "cb8-56" > < a href = "#cb8-56" > < / a > < span class = "cf" > else< / span > < / span >
< span id = "cb8-57" > < a href = "#cb8-57" > < / a > gtk_window_destroy < span class = "op" > (< / span > GTK_WINDOW < span class = "op" > (< / span > win< span class = "op" > ));< / span > < / span >
< span id = "cb8-58" > < a href = "#cb8-58" > < / a > < span class = "op" > }< / span > < / span >
< span id = "cb8-59" > < a href = "#cb8-59" > < / a > < / span >
< span id = "cb8-60" > < a href = "#cb8-60" > < / a > < span class = "dt" > int< / span > < / span >
< span id = "cb8-61" > < a href = "#cb8-61" > < / a > main < span class = "op" > (< / span > < span class = "dt" > int< / span > argc< span class = "op" > ,< / span > < span class = "dt" > char< / span > < span class = "op" > **< / span > argv< span class = "op" > )< / span > < span class = "op" > {< / span > < / span >
< span id = "cb8-62" > < a href = "#cb8-62" > < / a > GtkApplication < span class = "op" > *< / span > app< span class = "op" > ;< / span > < / span >
< span id = "cb8-63" > < a href = "#cb8-63" > < / a > < span class = "dt" > int< / span > stat< span class = "op" > ;< / span > < / span >
< span id = "cb8-64" > < a href = "#cb8-64" > < / a > < / span >
< span id = "cb8-65" > < a href = "#cb8-65" > < / a > app < span class = "op" > =< / span > gtk_application_new < span class = "op" > (< / span > < span class = "st" > " com.github.ToshioCP.tfv4" < / span > < span class = "op" > ,< / span > G_APPLICATION_HANDLES_OPEN< span class = "op" > );< / span > < / span >
< span id = "cb8-66" > < a href = "#cb8-66" > < / a > g_signal_connect < span class = "op" > (< / span > app< span class = "op" > ,< / span > < span class = "st" > " activate" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > app_activate< span class = "op" > ),< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb8-67" > < a href = "#cb8-67" > < / a > g_signal_connect < span class = "op" > (< / span > app< span class = "op" > ,< / span > < span class = "st" > " open" < / span > < span class = "op" > ,< / span > G_CALLBACK < span class = "op" > (< / span > app_open< span class = "op" > ),< / span > NULL< span class = "op" > );< / span > < / span >
< span id = "cb8-68" > < a href = "#cb8-68" > < / a > stat < span class = "op" > =< / span > g_application_run < span class = "op" > (< / span > G_APPLICATION < span class = "op" > (< / span > app< span class = "op" > ),< / span > argc< span class = "op" > ,< / span > argv< span class = "op" > );< / span > < / span >
< span id = "cb8-69" > < a href = "#cb8-69" > < / a > g_object_unref < span class = "op" > (< / span > app< span class = "op" > );< / span > < / span >
< span id = "cb8-70" > < a href = "#cb8-70" > < / a > < span class = "cf" > return< / span > stat< span class = "op" > ;< / span > < / span >
< span id = "cb8-71" > < a href = "#cb8-71" > < / a > < span class = "op" > }< / span > < / span > < / code > < / pre > < / div >
< p > Most of the changes are in the function < code > app_open< / code > . The
numbers at the left of the following items are line numbers in the
source code.< / p >
2022-04-17 13:54:42 +02:00
< ul >
2022-12-21 14:31:33 +01:00
< li > 11-13: Variables < code > nb< / code > , < code > lab< / code > and
< code > nbp< / code > are defined. They point GtkNotebook, GtkLabel and
GtkNotebookPage respectively.< / li >
2022-04-17 13:54:42 +02:00
< li > 23: The window’ s title is set to “file viewer”.< / li >
2022-12-21 14:31:33 +01:00
< li > 24: The default size of the window is 600x400.< / li >
< li > 26-27 GtkNotebook is created and inserted to the
GtkApplicationWindow as a child.< / li >
< li > 29-58 For-loop. The variable < code > files[i]< / code > points i-th
GFile, which is created by the GtkApplication from the i-th command line
argument.< / li >
< li > 31-36 GtkScrollledWindow, GtkTextView are created. GtkTextBuffer is
got from the GtkTextView. The GtkTextView is connected to the
GtkScrolledWindow as a child.< / li >
< li > 38-39 inserts the contents of the file into GtkTextBuffer and frees
the memory pointed by < code > contents< / code > .< / li >
< li > 40-42: If the filename is taken from the GFile, GtkLabel is created
with the filename. The string < code > filename< / code > is freed..< / li >
< li > 43-44: If it fails to take the filename, empty string GtkLabel is
created.< / li >
< li > 45-46: Appends a GtkScrolledWindow to the GtkNotebook as a child.
And the GtkLabel is set as the child’ s tab. At the same time, a
GtkNoteBookPage is created automatically. The function
< code > gtk_notebook_get_page< / code > returns the GtkNotebookPage of the
child (GtkScrolledWindow).< / li >
< li > 47: GtkNotebookPage has “tab-expand” property. If it is set to TRUE
then the tab expands horizontally as long as possible. If it is FALSE,
then the width of the tab is determined by the size of the label.
< code > g_object_set< / code > is a general function to set properties of
objects. See < a
href="https://docs.gtk.org/gobject/method.Object.set.html">GObject API
Reference – g_object_set< / a > .< / li >
< li > 48-50: If it fails to read the file and a filename is taken from the
GFile, “No such file” message is displayed. The < code > filename< / code > is
freed.< / li >
< li > 51-52: If < code > filename< / code > is NULL, the “No valid file is
given” message is displayed.< / li >
< li > 54-57: If at least one page exists, the window is shown. Otherwise,
the window is destroyed and the application quits.< / li >
2022-04-17 13:54:42 +02:00
< / ul >
2022-04-21 16:53:28 +02:00
< / div >
< script src = "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity = "sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin = "anonymous" > < / script >
< / body >
< / html >