इस लाइब्रेरी का एक बड़ा फायदा यह है कि यह व्यावसायिक उपयोग के लिए मुफ्त है। इंटरनेट पर GTK + के साथ काम करने पर बहुत अधिक प्रलेखन और वास्तव में उच्च-गुणवत्ता वाले लेख नहीं हैं। कई उदाहरणों में, प्रोग्राम इंटरफ़ेस "पेन" में लिखा गया है, जो कभी-कभी बहुत असुविधाजनक होता है। मैं खुद इस पार आया था और अक्सर अधिक समय सही रूप से कंटेनरों में विजेट्स (वस्तुओं) को रखने, और कार्य को हल करने पर ध्यान केंद्रित करने में नहीं बिताया।
मैं यह दिखाऊंगा कि ग्लेड विज़ुअल जीयूआई एप्लिकेशन का उपयोग करके जीटीके + के लिए इंटरफ़ेस कैसे बनाया जाए और इसे अपने प्रोग्राम में एकीकृत करें। ग्लेड न तो कंपाइलर है और न ही डिबगर। यह केवल आपको इंटरफ़ेस का वर्णन करने और इसे ग्लेडएक्सएमएल एक्सएमएल प्रारूप फाइलों में प्रस्तुत करने की अनुमति देता है।
जीटीके + लाइब्रेरी के लिए मूल इंटरफ़ेस सी है। लेकिन मैं इस उदाहरण में सी ++ का उपयोग करूंगा। तदनुसार, छोटी विशेषताएं दिखाई देंगी, जिसके बारे में मैं आपको बताऊंगा। लिनक्स वितरण मैं Ubuntu 10.04 का उपयोग कर रहा हूं।
कार्य यह होगा: एक कैनवास, एक साइड मेनू (कैनवास पर क्या चुनना है), मुख्य मेनू और स्थिति पट्टी से मिलकर एक छोटा अनुप्रयोग लिखें। एक ही समय में, साइड मेनू और कैनवास पूरे अनुप्रयोग विंडो का आकार बदलते समय स्थिर रहना चाहिए। लेकिन जिस कंटेनर में कैनवास स्थित है, उसका आकार मुख्य विंडो के आकार में वृद्धि / कमी के आधार पर बदल सकता है। और यदि आवश्यक हो, तो स्क्रॉलबार दिखाई देना चाहिए।
योजना इस प्रकार होगी:
- Glade3 स्थापित करें और लॉन्च करें
- हम ग्लेड 3 में अपने एप्लिकेशन का एक ग्राफिकल इंटरफेस बनाएंगे, मुख्य विंडो और कंटेनरों में मुख्य विजेट्स (ऑब्जेक्ट्स), विजेट्स और उनके हैंडलर (हैंडलर) के लिए घटनाओं (सिंगनल, सिग्नल) को परिभाषित करते हुए, अर्थात्। हमारे कार्यक्रम के कोड में प्रक्रिया, जिसे यह संकेत होने पर बुलाया जाएगा
- प्रोग्राम कोड लिखें: XML फ़ाइल को एक ग्राफिकल इंटरफ़ेस के साथ एकीकृत करें, हैंडलर और प्रदर्शन के लिए कुछ कार्यक्षमता लिखें
- हमारे आवेदन को थोड़ा परखें
ग्लेड 3 को स्थापित करें और लॉन्च करें
यह माना जाता है कि आपके पास पहले से ही जीटीके + देव पैकेज स्थापित है, यदि नहीं, तो आप इसे कंसोल के माध्यम से कर सकते हैं:
sudo aptitude install libgtk2.0-dev
आप उबंटू अपडेट सेंटर के माध्यम से या फिर कंसोल का उपयोग करके ग्लेड स्थापित कर सकते हैं:
sudo apt-get install glade-gnome
स्थापना के बाद, एप्लिकेशन - प्रोग्रामिंग - ग्लेड इंटरफ़ेस डिजाइनर के माध्यम से चलाएं
आकृति में दिखाए गए अनुसार सभी पैरामीटर सेट करें। संस्करण टूलकिट संस्करण 2.16 का चयन करें

