نصنع تطبيق سطح المكتب الأصلي عبر النظام الأساسي على Angular

الزاوي-nodegui


كما تعلم بالفعل ، فإن الزاوي موجود بالفعل على العديد من المنصات:



حسنًا ، بالطبع ، لم يكن هناك ما يكفي من سطح المكتب هنا (دعونا لا نتحدث عن الإلكترون حتى الآن).


لإنشاء تطبيقات سطح المكتب ، هناك العديد من الحلول التي تستخدم القوالب ، على سبيل المثال ، حلول مثل JavaFx و Qt و WPF. كل منهم ، باستثناء الأخير ، عبر منصة.


ولكن ماذا لو أردنا استخدام الإطار المألوف وتقديم تطبيق أصلي عليه؟ في الواقع ، هذا ما فعلته.


بادئ ذي بدء ، نظرت إلى ما هو متاح حاليًا ، وما الذي قد تم فعله بالفعل تحت الزاوي.


في الحقيقة ، بهذه الطريقة أود أن أوضح أنه يمكنك فعل أي شيء على الزاوي ، وكنت أقوم بكل أنواع الأشياء لعدة سنوات متتالية.

بحث


libui عقدة


إنها مكتبة GUI خفيفة الوزن ومحمولة تعمل على تعزيز الميزات الأصلية لـ GUI لكل منصة تدعمها. يتعلق الأمر بديلاً للإلكترون.


مثال تطبيق بسيط:


const win = new libui.UiWindow('Test window', 800, 600, false); 

تحت الغطاء ، لديه المجلدات libui بسيطة. (libui: مكتبة واجهة المستخدم الرسومية المحمولة لـ C). كل هذا يمر عبر node-gyp ، وهي أداة مصممة لتجميع الامتدادات الأصلية لـ Node.js. تشتمل عقدة libui على أكثر من 30 مكونًا جاهزًا ، وإذا قررت فجأة إنشاء شيء مخصص ، فستحتاج إلى الغوص في الشفرة في C. وإلى جانب ذلك ، تمت كتابة المكونات نفسها قبل عامين ، ومنذ ذلك الحين المحدثة. ربما يكون كل شيء جيدًا لدرجة أنه لا توجد حاجة لإجراء تغييرات ، وهذه المكونات الثلاثين كافية للتطوير ، أو لا يحتاج أي شخص إلى المشروع على الإطلاق.


حسنًا ، في الواقع ، قد يبدو التطبيق النهائي كما يلي:


libui عقدة libui عقدة


البروتون الأصليين و Vuido


وهنا أكثر إثارة للاهتمام قليلاً ، فالبروتون الأصلي والفييدو هو نفس عقدة libui ، فقط تحت React و Vue. تتم كتابة الأغلفة المقابلة تحت مكونات عقدة libui. على الرغم من عدد النجوم على github (9k و 6k) ، يتم التخلي عن المشاريع ، ولا يستخدمها أحد تقريبًا. من بين كل ما استطعت إيجاده ، كانت هذه تطبيقات بسيطة للغاية. المشكلة الأخرى التي اكتشفتها هي مشاكل تخصيص واجهة المستخدم نفسها ، ومن المستحيل القيام بذلك في إطار libui ، ويفكر مؤلف المشروع في إعادة كتابة كل شيء في Qt.


Libui نفسها تحظى بشعبية كبيرة لكتابة جميع أنواع الارتباطات ، جرها المتحمسين حتى في php

قد يبدو التطبيق النهائي كما يلي:


بروتون أصلية بروتون أصلية


واجهة مملة إلى حد ما دون تخصيص ، لذلك اختفى هذا الخيار على الفور.


أو ربما تأخذ كيو تي؟


كيو تي ، شبيبة ، المغلق


بالطبع سمعت عن كيو تي ، وحقيقة أنه يمكن العثور عليها في كل مكان ، ولكن لم يسمع الكثيرون أنه تم دمجها الآن مع جافا سكريبت خارج الصندوق. يسمح QML بالبناء التعريفي لواجهات المستخدم باستخدام روابط الخصائص ، وبالتالي زيادة قدرة عناصر QML الحالية. بالطبع ، هذا هو جافا سكريبت أكثر صرامة من على شبكة الإنترنت. يمكنك كتابة شيء مشابه لـ ES5 باستخدام كائنات QML ، ولكن لن يكون لديك واجهة برمجة تطبيقات DOM.


