The following content is all my personal programming experience in Linux, Which is original to me. If it is reproduced, indicate the source, and maintain Article Complete.
Compile GTK +ProgramBasic Ideas
Sagaeon, author of linuxfans
For common GUI programs, what you want to do is to perform some event processing (including various computing and file operations) and display it on the interface. The following steps describe how to get started with GTK. (Because the materials you have read cannot be found, please point out the errors ).
1. What functions and problems do we want to accomplish?
Let's first consider several situations when writing a program with a graphic interface.
1. You want to click the button button_dis and display a number on button_dis.
2. You want to display a number on the button button_dis every second.
3. You want to use libpcap to capture, analyze, and display the analysis results on the interface.
4. Make a game and control your actions by pressing the button.
1. For the first case, let's show it to a column.
Code:
// GCC pro1.c-O pro1 'pkg-config -- cflags -- libs GTK +-1000'
# Include & lt; GTK/GTK. H & gt;
# Include & lt; unistd. H & gt;
Static int COUNT = 1;
Char C [2];
Static void Hello (gtkwidget * widget,
Gpointer data)
{
C [0] = (char) (* (int *) data) + 48 );
Count = (count ++) % 9;
Gtk_button_set_label (gtkbutton *) widget, C );
}
Static void destroy (gtkwidget * widget,
Gpointer data)
{
Gtk_main_quit ();
}
Int main (INT argc,
Char * argv [])
{
Gtkwidget * window;
Gtkwidget * button;
gtk_init (& argc, & argv);
/* Create a new window */
window = gtk_window_new (gtk_window_toplevel );
g_signal_connect (g_object (window), "Destroy",
g_callback (destroy), null);
gtk_container_set_border_width (gtk_container (window ), 20);
button = gtk_button_new_with_label ("Hello World");
g_signal_connect (g_object (button), "clicked",
g_callback (Hello ), null);
gtk_container_add (gtk_container (window), button);
gtk_widget_show (window);
gtk_main ();
return 0;
}
Then GCC pro1.c-O pro1 'pkg-config -- cflags -- libs GTK +-2.0 '.
It is easy to implement. You have spent some time learning the basic GTK programming. This program is easy to understand. Let's look at the second case.
2. Do you want to put the following code in the callback function of the button: code:
Static void Hello (gtkwidget * widget,
Gpointer data)
{
Int I = 0;
For (; I & lt; 5; I ++ ){
C [0] = (char) (count + 48 );
Gtk_button_set_label (gtkbutton *) widget, C );
Count = (count ++) % 9;
Sleep (1 );
}
}
after you run the command, the result is not as accurate as you wish. A number is added per second (not accurate. What's the problem? The result is not as follows: the number on the button is automatically refreshed every second, but 5 seconds later. During this period, the window is as dead as it cannot respond to mouse events. To solve this problem, you must consider the main GUI loop in GTK.
most GUI masters are an infinite loop driven by events. This main loop detects an event queue provided by a lower-level system, retrieves and processes events from the queue. The event processing function is generally called a callback function. The mechanism that associates events with callback functions is generally called registration. For example,
g_signal_connect (gpointer) about1, "Activate",
g_callback (on_about1_activate),
null);
regardless of the fourth parameter, this function indicates that if the activate signal occurs on the part about1, The on_about1_activate function is called. This registration mechanism is actually quite understandable. For example, you can use a table where the signal of each widget corresponds to the callback function. G_signal_connect is called to fill the table. (Events differ from Signals in GTK. See background document 1 at the bottom of the article ).
This main loop (gtk_main () function) cyclically checks whether there are any signals or events in this window, and responds according to your callback function. The premise is that GTK can respond to external requests in a timely manner without stopping the geothermal cycle. When calling the callback function, note that during this period, it does not perform cyclic detection of external events, so it cannot respond to external events. If the processing time of your callback function is very long, naturally, you will see problems in our program. To solve this problem, let's first look at a simple method.
code:
Static void Hello (gtkwidget * widget,
Gpointer data)
{
Int I = 0;
For (; I & lt; 5; I ++ ){
C [0] = (char) (count + 48 );
Gtk_button_set_label (gtkbutton *) widget, C );
While (gtk_events_pending ())
Gtk_main_iteration ();
Count = (count ++) % 9;
Sleep (1 );
}
}
Compile, how is it going. But we still have problems.
To be continued .......
3. How to complete? ---- MVC Structure
The solution is the MVC structure, that is, model --- view --- controller. This term is used in Java, Smalltalk (note 1), and Object-Oriented Analysis and Design (2E) grady booch uses the display item object to represent the same meaning as the model (note 2). In MFC, document represents the model ("MFC programming"). Through the separation of view and model, we have implemented a good program framework (note 3 ).
Note 1: Design Pattern English page 4 Object-Oriented Analysis and Design 2E page 98
NOTE 2: Object-Oriented Analysis and Design 2E page 98
Note 3: For how to separate view and model, see applying UML and patterns 2E Craig larman page471.
To be supplemented
4. Optional communication between model and view
To be continued .....
Background information:
1. Differences between signals and events in GTK)
In the X system, the down-to-top relationship is xlib -- & gt; gdk -- & gt; GTK. Let's look at gdk first. We all know that X and gdk are both event-driven systems. That is to say, they work in a way that they constantly retrieve events from the event queue of the underlying system and then process them accordingly. Of course, this event queue is generated by a more underlying system (for example, the event queue of gdk is obtained from X, and the event queue of X is obtained from ....). Here, what is an event? Is a structure. This structure includes many elements. For example, the coordinates X and y on window a are an event, which is visible and self-contained, it contains all the information you want. Based on this information, you can do many things. For example, you can design a Main Loop Based on gdk. Suppose you have two widgets a and B, and you want to click on a (an event) "saga" is displayed on B ". You can do this in your main loop: 1. initialize and create a table. There are two items in the table: A and B. A is blank. Put two clicked items in B -- & gt; display: Display (SAGA) When B receives the clicked ). 2. loop: Take the event, if. click the location where the event occurs on a (view the location items in the event structure, which can be coordinates or corresponding windows ), then a sends a "clicked" (remember this sentence) to B, B receives "clicked" and displays, B. click do not occur on a, discard the event, and then take the next event for judgment, recurrence. See? Suppose there are dozens of widgets on the screen, each of which is made into tables like a and B, and put it into the "clicked" (or something else) that you receive) when you find (based on location) a "clicked" occurs on a widget in the main loop, you can look up the table and perform the corresponding event (function ), its functions are as powerful as GTK. Think of this as a framework. Anyone can use it. Just fill in the table and write the function to be executed after "clicked" is received. It is very convenient, you can all be System Architects. This is what GTK does! (Of course, GTK has done too many other things, and its name is "gimp toolkit"-it is the main thing to do to draw a widget)
Replace some words with formal terms. This process is like this: when the main loop receives an event (click with the mouse, in window a), window a sends a "clicked" signal to B ", b. Check whether the registered callback function (registration -- that is, the function of g_connect_signal) is available. There is a registered function, is display (...), execute this function (saga is displayed on B ).
We can see that a sends a signal to B, but you can also send a signal to yourself. This is the description: When a click event occurs on, A sends a "clicked" signal to A. After receiving this signal, a displays "saga" on "! In addition, in the implementation of most programmers, A sends a signal to himself, that is, it often goes through an event (A goes through clicking this event, saying experience, is it a bit dizzy when the widget sends a signal to itself and processes the signal? This is why events and signals are often confused !!!
In this way, we can summarize some differences:
1. The signal is always sent by a widget. The event is generated by a lower-level driver (of course, most of the time it is sent by a person and then packaged by the system or X and transferred to gdk). It carries the location information generated by the event itself.
2. there are many similar functions between them. For example, you can use gtk_widget_set (ADD) _ events, let a widget listen to an event (for example, you can listen to mouse clicks on different widgets), just like listening to a signal, the difference is that you can hear events that occur on other components, but you cannot hear signals that are not sent to you.
3. The signal has a transmission mechanism. For example, if a does not process the callback function of the signal, it will transmit the signal to the parent class until someone processes the signal or to the top layer. The event is always in the event queue. You can say to the operating system (the term is registration) That I care about the mouse click event and tell me that if you don't say it, it won't tell you!
4. There are many differences in details.