बाईं ओर आप विभिन्न विजेट्स के एक सेट के साथ एक विंडो देख सकते हैं। जिन लोगों ने विंडोज फॉर्म या एक वातावरण में काम किया, डेल्फी डेवलपर्स जल्दी से इसका पता लगाएंगे। दाईं ओर दो मेनू हैं: एक विजेट पदानुक्रम दिखाता है, और दूसरा विंडो विजेट गुण विंडो दिखाता है।
जीयूआई निर्माण
अपने GTK + एप्लिकेशन के लिए एक ग्राफिकल इंटरफ़ेस बनाना मुख्य फॉर्म - प्रोग्राम की मुख्य विंडो को सेट करने के साथ शुरू होता है। हम बाएं मेनू के TopLevels अनुभाग में विंडो विजेट पाते हैं।
गुण विंडो में दाईं ओर, इस विजेट के गुण सेट करें:
नाम: topWindow
विंडोज स्थिति: केंद्र
डिफ़ॉल्ट चौड़ाई: 500
डिफ़ॉल्ट ऊंचाई: 320

हम सिग्नल टैब (सिग्नल, ईवेंट) और GtkObject को नष्ट करने के लिए जाते हैं, हैंडलर कॉलम (हैंडलर) में टॉपविन्डो_डस्ट्रो_cb लिखें या सूची से चयन करें। यह उस प्रक्रिया का नाम होगा जो नष्ट संकेत को संसाधित करेगा - मुख्य रूप को बंद करना।

