تحياتي ، زملائي!
منذ حوالي شهر ، نشرت مقالًا هنا حول
أطر عمل واجهة المستخدم الرسومية - سلسلة رسائل تقترح تقنية لإنشاء أطر عمل واجهة المستخدم الرسومية للغات البرمجة المختلفة ، بناءً على الاتصال (tcp / ip أو بعض اللغات الأخرى) بعملية خارجية تلعب دور نوع خادم واجهة المستخدم الرسومية. أود هنا تقديم تنفيذ ملموس لهذه الفكرة - إطار واجهة المستخدم الرسومية الجديد لـ
Golang -
External .
لماذا كان من الضروري كتابة واجهة مستخدم رسومية جديدة لـ
Golang ، إذا كان هناك بالفعل العديد من هذه الأدوات المتاحة؟ بادئ ذي بدء ، لأن أياً منهم لم يناسبني على أكمل وجه. هناك حاجة إلى إنشاء تطبيقات سطح المكتب ، عبر النظام الأساسي ، لتبدو طبيعية لكل منصة. إذا كان ذلك ممكنًا ، وليس ضخمًا جدًا ، مع حد أدنى من التبعيات - فأنا ملتزم بنهج الحد الأدنى.
لقد استرشدت
بهذه القائمة . تم شطب موقعين -
التطبيق والمشي على الفور لأنه لا يفي بمتطلبات النظام الأساسي. بعد بعض التفكير ، رفض تلك القائمة على html / css / javascript. أولاً ، يبدو لي من غير المعتاد إلى حد ما إنشاء تطبيق سطح مكتب كصفحة ويب ، وثانياً ، يقومون بسحب محركات ثقيلة جدًا معهم. لذلك ، على سبيل المثال ، تعتمد
go-astilectron و
gowd على
Electron و
nw.js ، على التوالي ، وهذه بدورها تعتمد على
node.js. تخيل كم يجب تثبيت كل شيء من قبل المستخدم النهائي لتشغيل حتى فائدة صغيرة؟ ما لم يكن
الذهاب إلى الكاتبة المفضل من وجهة النظر هذه:
فالقفيء الذي يقف وراءه ليس وحشيًا جدًا.
تعتمد Go-gtk و
gotk3 على GTK. هذه ، على ما يبدو ، عبارة عن حزم مُصنَّعة بدقة ، لكنني رفضتها أيضًا ، لأنني أعتقد أن استخدام GTK ضمن Windows ليس هو الحل الأفضل. نوافذ GTK لا تبدو أصلية تحت ويندوز. ربط
Qt هو شيء قوي ، بالطبع ، ولكنه معقد إلى حد ما ، والأبعاد ... عندما قرأت: "أنت بحاجة أيضًا إلى ذاكرة وصول عشوائي خالية تبلغ 2.5 غيغابايت (لا يلزم إلا أثناء الإعداد الأولي) ومساحة خالية على القرص 5 غيغابايت على الأقل" ، اختفت الشكوك الأخيرة. الذهاب نفسه يستغرق مساحة عشر مرات أقل. ثم هناك قيود ترخيص: "هذا الارتباط مع ترخيص LGPL الخاص به غير مناسب لاستخدامه في تطبيق مفتوح المصدر يقصد توزيعه على الجمهور العام".
ماذا تركنا من القائمة؟ قد تكون
واجهة المستخدم خيارًا جيدًا ، لكنها لا تزال في مرحلة منتصف ألفا. تبدو
فين أيضًا جيدة ، لكن لا يبدو أنها جاهزة تمامًا. لقد كان الأمر محرجًا إلى حد ما ، من ناحية ، أن "Fyne مبني بالكامل باستخدام الرسومات المتجهة" ، ومن ناحية أخرى ، "حزم نوافذ EFL أقدم حاليًا حتى لا ترى أجزاء الرسومات المتجهة من تطبيقات Fyne" - مثل هذا. حسنًا ، لا يعجبني ذلك من أجل تثبيت
EFL (مكتبة الرسومات التي يعتمد عليها
Fyne ) على Windows ، فأنت بحاجة إلى
MSYS .
باختصار ، مع كل الاحترام الواجب لمؤلفي هذه الحزم ونواتج عملهم ، لم أختر أي شيء بنفسي ، وضميرًا واضحًا إلى ما أردت القيام به - كتابة إطار عمل جديد لمعلومات واجهة المستخدم -
خارجي .
كما كتبت في مقالة سابقة ، لا يقوم
External بتطبيق عناصر واجهة المستخدم الرسومية من تلقاء نفسه ، بل يستخدم تطبيقًا منفصلاً لذلك ، عملية منفصلة تعمل
كخادم واجهة المستخدم الرسومية ، ويسمى هذا التطبيق
GuiServer .
يقوم External بتدشينه ، وينضم إليه عبر tcp / ip ، ويرسل أوامر / طلبات لإنشاء النوافذ وعناصر واجهة التعامل ، ومعالجتها ، وما إلى ذلك ، ويستقبل الرسائل منه.
إليك برنامج بسيط يقوم بإنشاء نافذة بها نقش تقليدي Hello، world:
package main import egui "github.com/alkresin/external" func main() { if egui.Init("") != 0 { return } pWindow := &egui.Widget{X: 100, Y: 100, W: 400, H: 140, Title: "My GUI app"} egui.InitMainWindow(pWindow) pWindow.AddWidget(&egui.Widget{Type: "label", X: 20, Y: 60, W: 160, H: 24, Title: "Hello, world!" }) pWindow.Activate() egui.Exit() }
تبدأ الدالة Init ()
GuiServer وتنضم إليها. يمكن تمرير معلمة السلسلة إليها ، والتي تحدد ، إذا لزم الأمر ، اسم
GuiServer ومساره وعنوان IP ومنفذ التسجيل ومستوى التسجيل.
ينشئ InitMainWindow () إطار التطبيق الرئيسي مع المعلمات المحددة. الأسلوب AddWidget () - لإضافة عنصر واجهة مستخدم لتسمية النوع.
تنشيط () - يعرض نافذة على الشاشة ويضع البرنامج في وضع الاستعداد.
يتم تعريف كل من النوافذ والحاجيات في بنية عنصر واجهة المستخدم - لم أقوم بإنشاء هياكل منفصلة لكل كائن ، لأن لم أجد طريقة ملائمة لتنفيذ ذلك ، بالنظر إلى أن
Go لا تملك الميراث. تتضمن هذه البنية الحقول الشائعة لمعظم عناصر واجهة التعامل ، وسلسلة الخريطة [سلسلة] ، والتي تحتوي على خصائص خاصة بكائن معين:
type Widget struct { Parent *Widget Type string Name string X int [...] Font *Font AProps map[string]string aWidgets []*Widget }
تتضمن أساليب هذه البنية AddWidget () المألوف ، وكذلك SetText () ، SetImage () ، SetParam () ، SetColor () ، SetFont () ، GetText () ، Move () ، Enable () ، إلخ. أود أن أذكر SetCallBackProc () و SetCallBackFunc () - لإعداد معالجات الأحداث.
سيكون من غير المناسب سرد جميع الوظائف ، والهياكل ، والأساليب هنا ، لأنه يوجد بشكل أكثر دقة. يجب أن يكون هناك وثائق. سأقول القليل فقط لإعطاء فكرة عامة:
Menu () ، MenuContext () ، EndMenu () ، AddMenuItem () ، AddMenuSeparator () - مجموعة من الوظائف لإنشاء قائمة ، رئيسية أو سياق.
تمرير EvalProc (سلسلة sCode) ، يمرر EvalFunc (سلسلة sCode) جزءًا من رمز Harbour (يمكن أن يكون متعدد الأسطر) للتنفيذ على GuiServer - وهو نوع من تنفيذ لغة البرمجة النصية المضمّنة.
يقوم OpenForm (سلسلة sPath) - بإنشاء نافذة بناءً على الوصف من ملف xml الذي تم إنشاؤه بواسطة HwGui Designer.
OpenReport (سلسلة sPath) - طباعة تقرير بناءً على الوصف من ملف xml الذي تم إنشاؤه بواسطة HwGui Designer.
MsgInfo () ، ... ، SelectFile () ، SelectColor () ، SelectFont () - استدعاء مربعات حوار ومربعات حوار قياسية.
يوفر InitPrinter () ومجموعة من أساليب بنية الطابعة: Say () ، Box () ، Line () ، إلخ. الطباعة إلى الطابعة مع إمكانية المعاينة.
هنا قائمة كاملة من الحاجيات المدعومة حاليا:
تسمية ، تحرير ، زر ، فحص ، راديو ، راديو ، مجموعة ، تحرير وسرد ، صورة نقطية ، خط ، لوحة (مصممة لاستضافة عناصر واجهة مستخدم أخرى عليها) ، paneltop ، panelbot ، ownbtn (زر ownerdrawn) ، التقسيم ، التحديث ، شجرة ، التقدم ، علامة تبويب ، تصفح (جدول ، يسميه كثيرون) ، cedit (تحرير بميزات متقدمة) ، monthcal.
يتم سرد كل منهم في وظيفة init () من extwidg.go جنبا إلى جنب مع خصائص إضافية. يمكن الوصول إليها لكل منها - يتم تعيين هذه الخصائص من خلال Widget.AProps. العديد من هذه الحاجيات لها خصائص أخرى ، خاصة التصفح الغنية بها ؛ يمكن تعيينها بشكل منفصل باستخدام الأسلوب SetParam ().
تحولت
الخارجية إلى أن تكون صغيرة في حجمها ، هو مكتوب في
Go النقي ، فإنه لا يسحب حزم أخرى باستثناء عدد قليل منها القياسية. يتم توفير النظام الأساسي
المتقاطع بواسطة
GuiServer ، والذي يمكن تجميعه ضمن أنظمة التشغيل Windows و Linux / Unix و Mac OS. يرتبط إزعاج معين على وجه التحديد بالحاجة إلى استخدام هذه الوحدة الخارجية ، والتي تحتاج إما إلى تجميعها من المصادر ، أو تنزيل واحدة منتهية من موقعي ووضعها في الدليل المحدد في PATH. بالمناسبة ، فهو صغير - فقط حوالي ميغابايت ونصف لنظام التشغيل Windows وحوالي ثلاثة - لنظام التشغيل Linux.
كيف يبدو الأمر ، سأريك مثالاً على تطبيق
ETutor صغير - البرنامج التعليمي Golang. يقدم هذا البرنامج مجموعة من أجزاء التعليمات البرمجية على Go في شكل شجرة. يمكن تحرير الكود وتشغيله للتنفيذ. لا شيء خاص ، ولكن مريح جدا. يمكن تجديد المجموعة ، إضافة مجموعات جديدة. الآن هناك مجموعة (ليس بالكامل بعد) جولة من Go ، Go by Example والعديد من الأمثلة على
External نفسه. يمكن استخدام
ETutor أيضًا ، على سبيل المثال ، لتنظيم مجموعة من الأدوات المساعدة أثناء
التنقل . لذلك ، لقطات.
ويندوز 10:

دبيان ، غنوم:

وأخيرا ، الروابط:
الخارجية على جيثبGuiServer على جيثبETutor على جيثبصفحة حول GuiServer على موقع الويب الخاص بي حيث يمكنك تنزيل ثنائيات جاهزةhttps://groups.google.com/d/forum/guiserver - مجموعة لمناقشة جميع المشكلات المتعلقة بـ GuiServer و External
مقال عن GuiServer عن حبري