Golang GUI: GTK + 3

قررت كتابة تطبيق واحد لسطح المكتب عبر النظام الأساسي على Go . صنع إصدار CLI ، كل شيء يعمل بشكل جيد. نعم ، ويتم دعم الترجمة المتقاطعة في Go . كل شيء على ما يرام بشكل عام. ولكن هناك حاجة أيضًا إلى إصدار واجهة المستخدم الرسومية . ثم بدأت ...


جولانج جوتك 3


اختيار مكتبة (ملزمة) لواجهة المستخدم الرسومية


كان من المفترض أن يكون التطبيق عبر الأنظمة الأساسية.
لذلك ، يجب أن يتم تجميعه تحت Windows و GNU / Linux و macOS .
وقع الاختيار على مثل هذه المكتبات:



إلكترون وإطارات عمل أخرى تسحب Chromium و node.js معي ، لقد رميت لأنها تزن الكثير جدًا ، وتستهلك أيضًا الكثير من موارد نظام التشغيل.


الآن القليل عن كل مكتبة.


جوتك 3


مكتبة GTK + 3 ملزمة . التغطية بعيدة كل الاحتمالات ، ولكن كل الأساسيات موجودة.


يتم تجميع التطبيق باستخدام إصدار go build القياسي. التجميع عبر الأنظمة الأساسية ممكن باستثناء macOS . فقط مع macOS يمكن تجميعه لنظام التشغيل هذا ، حسنًا ، مع macOS يمكن تجميعه لنظام Windows + GNU / Linux أيضًا .


ستبدو الواجهة أصلية في GNU / Linux و Windows (ستحتاج إلى تحديد موضوع خاص). بالنسبة لنظام التشغيل macOS ، لن يبدو الأصلي. يمكنك الخروج فقط ما لم يكن هناك موضوع رهيب يحاكي عناصر macOS الأصلية.


therecipe / qt


مكتبة ملزمة كيو تي 5 . دعم QML ، الحاجيات القياسية. بشكل عام ، ينصح الكثير من الناس بهذا الإلزام.


qtdeploy باستخدام الأمر الخاص qtdeploy . بالإضافة إلى منصات سطح المكتب ، هناك أيضًا منصات متنقلة. يتم تجميع عبر باستخدام Docker . بالنسبة لأنظمة التشغيل ، لا يمكن تجميع Apple إلا مع macOS .


إذا رغبت في ذلك ، على Qt ، يمكنك جعل الواجهة تبدو أصلية على نظام تشغيل سطح المكتب.


zserge / webview


المكتبة ، التي كُتبت في الأصل باللغة C ، ثبتها المؤلف بالعديد من اللغات ، بما في ذلك Go . يتم استخدام عرض الويب الأصلي للعرض: Windows - MSHTML و GNU / Linux - gtk-webkit2 و macOS - Cocoa / WebKit . بالإضافة إلى التعليمات البرمجية على Go ، ستحتاج إلى الكتابة على JS أيضًا ، وسوف يكون HTML مفيدًا.


يتم تجميعها باستخدام go build ، ويمكن إجراء التجميع المتقاطع مع xgo .


يمكن أن يبدو أصليًا بقدر ما يسمح به المتصفح القياسي.


الاختيار


لماذا اخترت gotk3 ؟


في therecipe / qt ، لم يعجبني النظام المعقد جدًا لبناء التطبيق ، بل قاموا بإجراء أمر خاص.


يبدو أن zserge / webview ليس سيئًا ، ولن يزن كثيرًا ، ولكنه لا يزال عرضًا على الويب وقد تكون هناك مشاكل قياسية في مثل هذه التطبيقات: ربما في مكان ما للذهاب إليه في مكان ما. وهذا ليس إلكترون ، حيث يتم تضمين Chromium المتقدم دائمًا ، ولكن في بعض أنظمة التشغيل Windows القديمة يمكن أن يذهب كل شيء. بالإضافة إلى ذلك ، يجب عليك أيضًا الكتابة في JS .


اخترت gotk3 كمتوسط. يمكنك بناءه باستخدام الإصدار القياسي من go build ، وهو يبدو مقبولًا ، وفي الواقع أحب GTK + 3 !