مجرد ملاحظة سريعة ، كيف تكتب في كيو تي تحت C ++:


 #include <QApplication> #include <QPushButton> int main(int argc, char *argv[]) { QApplication app(argc, argv); *// Important * QPushButton hello("Hello world!"); hello.resize(100, 30); hello.show(); return app.exec(); *// Important *} 

كيف يبدو رمزك في Qml:


 Item { function factorial(a) { a = parseInt(a); if (a <= 0) return 1; else return a * factorial(a - 1); } MouseArea { anchors.fill: parent onClicked: console.log(factorial(10)) } } 

يمكن إنشاء هذه المكونات بشكل حيوي.


يحتوي QML أيضًا على نظام كتابة كبير ، والذي سيكون بلا شك مفيدًا عند تحديد كل هذا في Typescript.


يمكنك أيضًا تخصيص المكونات بسهولة:


 Reactangle { id: redRectId width: 50 color: red } 

تقريبا CSS ، أليس كذلك؟


كل ما تبقى يجب إضافته هو ما يمكن لـ Qt القيام به على معظم الأنظمة الأساسية.


وسيكون لدينا Node.js


عند البحث عن "nodejs + qt" ، سوف نحصل على الفور على العقدة-qt ، لكنه يلفت انتباه العين على الفور أن المنتج قد مات منذ فترة طويلة ، وأظهرت آخر مرة علامات على الحياة منذ 8 سنوات.


ومع ذلك ، في البحث يمكنك العثور على مشروع جديد جدا - NodeGui.


NodeGui


مثل العديد من مكتبات واجهة المستخدم الرسومية ، تستخدم كيو تي حلقة الأحداث / الرسائل لمعالجة الأحداث من الحاجيات. لذلك ، عندما ندعو app.exec () بشكل مشروط ، تبدأ Qt في تشغيل حلقة الرسائل وحظرها هناك. كل هذا جيد عندما يكون هناك حلقة رسالة واحدة فقط في التطبيق بأكمله. ولكن نظرًا لأننا نحتاج إلى استخدام Qt مع NodeJs ، وللأخير أيضًا حلقة أحداث خاصة به ، فمن المستحيل دمجها بسهولة. ولكن تم اتخاذ مثل هذه القرارات بالفعل ، على سبيل المثال ، الحزمة نفسها مع Electron أو yode. هذه الحلول لها خصوصية خاصة بها ، فهي ترفع عمليتين على الأقل - للخيط الرئيسي ، وللعارض. على الرغم من هذا ، فإن هذا النهج له مكسب كبير ، لا حاجة لتعديل NodeJs أو Chromium.


في حالة NodeGui ، يكون الموقف مختلفًا قليلاً ، فهناك عملية واحدة لكل شيء ، وبالتالي ، ليست هناك حاجة لتلاعب الأحداث بين العمليات. تم تفرع Nodejs لهذا - وأدخلت تحسينات طفيفة على المجلدات اللازمة في كيو تي. والآن أنت بحاجة إلى بدء العملية ليس كالعادة main.js ، لكن qode main.js. لحسن الحظ ، يتم نشر qode كوحدة npm في حزمة @ nodegui / qode. من أجل بدء عالم hello بسيط ، تحتاج إلى تثبيت عدد قليل من الحزم ، لمزيد من التفاصيل لكل نظام تشغيل يمكنك مشاهدته على الموقع الرسمي: https://docs.nodegui.org/docs/guides/getting-started


بشكل افتراضي ، في nodegui ، كل شيء عبارة عن عنصر واجهة مستخدم ، ويمكن تثبيته في قوالب مختلفة. يوجد حاليًا نوعان من القوالب في nodegui: FlexLayout و QGridLayout.