इसके अलावा, हमारी योजना है कि हमारे आवेदन में एक मुख्य मेनू होना चाहिए, मुख्य कार्यात्मक भाग (यह कैनवास और मेनू को चुनने के लिए कि क्या आकर्षित करना है) और स्थिति पट्टी। कंटेनर अनुभाग में बाएं मेनू में वर्टिकल बॉक्स विजेट कंटेनर लें और इसे हमारे मुख्य रूप में रखें। दिखाई देने वाले संवाद में, आइटमों की संख्या चुनें: 3. इसका मतलब है कि हमारे द्वारा बनाए गए कंटेनर में 3 विगेट्स रखे जा सकते हैं।
हमारे पास vbox1 कंटेनर में 3 तथाकथित सेल या डिब्बे हैं। दूसरे (केंद्र) डिब्बे में, फ़्रेम (विजेट मेनू के कंटेनर अनुभाग) डालें। हम दाईं ओर विजेट ट्री को देखते हैं। बनाए गए विजेट फ्रेम 1 के अंदर दो विजेट होंगे: एलाइनमेंट 1 और लेबल 1 - उन्हें हटाया जा सकता है। हम इस पर थोड़ा विचलन करेंगे और सिद्धांत की ओर मुड़ेंगे।
यह समझना कि विजेट आकार को GTK + में कैसे प्रबंधित किया जाता है, सही और कुशल ग्राफिकल इंटरफेस बनाने के लिए बहुत महत्वपूर्ण है। इस प्रक्रिया को अक्सर अनुमोदन प्रक्रिया कहा जाता है, जिसमें दो घटक (2 चरण) होते हैं: अनुरोधित आकार और आवंटित आकार।
अनुरोध चरण एक पुनरावर्ती प्रश्न है: "आपको कितनी जगह की आवश्यकता है?" मुख्य विंडो इसे चाइल्ड विंडो पर सेट करती है, चाइल्ड विंडो इसे उनके चाइल्ड विंडो पर सेट करती है, और इसलिए जब तक कि इस पूरी पदानुक्रम प्रतिक्रिया में सभी विजेट नहीं मिलते।
2 महत्वपूर्ण बिंदु हैं:
- चाइल्ड विजेट पैरेंट विजेट साइज के बारे में कुछ नहीं जानते
- पैरेंट विजेट्स का आकार चाइल्ड विजेट्स के आकार पर निर्भर करता है
अब जब मुख्य विंडो को पता है कि आदर्श रूप से कितनी जगह की आवश्यकता है, तो इस बारे में निर्णय लिया जाता है कि वास्तव में कितनी जगह उपलब्ध होगी। यदि एक उचित मूल्य अनुरोध पर आया है, तो यह डिफ़ॉल्ट है। लेकिन अगर विंडो का आकार मैन्युअल रूप से सेट किया गया है (उदाहरण के लिए, gtk_window_setdefault_size का उपयोग करके) या अन्यथा, विंडो अनुरोधित आकार को छोड़ देती है और दूसरा सेट करती है।
दूसरे चरण में (आकार का आवंटन), माता-पिता से बच्चे के विजेट के लिए एक कमांड होता है: "यहां आपके पास कुछ जगह है, इसमें फिट होने के लिए सब कुछ करें।" यदि विजेट में एक से अधिक चाइल्ड विजेट हैं, तो इस चरण का कार्य बच्चे के विजेट के बीच मुक्त स्थान को ठीक से विभाजित करना है।
अब हम अपने आवेदन के मुख्य भाग को पास करते हैं। विजेट मेनू पर जाएं और कंटेनर अनुभाग में क्षैतिज पैन का चयन करें और इसे फ्रेम 1 पर रखें। हमें एक निश्चित आकार होने के लिए हमारे बाईं ओर की आवश्यकता है, दाईं ओर नहीं। फिर से, विजेट मेनू पर जाएं और वहां स्क्रॉल विंडो देखें। और पहले हम एक डालते हैं, और फिर बाएं और दाएं डिब्बे में दूसरी स्क्रॉल की गई विंडो hpand1 (क्षैतिज फलक)। स्क्रॉल किए गए विंडो में बाईं ओर स्क्रॉलडविंडो 1 कहा जाता है, संपत्ति सेट करें (सामान्य टैब में) चौड़ाई reguest 145 तक - इसका मतलब अनुरोधित आकार (मिलान प्रक्रिया के लिए) होगा। आपको यह भी जांचना चाहिए कि स्क्रॉलविंडो 1 की रिसाइज संपत्ति पैकिंग टैब में नहीं है और स्क्रॉलविंडो 2 हां है ।
कंटेनर सेक्शन से, हम पहले ViewPort विजेट को रखते हैं, और फिर हमारे स्क्रॉलडॉन्डवो 1 और स्क्रॉलडविंडो 2 दोनों पर क्रमशः दूसरा।

चलो हमारे साइड मेनू लेते हैं। 3 डिब्बों के साथ ViewPort1 कार्यक्षेत्र बॉक्स में जोड़ें। और प्रत्येक डिब्बे में रेडियो बटन जोड़ें। प्रत्येक रेडियो बटन के लिए, विस्तृत करें कोई गुण सेट न करें ताकि वे मूल विजेट के आकार में वृद्धि न करें। सामान्य टैब में भी, आप चौड़ाई और ऊँचाई अनुरोध को निर्दिष्ट कर सकते हैं, फिर वे जो हम निर्दिष्ट करते हैं उसका आकार होगा, और डिफ़ॉल्ट रूप से नहीं। लेकिन किसी भी मामले में, वे आकार में भिन्न होंगे। सामान्य टैब में उनके गुणों को बदलें:
क्रमशः rbutRectangle , rbutEllipse , rbutTriangle पर नाम
आयत , एलीप , त्रिभुज पर क्रमशः लेबल
और rbutEllipse और rbutTriangle के लिए हम एक विशेष संवाद का उपयोग करके समूह की संपत्ति rbutRectangle में निर्दिष्ट करते हैं।