بشكل عام ، اعتقدت أن كل شيء سيكون بسيطًا. وما عبثًا في Go يقولون أنهم يعانون من مشكلة في واجهة المستخدم الرسومية . ولكن كم كنت مخطئا ...


الشروع في العمل


قم بتثبيت كل شيء من gotk3 ( gtk ، gdk ، glib ، cairo ) إلى أنفسنا:


 go get github.com/gotk3/gotk3/... 

أيضًا ، يجب تثبيت مكتبة GTK + 3 نفسها على نظامك للتطوير.


غنو / لينكس


في أوبونتو :


 sudo apt-get install libgtk-3-dev 

في Arch Linux :


 sudo pacman -S gtk3 

macOS


عبر Homebrew :


  brew install gtk-mac-integration gtk+3 

نوافذ


الأمر ليس بهذه البساطة هنا. تقترح التعليمات الرسمية استخدام MSYS2 وتفعل كل شيء فيه بالفعل. أنا شخصياً كتبت تعليمات برمجية على أنظمة تشغيل أخرى ، وقمت بتجميع متقاطع لـ Windows في Arch Linux ، والتي آمل أن أكتبها قريبًا.


مثال بسيط


الآن نكتب ملف صغير برمز main.go :


 package main import ( "log" "github.com/gotk3/gotk3/gtk" ) func main() { //  GTK. gtk.Init(nil) //    ,   //     "destroy"     //     win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL) if err != nil { log.Fatal("   :", err) } win.SetTitle(" ") win.Connect("destroy", func() { gtk.MainQuit() }) //         l, err := gtk.LabelNew(", gotk3!") if err != nil { log.Fatal("   :", err) } //     win.Add(l) //      win.SetDefaultSize(800, 600) //      win.ShowAll() //    GTK ( ).    //  gtk.MainQuit() gtk.Main() } 

يمكنك الترجمة باستخدام go build ثم تشغيل الملف الثنائي. لكننا نديرها فقط:


 go run main.go 

بعد البدء ، نحصل على نافذة من هذا النوع:


مثال بسيط على Golang gotk3


مبروك! لقد حصلت على تطبيق بسيط من README gotk3 !


يمكن العثور على مزيد من الأمثلة على Github gotk3 . لن أقوم بتفكيكها. من الأفضل أن نفعل شيئًا غير موجود في الأمثلة!


سعيد


هناك شيء من هذا القبيل ل Gtk + 3 - Glade . هذا مصمم رسومية لـ GTK + . يبدو شيء مثل هذا:


سعيد


من أجل عدم إنشاء كل عنصر يدويًا وعدم وضعه لاحقًا في مكان ما في النافذة باستخدام رمز البرنامج ، يمكنك إلقاء التصميم بالكامل في Glade . ثم احفظ كل شيء في ملف XML. * glade وتحميله من خلال تطبيقنا.


تثبيت Glade


غنو / لينكس


في توزيعات غنو / لينكس ، من السهل تثبيت الفسحة . في بعض أوبونتو ، سيكون:


 sudo apt-get install glade 

في Arch Linux :


 sudo pacman -S glade 

macOS


التنزيلات من الموقع الرسمي قديمة جدًا. لذلك ، من الأفضل التثبيت من خلال Homebrew :


 brew install glade 

ثم قم بتشغيل:


 glade 

نوافذ


يمكنك تنزيل أحدث إصدار هنا . أنا شخصياً لم أقم بتثبيته على Windows على الإطلاق ، لذلك لا أعرف عن استقرار Glade هناك.


تطبيق بسيط باستخدام Glade


بشكل عام ، صممت شيئًا مثل هذه النافذة:


سعيد


حفظ main.glade ملف main.glade :


 <?xml version="1.0" encoding="UTF-8"?> <!-- Generated with glade 3.22.1 --> <interface> <requires lib="gtk+" version="3.20"/> <object class="GtkWindow" id="window_main"> <property name="title" translatable="yes"> Glade</property> <property name="can_focus">False</property> <child> <placeholder/> </child> <child> <object class="GtkBox"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="margin_left">10</property> <property name="margin_right">10</property> <property name="margin_top">10</property> <property name="margin_bottom">10</property> <property name="orientation">vertical</property> <property name="spacing">10</property> <child> <object class="GtkEntry" id="entry_1"> <property name="visible">True</property> <property name="can_focus">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkButton" id="button_1"> <property name="label" translatable="yes">Go</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> <object class="GtkLabel" id="label_1"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">This is label</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">2</property> </packing> </child> </object> </child> </object> </interface> 

أي أننا حصلنا على النافذة window_main ( GtkWindow ) ، التي داخل الحاوية ( GtkBox ) ، والتي تحتوي على حقل الإدخال button_1 ( GtkButton ) GtkButton ( GtkButton ) و label_1 ( GtkLabel ). بالإضافة إلى ذلك ، هناك أيضًا سمات الأخطاء (لقد قمت بتكوين القليل) ، والرؤية والسمات الأخرى التي أضافها Glade تلقائيًا.


دعنا الآن نحاول تحميل هذا العرض في main.go :


 package main import ( "log" "github.com/gotk3/gotk3/gtk" ) func main() { //  GTK. gtk.Init(nil) //   b, err := gtk.BuilderNew() if err != nil { log.Fatal(":", err) } //       Glade err = b.AddFromFile("main.glade") if err != nil { log.Fatal(":", err) } //      ID obj, err := b.GetObject("window_main") if err != nil { log.Fatal(":", err) } //       gtk.Window //     "destroy"     //     win := obj.(*gtk.Window) win.Connect("destroy", func() { gtk.MainQuit() }) //      win.ShowAll() //    GTK ( ).    //  gtk.MainQuit() gtk.Main() } 

تشغيل مرة أخرى:


 go run main.go 

ونحصل على:


غولاند غليد غوتك


مرحى! الآن نحمل إرسال النموذج في ملف main.glade XML ، والرمز في main.go !


الإشارات


تبدأ النافذة ، لكن دعنا نضيف تفاعلًا. اسمح للنص من حقل الإدخال عند النقر فوق الزر بالدخول إلى الملصق.


للقيام بذلك ، نحصل أولاً على عناصر حقل الإدخال والزر والتسمية في الرمز:


 //    obj, _ = b.GetObject("entry_1") entry1 := obj.(*gtk.Entry) //   obj, _ = b.GetObject("button_1") button1 := obj.(*gtk.Button) //   obj, _ = b.GetObject("label_1") label1 := obj.(*gtk.Label) 

لا أتعامل مع الأخطاء التي GetObject() الدالة GetObject() لجعل التعليمات البرمجية أبسط. ولكن في تطبيق عمل حقيقي ، يجب معالجتها.


جيد. باستخدام الكود أعلاه ، نحصل على عناصر النموذج. الآن دعنا نتعامل مع إشارة الزر الذي تم clicked (عند الضغط على الزر). إشارة GTK + هي في الأساس رد فعل على الحدث. أضف الكود:


 //      button1.Connect("clicked", func() { text, err := entry1.GetText() if err == nil { //       label1.SetText(text) } }) 

الآن قم بتشغيل الكود:


 go run main.go 

بعد إدخال بعض النص في الحقل والنقر فوق الزر انتقال ، سنرى هذا النص في التسمية:


إشارة Golang Glade gotk3


الآن لدينا تطبيق تفاعلي!


الخلاصة


في هذه المرحلة ، يبدو كل شيء بسيطًا وليس صعبًا. ولكن واجهت صعوبات في الترجمة المتقاطعة (لأن برنامج gotk3 تم تجميعه مع CGO ) ، والتكامل مع أنظمة التشغيل ومع مربع حوار اختيار الملف. حتى أضفت مربع حوار أصلي إلى مشروع جوتك . أيضا ، يحتاج مشروعي إلى التدويل. هناك أيضًا بعض الميزات. إذا كنت مهتمًا برؤية كل هذا الآن في الرمز ، فيمكنك إلقاء نظرة خاطفة هنا .


أكواد المصدر لأمثلة من المقالة هنا .


وإذا كنت تريد قراءة التكملة ، يمكنك التصويت. وفي حال تبين أنها مثيرة للاهتمام لشخص ما ، سأستمر في الكتابة.

Source: https://habr.com/ru/post/ar420035/


All Articles