الأنماط في Nodegui


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


 widget.setInlineStyle(`color: green`) view.setStyleSheet(` `#helloLabel { color: red; padding: 10px; } #worldLabel { color: green; padding: 10px; } #rootView { background-color: black; } `); 

يدعم Qt افتراضيًا جميع محددات CSS2 ( https://doc.qt.io/qt-5/stylesheet-syntax.html#selector-types )


كما لا يتم الاستغناء عن الخصائص المخصصة لمكونات التصميم. لحسن الحظ ، تم وصف هذه الخصائص بالفعل في أرصفة كيو تي وتمضغ على stackoverflow.


 *QPushButton* { qproperty-iconsize: 20px 20px; } 

زاوي


قام مؤلف المشروع بتنفيذ الدعم للرد فعلًا ، ولكن بالطبع نسي الجميع وجود Angular.

كما هو مكتوب بالفعل في البداية ، يمكن أن تقوم Angular بمعظم المنصات ، ولكن حتى الآن لم يكن هناك نظام أساسي لسطح المكتب. نظرًا لواجهة برمجة التطبيقات (API) Angular المصممة جيدًا والمنظمة ، فإن تطبيق nodegui ضمن Angular يكمن في كتابة نظام أساسي مخصصBrowserDynamic مع Renderer واستبداله في التطبيق.


ولكن كيف يعمل كل شيء من الداخل إلى الخارج؟


لدينا مفتاح مشروط ، وسنبدأ به.


تتكون عملية التمهيد من جزأين: إنشاء نظام أساسي وإلقاء وحدة بدء فيه.


 platformBrowserDynamic().bootstrapModule(AppModule); 

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


في وحدة البدء ، نصف العنصر الذي يجب تقديمه أولاً. عند إنشاء مثيل لأحد المكونات ، تقوم Angular باستدعاء renderComponent ، renderComponent المرغوب الذي يتلقاه ، مع مثيل المكون. كل ما ستفعله Angular فيما يتعلق بتقديم المكون (إنشاء عناصر ، وتحديد السمات ، والاشتراك في الأحداث ، وما إلى ذلك) سوف يمر عبر هذا العارض. لذلك ، نحن بحاجة إلى استبدال RendererFactory.


بادئ ذي بدء ، في Renderer ، سنهتم بالطريقة createElement. في هذه الطريقة ، نحصل على اسم العلامة ، ومنه نحتاج إلى إنشاء المكون المطلوب. لحسن الحظ ، لدى nodegui مجموعة أساسية من المكونات ، والتي قمت بتحويلها بعناية ووصف كيف سيتم تقديمها في إطار Angular ، مع إلقاء كل شيء في الدليل العام للمكونات. سوف تمر الإجراءات الأخرى ذات المكونات القياسية أيضًا من خلال هذا العارض. مزيد من التفاصيل .


[Https://blog.nrwl.io/](https://blog.nrwl.io/) https://blog.nrwl.io/


للاستماع إلى الأحداث في العارض ، يتم طرح اسم الحدث ، ولهذه المكونات نقوم بتعليق الحدث المعتاد.


 listen(target: any, eventName: string, callback: (event: any) => boolean | void): () => void { const callbackFunc = (e: NativeEvent) => callback.call(target, e); target.addEventListener(eventName, callbackFunc); return () => target.removeEventListener(eventName, callbackFunc); } 

أحداث المكونات هي نفسها تمامًا مثل Qt ، على سبيل المثال ، بدلاً من المعتاد (click)=”clickFunc($event)” يجب أن تكتب (clicked) = ”clickFunc($event)” .


حاليا 16 مكونات قياسية متاحة. ولكن إذا كنت بحاجة إلى كتابة المكون المخصص الخاص بك ، فهناك دائمًا فرصة للقيام بذلك من خلال QWidget.


تم أيضًا إنشاء جهاز توجيه لجعل تطبيقنا متوافقًا قدر الإمكان مع Angular.


 const appRoutes: Routes = [ { path: 'home', component: HomeComponent }, { path: 'about', component: AboutComponent } ]; // AppModule imports ... NodeguiRouterModule.forRoot(appRoutes), 

التطبيق nodegui الزاوي
التطبيق nodegui الزاوي


تطبيق الطقس
تطبيق الطقس


نجمعها في همز


لبناء تطبيق جاهز ، لدى nodegui باكر خاص به - @nodegui/packer.


الأداة بسيطة للغاية ، وتتألف حتى الآن من فريقين.


npx nodegui-packer - الحرف الأول myapp


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


npx nodegui باكر - حزمة

يقوم هذا الأمر بتشغيل الأداة اللازمة للتعبئة (على سبيل المثال ، macdeployqt for mac) وحزم التبعيات.


في الختام


في الختام ، أريد مقارنة النتائج مع حلول الويب الأخرى على سطح المكتب (نتائج التشغيل تحت Mac OS).


حجم التحميل حجم التحميل


استخدام الذاكرة استخدام الذاكرة



رابط للمشروع:
irustm / الزاوي nodegui
* بناء تطبيقات سطح المكتب المؤدية ، وعبر منصة مع الزاوي. الزاوي NodeGUI هو مدعوم من الزاوي


معلومات عن المشروع:
https://t.me/ngFanatic


معلومات حول مشاريعي مفتوحة المصدر
https://twitter.com/irustm

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


All Articles