यह इस तरह दिखना चाहिए:

अब आपको प्रत्येक रेडियो बटन के लिए घटनाओं को पंजीकृत करने की आवश्यकता है। सिग्नल टैब में, यह या तो GroupChanged इवेंट के लिए या toggled (मैं इसके लिए करूँगा) के लिए कोई बात नहीं है, हम rbutton_toggled_cb हैंडलर लिखेंगे:

अब हमारी विंडो के दाईं ओर मुड़ें। ViewPort2 में दो डिब्बों के साथ एक वर्टिकल बॉक्स जोड़ें। शीर्ष में हम सामान्य लेबल डालते हैं, और नीचे ड्राइंग क्षेत्र में - यह कैनवास होगा। लेबल 1 के लिए, लेबल गुण में, 300 x 200 कैनवस लिखें। पैकिंग टैब पर जाएं और सेट करें का विस्तार करें
अब हमारा कैनवास।
नाम: रेखाचित्र
व्यय: नहीं
चौड़ाई अनुरोध: 300
ऊंचाई का अनुरोध: 200
घटना: एक्सपोजर की जाँच करें
सिग्नल में, एक्सपोज़-ईवेंट की तलाश करें और सूची से लिखें या चुनें:
drawingarea_expose_event_cb

अब हमें स्टेटस बार (सबसे निचले डिब्बे में) और मुख्य मेनू (सबसे ऊपरी डिब्बे में) जोड़ने की जरूरत है। हमने मेनू बार (विजेट मेनू के कंटेनर अनुभाग) को बहुत ऊपर रखा है, स्टेटस बार (विजेट मेनू का नियंत्रण और प्रदर्शन अनुभाग) के बहुत नीचे डिब्बे में, इसे जोड़ने के बारे में एक संवाद दिखाई देगा, आइटम की संख्या का चयन करें: 1।

हमारे उदाहरण के लिए menubar1 में, हम केवल एक मेनू आइटम छोड़ देंगे - प्रोग्राम से बाहर निकलें। तदनुसार, आप हटा सकते हैं: menuitem2, menuitem3, menuitem4। फिर menuitem1 खोलें, menu1 पर जाएं और imagemenuitem5 को छोड़कर सब कुछ हटा दें। यह क्विट आइटम है। आप इस पर क्लिक कर सकते हैं और प्रॉपर्टी विंडो के जनरल टैब में स्टॉक आइटम प्रॉपर्टी को देख सकते हैं, जिसमें gtk-Skip दर्ज है। वहां आप "चारों ओर खेल सकते हैं।" आप आम तौर पर कस्टम लेबल और छवि का चयन कर सकते हैं और खुद को सब कुछ सेट कर सकते हैं। यह इतना महत्वपूर्ण नहीं है। सिग्नल टैब में imagemenuitem5 के लिए, फॉर्म को बंद करने के लिए सिग्नल के लिए सक्रिय सिग्नल (मेनू आइटम पर क्लिक करके) को उसी तरह सेट करें : topWindow_destroy_cb ।
इस तरह से हमारे इंटरफ़ेस को अंत में कैसा दिखना चाहिए। हम अपने प्रोजेक्ट को mainForm नाम से बचाते हैं। फ़ाइल को mainForm.glade कहा जाएगा

हमारे कार्यक्रम का कोड
फ़ाइल को उसी फ़ोल्डर में बनाएँ जहाँ आपने mainForm.glade को बचाया हो। पहले मैं पूरा कोड दूंगा, और फिर कुछ महत्वपूर्ण बिंदु बताऊंगा।
/* Example1.cpp */ #include <cairo.h> #include <gtk/gtk.h> #define UI_FILE "mainForm.glade" // GtkBuilder *builder; GtkWidget *topWindow; GtkRadioButton *rbutRectangle, *rbutEllipse, *rbutTriangle; GtkDrawingArea *drawingarea; // extern "C" void topWindow_destroy_cb (GtkObject *object, gpointer user_data); extern "C" gboolean drawingarea_expose_event_cb(GtkWidget *widget, GdkEventExpose *event, gpointer data); extern "C" void rbutton_toggled_cb (GtkObject *object); int main( int argc, char **argv ) { GError *error = NULL; // GTK+ gtk_init( &argc, &argv ); // GtkBuilder builder = gtk_builder_new(); // , Glade if( ! gtk_builder_add_from_file( builder, UI_FILE, &error ) ) { g_warning( "%s", error->message ); g_free( error ); return( 1 ); } // GladeXML topWindow = GTK_WIDGET(gtk_builder_get_object(builder, "topWindow")); rbutRectangle = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "rbutRectangle")); rbutEllipse = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "rbutEllipse")); rbutTriangle = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "rbutTriangle")); drawingarea = GTK_DRAWING_AREA(gtk_builder_get_object(builder, "drawingarea")); // gtk_builder_connect_signals (builder, NULL); // g_object_unref( G_OBJECT( builder ) ); // gtk_widget_show( topWindow ); // gtk_main(); return( 0 ); } // void topWindow_destroy_cb (GtkObject *object, gpointer user_data) { // gtk_main_quit(); } // gboolean drawingarea_expose_event_cb(GtkWidget *widget, GdkEventExpose *event, gpointer data) { cairo_t *cr; cr = gdk_cairo_create (widget->window); cairo_set_line_width (cr, 7); cairo_set_source_rgb (cr, 0, 0, 0); // if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rbutRectangle))) { // cairo_rectangle (cr, 20, 20, 200, 100); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 0, 0.8, 0); } // if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rbutEllipse))) { // cairo_arc(cr, 150, 100, 90, 0, 2 * 3.14); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 0.8, 0, 0); } // if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rbutTriangle))) { // cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_move_to (cr, 40, 40); cairo_line_to (cr, 200, 40); cairo_line_to (cr, 120, 160); cairo_line_to (cr, 40, 40); cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 0.8, 0, 0.8); } cairo_fill(cr); cairo_destroy(cr); return FALSE; } void rbutton_toggled_cb (GtkObject *object) { // drawingarea gtk_widget_queue_draw (GTK_WIDGET(drawingarea)); }
पहले हम उन वस्तुओं को घोषित करते हैं। हम किसके साथ काम करेंगे। फिर हम सिग्नल हैंडलर पंजीकृत करना शुरू करते हैं। क्योंकि हम C ++ में लिखते हैं, बाहरी "C" का उपयोग करके हम topWindow_destroy_cb घोषित करते हैं, Drawingarea_expose_event_cb, rbutton_toggled_cb को बाहरी कार्यों के रूप में दर्शाते हैं और संकेत देते हैं कि उन्हें C. ऑर्डर में बाध्यकारी क्रम के अनुसार जोड़ा जाना चाहिए। GtkBuilder में ग्लेड के वर्णन से सभी ऑब्जेक्ट्स के लिंक शामिल हैं। Gtk_builder_get_object फ़ंक्शन को GtkBuilder (इस मामले में, बिल्डर) से संबंधित नाम के साथ ऑब्जेक्ट का संदर्भ मिलता है। Gtk_builder_connect_signals फ़ंक्शन का उपयोग ग्लेडएक्सएमएल में संबंधित सिग्नल हैंडलर के साथ कोड में हैंडलर फ़ंक्शन को जोड़ने के लिए किया जाता है। ऐसा अपने आप होता है। यह महत्वपूर्ण है कि ग्लेड और कोड मैच में नाम। एप्लिकेशन सामान्य रूप से संकलित करेगा, बस संकेतों पर कार्रवाई नहीं की जाएगी, और यदि आप कंसोल के माध्यम से प्रोग्राम चलाते हैं, तो चेतावनी वहां प्रदर्शित की जाएगी कि इस तरह के और इस तरह के सिग्नल के लिए हैंडलर ढूंढना असंभव है।
भी, क्योंकि हम C ++ में लिखते हैं बहुत बार हमें स्पष्ट प्रकार के रूपांतरण का उपयोग करना पड़ता है। उदाहरण के लिए
rbutRectangle = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "rbutRectangle"));
अगर हमने C में लिखा है, तो हम GTK_RADIO_BUTTON के स्पष्ट भूत के बिना कर सकते हैं।
अपने कार्यक्रम को संकलित करने के लिए, आपको या तो एक स्वचालित निर्माण प्रणाली (उदाहरण के लिए सीएमके) का उपयोग करने की आवश्यकता है, या स्वयं एक मेफाइल पंजीकृत करें। मैं इस पर विस्तार से ध्यान नहीं दूंगा। मैं केवल मेकफाइल के विवरण का एक उदाहरण दूंगा। पोस्ट के अंत में, दो सबसे हाल की लिंक एक मेक फाइल के निर्माण की चिंता करते हैं।
CC=g++ LDLIBS=`pkg-config --libs gtk+-2.0 gmodule-2.0` CFLAGS=-Wall -g `pkg-config --cflags gtk+-2.0 gmodule-2.0` Example1: Example1.o $(CC) $(LDLIBS) Example1.o -o Example1 Example1.o: Example1.cpp $(CC) $(CFLAGS) -c Example1.cpp clean: rm -f Example1 rm -f *.o
संकलन कमांड के साथ होता है:
make
हमारे कार्यक्रम का थोड़ा परीक्षण
लॉन्च हो रहा है ...

... और फिर विंडो का आकार बदलें

जैसा कि हम साइड मेनू देखते हैं और कैनवास खिंचाव नहीं करता है और उसी आयाम में बना रहता है, लेकिन जिस कंटेनर में कैनवास ने अपने आयाम बदल दिए हैं। और फार्म के आकार में वृद्धि के साथ दिखाई देने वाले सभी मुक्त स्थान उसके पास गए। यह सब इसलिए है क्योंकि हमने स्क्रॉलविंडो 1 चौड़ाई रीजेंट = 145 सेट किया है और हां का आकार बदला है। स्क्रॉलबार का एक उदाहरण यहां दिखाई दे रहा है, क्योंकि मुख्य विंडो छोटी हो गई है

अब, मैं ग्लेड 3 में जाऊंगा और लेबल 1 की विस्तार संपत्ति को हां में बदलूंगा। परियोजना को पुन: स्थापित करने की आवश्यकता नहीं है। बस मेनफॉर्म फाइल को सेव करें। और यहाँ परिणाम है:

ऐसा क्यों? हमारे पास एक निश्चित आकार का कैनवास है। और मुख्य विंडो बड़ा होने पर प्राप्त होने वाली सभी जगह लेबल 1 विजेट को दी गई है। आप इस सभी व्यवसाय के साथ "खेल सकते हैं"। उदाहरण के लिए, सेटिंग को वापस नहीं में विस्तारित करें और सटीक ऊँचाई मान निर्दिष्ट करें, उदाहरण के लिए 70। और फिर फिर से एक निश्चित आकार होगा, लेकिन डिफ़ॉल्ट रूप से नहीं, लेकिन वह जिसे आप निर्दिष्ट करते हैं।
यह इस पोस्ट को समाप्त करता है। यदि यह विषय दिलचस्प है, तो मुझे इस दिशा में और अधिक पोस्ट लिखने की इच्छा है।
थोडा सिद्धांत Glade3 ट्यूटोरियल - आकार बातचीत से लिया गया है।
मैं आपको पढ़ने की सलाह देता हूं: पैकिंग विजेट , काहिरा ग्राफिक्स ट्यूटोरियल , उदाहरण के लिए मेकफाइल्स , जीएनयू `मेक '