#include <gtk/gtk.h>
Gint Test ()
{
while (1)
{
Gdk_threads_enter ();
g_printf ("hello\n");
Gdk_threads_leave ();
};
return TRUE;
}
Gint timeout_callback (gpointer data)
{
G_thread_create (test, NULL, FALSE, NULL);
return FALSE;
}
/* This is a callback function. The data parameter is ignored in this example.
* There are more examples of callback functions later. */
void Hello (Gtkwidget *widget,
Gpointer data)
{
G_print ("Hello world\n");
}
Gint delete_event (Gtkwidget *widget,
Gdkevent *event,
Gpointer data)
{
/* If your "delete_event" Signal processing function returns FALSE,GTK a "destroy" signal is emitted.
* Returns True, you do not want to close the window.
* When you want to pop up "are you sure you want to quit?" dialog box, it is useful. */
G_print ("Delete event occurred\n");
/* Change true to false the program will close. */
return TRUE;
}
/* Another callback function */
void Destroy (Gtkwidget *widget,
Gpointer data)
{
Gtk_main_quit ();
}
int main (int argc,
Char *argv[])
{
/* Gtkwidget is the storage type of the component */
Gtkwidget *window;
Gtkwidget *button;
if (!g_thread_supported ()) G_thread_init (NULL);
Gdk_threads_init ();
/* This function is called in all GTK programs. Parameters are parsed out of the command line and sent to the program */
Gtk_init (&ARGC, &ARGV);
/* Create a new window */
window = Gtk_window_new (gtk_window_toplevel);
/* When the window receives a "delete_event" signal (this signal is issued by the window manager, usually "off"
* option or the Close button on the title bar is emitted), we let it invoke the Delete_event () function defined earlier.
* The value of the data parameter passed to the callback function is NULL, which is ignored by the callback function. */
G_signal_connect (G_object (window), "Delete_event",
G_callback (delete_event), NULL);
/* Here we connect the "destroy" event to a signal processing function.
* Call the Gtk_widget_destroy () function on this window or return a false value in the "Delete_event" callback function
* will trigger this event. */
G_signal_connect (G_object (window), "Destroy",
G_callback (Destroy), NULL);
/* Create a New button labeled "Hello World". */
button = Gtk_button_new_with_label ("Hello World");
/* When the button receives a "clicked" Signal, the Hello () function is called and NULL is passed to the
* It is used as a parameter. The hello () function is defined earlier. */
G_signal_connect (g_object button), "clicked",
G_callback (hello), NULL);
/* When the button is clicked, the window is closed by calling Gtk_widget_destroy (Windows).
* the "destroy" signal will be sent from here or from the window manager. */
g_signal_connect_swapped (g_object button), "clicked",
G_callback (Gtk_widget_destroy),
window);
/* Put the button into the window (a GTK container). */
Gtk_container_add (Gtk_container (window), button);
/* The last step is to display the newly created button and window */
Gtk_widget_show (button);
Gtk_widget_show (window);
Gtk_timeout_add (1, Timeout_callback, NULL);
/* All GTK programs must have a gtk_main () function. Program Run stop here
* Wait for events (such as keyboard events or mouse events) to occur. */
Gdk_threads_enter ();
Gtk_main ();
Gdk_threads_leave ();
return 0;
}
#include <gtk/gtk.h>
Static Gtkwidget *fixed;
Static Gtkwidget *button1;
Static Gtkwidget *button2;
int running = 1;
void Our_thread1 (Gtkwidget *button)
{
Gint x,y,towards;
x=40;
y=40;
Towards=1;
while (running)
{
G_usleep (1); Be sure to add
Gdk_threads_enter (); When you need to interact with the graphics window, add
Gtk_fixed_move (gtk_fixed (fixed), button,x,y);
Switch (towards)
{
Case 1:
x=x+10;
if (x==250) towards=2;
Break
Case 2:
y=y+10;
if (y==250) towards=3;
Break
Case 3:
x=x-10;
if (x==40) towards=4;
Break
Case 4:
y=y-10;
if (y==50) towards=5;
}
Gdk_threads_leave (); Match the above
}
}
void On_begin (gtkwidget* button,gpointer data)
{
Gtk_widget_set_sensitive (Button,false);
G_thread_create (Our_thread1,button1,false,null);
}
void *run_f (gtkwidget *butt,gpointer data)
{
running = 0;
}
int main (int argc,char* argv[])
{
Gtkwidget *window,*view;
Gtkwidget *vbox,*button,*label;
if (!g_thread_supported ())
G_thread_init (NULL);
Gdk_threads_init ();
Gtk_init (&ARGC,&ARGV);
Window=gtk_window_new (Gtk_window_toplevel);
Gtk_window_set_title (Gtk_window (window), "Thread Apllication");
G_signal_connect (G_object (window), "Delete_event",
G_callback (Gtk_main_quit), NULL);
Gtk_container_set_border_width (Gtk_container (window), 10);
Vbox=gtk_vbox_new (false,0);
Gtk_container_add (Gtk_container (window), vbox);
Label=gtk_label_new ("notice! button is moving ");
Gtk_box_pack_start (Gtk_box (VBox), label,false,false,0);
View=gtk_viewport_new (Null,null);
Gtk_box_pack_start (Gtk_box (VBox), view,false,false,0);
Fixed=gtk_fixed_new ();
Gtk_widget_set_usize (fixed,330,330);
Gtk_container_add (Gtk_container (view), fixed);
Button1=gtk_button_new_with_label ("1");
Gtk_fixed_put (gtk_fixed (fixed), button1,10,10);
Button=gtk_button_new_with_label ("Start");
Gtk_box_pack_start (Gtk_box (VBox), button,false,false,5);
G_signal_connect (g_object button), "clicked",
G_callback (On_begin), NULL); Call On_begin
Gtkwidget *run = Gtk_button_new_with_label ("Stop");
Gtk_box_pack_start (Gtk_box (VBox), run,false,false,5);
G_signal_connect (G_object (Run), "clicked",
G_callback (Run_f), NULL); Call On_begin
Gtk_widget_show_all (window);
Gdk_threads_enter ();
Gtk_main ();
Gdk_threads_leave ();
return FALSE;
}
We know that glib provides a function called G_idle_add, which is easy to understand: Add an idle task to allow the application to execute the specified function when it is idle. This mechanism is very useful, and many things will be very cumbersome without such a mechanism. Its functionality is simple, but not everyone knows how to make the most of its potential, here are some of its main uses.
1. Perform low-priority tasks at idle time. Some task priority is relatively low, but the cost time is relatively long, like screen refresh and other operations, we do not want it to hinder the current operation too long, it can be put into the idle task to do. In fact, GTK + does this in the same way, so you get better responsiveness.
2. Asynchronously synchronizes the synchronization operation. We know that in GTK +, it uses glib's signal as a means of communication between windows/controls, and the execution of signal is a direct call to the function, that is, the entire signal execution process is done synchronously. This works well in most cases, but sometimes there is a problem of re-entry, you tune me, I will tune you, you may get into trouble. At this point we have to use async, and GTK + does not provide asynchronous messages like PostMessage under Win32, but fortunately we can use the G_idle_add function to simulate.
3. Serialization of access to the GUI. In most platforms, access to GUI resources is required to be serialized, that is, in a GUI application, only one thread can manipulate the GUI resources directly. This is because GUI resources are not lock-protected for efficiency reasons, and so is GTK +. What if another thread wants to access the GUI resources, such as to display a message? This can be accomplished by adding an idle task to the G_idle_add, which is executed in the GUI thread (the main thread), so that the GUI resources are accessed serially.
Note here that the idle task is not a separate thread or process, but is executed in the main thread. Idle means that when main loop has no other messages to handle, and no higher priority work is to be done, it is considered to be in an idle state.
Various articles on the Web strongly recommend that all operations on the GUI be done within one thread, while others may cause blocking to work in another thread.
So
Gdk_threads_enter ();
Gtk_label_set_text (Gtk_label (wbus->time), text);
Gdk_threads_leave ();
This code should be replaced by:
G_idle_add (On_finish, Wbus);//Sub-thread.
Gboolean on_finish (Gpointer wbus)
{
Gtk_label_set_text (Gtk_label (wbus->time), text);
return FALSE;
}
"Go" GTK + multi-threaded program instances