📄 sec-mainloop.html
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html> <head> <title> The Main Loop </title> <meta name="GENERATOR" content= "Modular DocBook HTML Stylesheet Version 1.45"> <link rel="HOME" title="GTK+ / Gnome Application Development" href="ggad.html"> <link rel="UP" title="GTK+ Basics" href="cha-gtk.html"> <link rel="PREVIOUS" title="Widget Concepts" href="z57.html"> <link rel="NEXT" title="Building a Gnome Application" href= "build-app.html"> </head> <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink= "#840084" alink="#0000FF"> <div class="NAVHEADER"> <table width="100%" border="0" bgcolor="#ffffff" cellpadding= "1" cellspacing="0"> <tr> <th colspan="4" align="center"> <font color="#000000" size="2">GTK+ / Gnome Application Development</font> </th> </tr> <tr> <td width="25%" bgcolor="#ffffff" align="left"> <a href="z57.html"><font color="#0000ff" size="2"><b> <<< Previous</b></font></a> </td> <td width="25%" colspan="2" bgcolor="#ffffff" align= "center"> <font color="#0000ff" size="2"><b><a href="ggad.html"> <font color="#0000ff" size="2"><b> Home</b></font></a></b></font> </td> <td width="25%" bgcolor="#ffffff" align="right"> <a href="build-app.html"><font color="#0000ff" size= "2"><b>Next >>></b></font></a> </td> </tr> </table> </div> <div class="SECT1"> <h1 class="SECT1"> <a name="SEC-MAINLOOP">The Main Loop</a> </h1> <p> The GTK+ main loop's primary role is to listen for events on a file descriptor connected to the X server, and forward them to widgets. <a href="sec-gdkevent.html#SEC-GTKEVENTS"> the section called <i>Receiving GDK Events in GTK+</i> in the chapter called <i>GDK Basics</i></a> describes the main loop's event handling in more detail. This section explains the main loop in general terms, and describes how to add new functionality to the main loop: callbacks to be invoked when the loop is idle, at a specified interval, when a file descriptor is ready for reading or writing, and when the main loop exits. </p> <div class="SECT2"> <h2 class="SECT2"> <a name="Z60">Main Loop Basics</a> </h2> <p> The main loop is primarily implemented by glib, which has a generic main loop abstraction. GTK+ attaches the glib main loop to GDK's X server connection, and presents a convenient interface (the glib loop is slightly lower-level than the GTK+ loop). The core GTK+ main loop interface is shown in <a href= "sec-mainloop.html#FL-MAINLOOP">Figure 28</a>. </p> <p> <tt class="FUNCTION">gtk_main()</tt> runs the main loop. <tt class="FUNCTION">gtk_main()</tt> will not return until <tt class="FUNCTION">gtk_main_quit()</tt> is called. <tt class="FUNCTION">gtk_main()</tt> can be called recursively; each call to <tt class="FUNCTION"> gtk_main_quit()</tt> exits one instance of <tt class= "FUNCTION">gtk_main()</tt>. <tt class="FUNCTION"> gtk_main_level()</tt> returns the level of recursion; that is, it returns 0 if no <tt class="FUNCTION"> gtk_main()</tt> is on the stack, 1 if one <tt class= "FUNCTION">gtk_main()</tt> is running, etc. </p> <p> All instances of <tt class="FUNCTION">gtk_main()</tt> are functionally identical; they are all watching the same connection to the X server and working from the same event queue. <tt class="FUNCTION">gtk_main()</tt> instances are used to block, halting a function's flow of control until some conditions are met. All GTK+ programs use this technique to keep <tt class="FUNCTION"> main()</tt> from exiting while the application is running. The <tt class="FUNCTION">gnome_dialog_run()</tt> function (see <a href="sec-modaldialogs.html">the section called <i>Modal Dialogs</i> in the chapter called <i>User Communication: Dialogs</i></a>) uses a recursive main loop, so it doesn't return until the user clicks a dialog button. </p> <p> Sometimes you want to process a few events, without handing the flow of control to <tt class="FUNCTION"> gtk_main()</tt>. You can perform a single iteration of the main loop by calling <tt class="FUNCTION"> gtk_main_iteration()</tt>. This might process a single event, for example; it depends on what tasks are pending. You can check whether any events need to be processed by calling the <tt class="FUNCTION"> gtk_events_pending()</tt> predicate. Together, these two functions allow you to temporarily return control to GTK+, so the GUI can "catch up." For example, during a long computation, you will want to display a progress bar; you must allow the GTK+ main loop to run periodically, so GTK+ can redraw the progress bar. Use this code: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> while (gtk_events_pending()) gtk_main_iteration(); </pre> </td> </tr> </table> <div class="FIGURE"> <a name="FL-MAINLOOP"></a> <div class="FUNCSYNOPSIS"> <a name="FL-MAINLOOP.SYNOPSIS"></a> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="FUNCSYNOPSISINFO">#include <gtk/gtkmain.h></pre> </td> </tr> </table> <p> <code><code class="FUNCDEF">void <tt class= "FUNCTION">gtk_main</tt></code>(void);</code> </p> <p> <code><code class="FUNCDEF">void <tt class= "FUNCTION">gtk_main_quit</tt></code>(void);</code> </p> <p> <code><code class="FUNCDEF">void <tt class= "FUNCTION"> gtk_main_iteration</tt></code>(void);</code> </p> <p> <code><code class="FUNCDEF">gint <tt class= "FUNCTION"> gtk_events_pending</tt></code>(void);</code> </p> <p> <code><code class="FUNCDEF">guint <tt class= "FUNCTION">gtk_main_level</tt></code>(void);</code> </p> </div> <p> <b>Figure 28. Main Loop</b> </p> </div> </div> <div class="SECT2"> <h2 class="SECT2"> <a name="Z61">Quit Functions</a> </h2> <p> A <i class="FIRSTTERM">quit function</i> is a callback to be invoked when <tt class="FUNCTION">gtk_main_quit()</tt> is called. In other words, the callback runs just before <tt class="FUNCTION">gtk_main()</tt> returns. The callback should be a <span class="STRUCTNAME"> GtkFunction</span>, defined as follows: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> typedef gint (*GtkFunction) (gpointer data); </pre> </td> </tr> </table> <p> Quit functions are added with <tt class="FUNCTION"> gtk_quit_add()</tt> (<a href= "sec-mainloop.html#FL-QUITFUNCS">Figure 29</a>). When adding a quit function, you must specify a main loop level, as returned by <tt class="FUNCTION"> gtk_main_level()</tt>. The second and third arguments specify a callback and callback data. </p> <p> The callback's return value indicates whether the callback should be invoked again. As long as the callback returns <span class="STRUCTNAME">TRUE</span>, it will be repeatedly invoked. As soon as it returns <span class= "STRUCTNAME">FALSE</span>, it is disconnected. When all quit functions have returned <span class="STRUCTNAME"> FALSE</span>, <tt class="FUNCTION">gtk_main()</tt> can return. </p> <p> <tt class="FUNCTION">gtk_quit_add()</tt> returns an ID number that can be used to remove the quit function with <tt class="FUNCTION">gtk_quit_remove()</tt>. You can also remove a quit function by passing its callback data to <tt class="FUNCTION">gtk_quit_remove_by_data()</tt>. </p> <div class="FIGURE"> <a name="FL-QUITFUNCS"></a> <div class="FUNCSYNOPSIS"> <a name="FL-QUITFUNCS.SYNOPSIS"></a> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="FUNCSYNOPSISINFO">#include <gtk/gtkmain.h></pre> </td> </tr> </table> <p> <code><code class="FUNCDEF">guint <tt class= "FUNCTION">gtk_quit_add</tt></code>(guint <tt class= "PARAMETER"><i>main_level</i></tt>, GtkFunction <tt class="PARAMETER"><i>function</i></tt>, gpointer <tt class="PARAMETER"><i>data</i></tt>);</code> </p> <p> <code><code class="FUNCDEF">void <tt class= "FUNCTION">gtk_quit_remove</tt></code>(guint <tt class="PARAMETER"><i> quit_handler_id</i></tt>);</code> </p> <p> <code><code class="FUNCDEF">void <tt class= "FUNCTION"> gtk_quit_remove_by_data</tt></code>(gpointer <tt class="PARAMETER"><i>data</i></tt>);</code> </p> </div> <p> <b>Figure 29. Quit Functions</b> </p> </div> </div>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -