paint-brush
Mana men Python uchun UI Builder kabi veb-oqimni qanday yaratdimtomonidan@paulfreeman
Yangi tarix

Mana men Python uchun UI Builder kabi veb-oqimni qanday yaratdim

tomonidan Paul10m2024/10/05
Read on Terminal Reader

Juda uzoq; O'qish

Fikrlash jarayonim va python uchun Drag and Drop UI quruvchisini yaratish tajribam bilan o'rtoqlashaman
featured image - Mana men Python uchun UI Builder kabi veb-oqimni qanday yaratdim
Paul HackerNoon profile picture
0-item
1-item


Men so'nggi bir necha hafta davomida Python uchun Drag and Drop quruvchisi ustida ishlayapman.


Bu yerda tekshirishingiz mumkin PyUIBuilder

Manba kodi: https://github.com/PaulleDemon/PyUIBuilder


Quruvchi nima qila oladi?

Qisqasi, bu sizga Python uchun UI-ni tezda yaratishga va bir nechta kutubxonalar/ramkalarda, jumladan Tkinter va customtkinterda UI kodini yaratishga yordam beradi. haqida ko'proq o'qishingiz mumkin xususiyatlar bo'limi


Lekin men shunchaki loyihani yo‘lga qo‘ymoqchi emasman, balki o‘z tajribamni siz bilan baham ko‘rmoqchiman. Ushbu blogda men o'z fikrlash jarayonimni va ilovani qanday yaratganimning yuqori darajadagi umumiy ko'rinishini ko'rib chiqaman.

Fikr bilan chiqish.

Ommabop e'tiqoddan farqli o'laroq, Python tez-tez ilovalarni yaratish uchun ishlatiladi, ayniqsa ma'lumotlar fanida, avtomatlashtirishda, skript vazifalarida va hokazolarda ishlaydigan ishlab chiquvchilar orasida mashhurdir. Ko'pgina ichki vositalar va grafik interfeyslar, ayniqsa ilmiy va tadqiqot sozlamalarida, Python bilan yaratilgan. soddaligi va Tkinter, PyQt va boshqalar kabi ramkalarning mavjudligi.

fikr

Endi veb uchun Drag and drop quruvchilar juda ko'p edi, lekin Python GUI uchun, ayniqsa tkinter uchun juda kam. Men bir nechtasini ko'rdim, lekin muammo shundaki, ular juda cheklangan miqdordagi vidjetlar edi yoki XML formatida kod ishlab chiqaradi, agar siz Python-da UI-ni ishlab chiqayotgan bo'lsangiz, bu ideal emas.


Shunday qilib, dastlab, men shunchaki Tkinter uchun tegishli sudrab olib tashlash UI quruvchisini yaratmoqchi edim.


Men ideal GUI yaratuvchisi g'oyasi atrofida o'ylashda davom etdim (hech qanday so'z o'yini nazarda tutilmagan). Men Canva foydalanuvchi interfeysidan ilhom oldim va mening GUI-ni idealga aylantiradigan bir nechta xususiyatlarni o'ylab topdim.


  1. Barcha vidjetlar plaginlar kabi yaratilishi kerak.
  2. Plaginlar ko'rinishidagi uchinchi tomon UI vidjetlarini qo'llab-quvvatlashi kerak.
  3. Tasvirlar, videolar va boshqalar kabi aktivlarni yuklay olishi kerak.
  4. U Python-da kod yaratishi kerak.

Shunday qilib, iyul oyining oxirida men loyiha ustida ishlashga qaror qildim

Fikrni kengaytirish

Dastlab u tkbuilder deb nomlangan, bu Tkinter UI kutubxonasi uchun GUI quruvchisi ekanligini ko'rsatadi.


Ammo, agar siz payqagan bo'lsangiz, men bir nechta Python GUI ramkalari va kutubxonalarini qo'llab-quvvatlash uchun bir xil g'oyani kengaytirishim mumkin, chunki hamma narsa plagin kabi yaratilgan va men aynan shunday qilishni rejalashtirgan edim.

Dastlabki versiyani rejalashtirish.

Dastlabki versiya uchun men foydalanuvchilarni hayratda qoldiradigan juda ko'p xususiyatlarni qo'shishni xohlamadim. Men uni ishlatadigan odamlarning fikr-mulohazalari asosida qurmoqchi edim. Shunday qilib, men odamlar istamaydigan narsalarni qurishga vaqt sarflamayman.


Eng boshidan men backend yoki boshqa yoki ro'yxatdan o'tish shakliga ega bo'lmaslikka qaror qildim. Bu men uchun ishlab chiqish va undan foydalanadigan foydalanuvchilar uchun ancha sodda. Men shunchaki odamlar boshlashi mumkin bo'lgan oddiy frontendni xohlardim.

JS, TS yoki Python tilini tanlash

tilni tanlash

Ha, bu men ba'zan o'ylayotgan narsa edi, Python uchun GUI quruvchilarning aksariyati Python yordamida qurilgan. Python uchun birinchi tanlovim PySide edi.


PyQt/Pyside yordamida yaratgan eng murakkab GUI asosidagi ilovam a edi tugunga asoslangan muharrir bir necha yil oldin.


Lekin men dastlabki versiyani yaratish uchun python dan foydalanish cheklovlarini tezda angladim.


  • Python UI kutubxonalarida menga dastlabki versiyani tezda yaratishga yordam beradigan ko'plab uchinchi tomon vidjetlari mavjud emas.
  • Python ilovasini exe fayllari sifatida tarqatish oson emas, JS dan foydalanganda biz uni elektron ilova ko'rinishida tarqatishimiz mumkin.
  • Ko'pchilik notanish veb-saytdan bajariladigan faylni yuklab olish o'rniga internetdan foydalanishni afzal ko'radi.


Typescript ham variant edi, lekin Typescript bilan men buni har doim juda batafsil deb his qildim


Bular men darhol payqagan yagona narsa edi, shuning uchun mening birinchi tanlovim JS dan foydalanishga aylandi.


PS: Keyinchalik men TS bilan boshlamaganimdan afsuslandim, lekin bu boshqa vaqt uchun hikoya bo'ladi.

Ramka yoki ramka yo'q.

Menga eng qulay bo'lgan ramkaga o'xshash kutubxona React.js, lekin abstraktsiya yaratish sinflardan foydalanishni talab qiladi, bu ilgaklar joriy qilinganidan beri tavsiya etilmaydi.


Ramkadan foydalanmaslik muammosi shundaki, men hamma narsani o'zim qurishim kerak edi va reaktsiya taklif qiladigan keng komponent kutubxonalariga kira olmasdim.


Ikkalasi ham o'zaro kelishuvga ega edi, ammo React sinflaridan hali ham foydalanish mumkin, shuning uchun bu men uchun aniq tanlov bo'ldi.

Qattiq boshlanish

Men avgust oyining boshida poydevor va yon panelni qurishni boshladim va mablag' etishmasligi tufayli to'xtashga majbur bo'ldim, shuning uchun mijozning ishiga kirishdim, afsuski, yakuniy miqdorni to'lamadi. Men olomonni moliyalashtirishga harakat qildim, lekin u erda ham omadim kelmadi.


Shunday qilib, sentyabr oyida men qoldirgan ozgina mablag' bilan men ushbu loyihada qatnashishga qaror qildim. Taxminan 9 sentyabr kuni men ishni qayta boshladim.

Oldindan rejalashtirish ...

oldindan rejalashtirish

Ehtiyojlarni qondirish uchun kengaytirilishi mumkin bo'lgan asosiy abstraktsiya haqida ko'p vaqt o'tdi.


  1. Figmaga o'xshash kattalashtirish va panorama qilish mumkin bo'lgan kanvasga ega bo'lishni xohlardim.

  2. Boshqa barcha vidjetlar uzaytirilishi mumkin bo'lgan asosiy vidjet.

  3. UI elementlarini tuvalga sudrab olib tashlash uchun sudrab olib tashlash xususiyati.


React bilan qurish uchun siz uni ma'lum bir tarzda o'ylab ko'rishingiz va qurishingiz kerak, bu kutubxona yoki ramka ekanligi haqidagi bahslarga qaramay, u har doim kutubxonadan ko'ra ko'proq Frameworkga o'xshaydi.

UI dizayni

Menga har doim Canva o'zlarining yon panellarini qanday yaratganini yoqtirardim, men sudrab olib tashlash quruvchim uchun shunga o'xshash narsaga ega bo'lishni xohlardim.

Ko‘nglimdagilarni qog‘ozga chizdim. U erdagi eng yaxshi rassom emas 🙄

UI dizayni

Tuval va vidjet o'zaro ta'siri haqidagi fikrlash jarayonim.

oldindan rejalashtirish ...

Shunday qilib, sudrab olish, o'lchamini o'zgartirish, tanlash uchun kim mas'ul bo'lishi kerak. Tuval yoki asosiy vidjet. Vidjet ichidagi vidjetlar qanday boshqariladi?


Asosiy vidjet o'z farzandlarini biladimi yoki uni tuvalning o'zi bitta ma'lumotlar strukturasi bilan boshqaradimi. Bolalarni bolalar ichida qanday qilib ko'rsataman?


Tuval va boshqa vidjetlar ichida sudrab olib tashlash qanday ishlaydi?


Tartiblar qanday boshqariladi?


Bu men hamma narsani qurishdan oldin so'ra boshlagan savollarim edi.


Endi UI soddaroq ko'rinsa-da, bazani yaratish haqida ko'p o'ylangan, shuning uchun u foydalanuvchilar uchun ancha sodda ko'rinadi.

HTML Canvas-ga asoslangan yondashuv yoki kanvas bo'lmagan yondashuv.

Kanvasga asoslangan yondashuv

Endi html standart Canvas elementiga ega, bu sizga chizish, rasm va boshqa narsalarni qo'shish kabi ko'p narsalarni qilish imkonini beradi, endi u mening dasturim uchun foydalanish uchun ideal elementga o'xshardi.


Shunday qilib, sudrab olib tashlash, o'lchamini o'zgartirish, kattalashtirish va panoramaning mavjudligi va mavjudligini tekshirishni boshladim. topdim FabricJs , bu mening foydalanishim uchun ajoyib kutubxonaga o'xshardi.


Men Fabric.Js bilan tajriba o'tkazishga harakat qildim va buni ko'rib turganingizdek fabric.js da to'liq amalga oshirishga harakat qildim. amalga oshirish , lekin tuval haqida men oldindan bilmagan narsa bor edi.


  1. Men kanvas yaratishda ilgaklar asosidagi yondashuv bilan tajriba o‘tkazishni boshladim, lekin fabric.js dispose funksiyasi asinx edi, shuning uchun u Hooks bilan yaxshi o‘ynamaydi.
  2. Canvasda Div yoki boshqa elementlar kabi bolalar elementlari bo'lishi mumkin emas, bu esa tartib menejerlarini yaratishni biroz qiyinlashtiradi.
  3. Tuvaldagi biror narsani disk raskadrovka qilish juda qiyin, chunki tuvalning ichki elementlari ishlab chiquvchi vositalarini tekshirish elementida ko'rinmaydi.


Tuvalga asoslangan bo'lmagan yondashuv


Tajribadan so'ng, endi kanvas bo'lmagan yondashuv yaxshiroq bo'lib tuyuldi, chunki men taqdim etilgan standart tartib boshqaruvchisiga kirish huquqiga egaman, shuningdek, miqyoslashda bu ideal tanlovni amalga oshiradigan ko'plab oldindan o'rnatilgan UI komponentlari mavjud edi.


Ikki xil div ning bir ichki div va tashqi konteyner div yordamida kanvasni simulyatsiya qilishni rejalashtirdim.


Endi masshtab va panoramani yaratish juda oson edi, chunki CSS allaqachon o'zgartirish, o'lchov va tarjimaga ega edi.


Birinchidan, buni amalga oshirish uchun men tuvalni ushlab turadigan idishga ega bo'lishim kerak edi. Endi bu tuval ko'rinmas element (to'lib-toshgan holda yashirin), bu erda barcha elementlar tushiriladi va masshtablash va tarjima qo'llaniladi.

Konteyner

Kattalashtirish uchun masshtabni oshirishim va kichraytirish uchun uni kichraytirishim kerak edi.

Ushbu oddiy misolni sinab ko'ring. (kattalashtirish uchun + tugmasi va kichraytirish uchun - tugmasi)


Panorama xuddi shunday ishladi

Olib tashlang va torting

sudrab olib tashlang

Ishni boshlaganimda men bir nechta kutubxonalarni tadqiq qildim, masalan React-beautiful-Dnd , React Dnd-to'plami va React Swappy .


Tadqiqotdan so'ng, men react-beautiful-dnd endi saqlanmasligini va React dnd-kit-dan boshlaganini ko'rdim. Qurilishni boshlaganimda, men qurayotgan narsam uchun dnd-kit hujjatlarini juda cheklangan deb topdim, bundan tashqari, kutubxonaga katta o'zgarishlar kiritilgan yangi nashr yaqinda chiqadi, shuning uchun men react-dnd-kitni asosiy nashrigacha tashlab qo'yishga qaror qildim.


Men HTML-ning Drag and Drop API-si bilan DND-to'plamini ishlatgan qismlarimni qayta yozdim. Mahalliy Drag and drop API bilan cheklov shundan iboratki, u hali ham ba'zi sensorli qurilmalar tomonidan qo'llab-quvvatlanmaydi, bu men uchun ahamiyatsiz edi, chunki men sensorli bo'lmagan qurilmalar uchun tuzganman.

Haqiqatning yagona manbai

Haqiqatga yuz tuting

shunga o'xshash ilovani yaratishda barcha o'zgaruvchilar va o'zgarishlarni kuzatishni yo'qotish oson bo'lishi mumkin. Shunday qilib, men bir xil ma'lumotni kuzatib boradigan bir nechta o'zgaruvchilarga ega bo'lolmayman.


Har bir vidjetning ma'lumoti/holati tuvalda yoki vidjetning o'zida bo'lishi kerak, so'ngra so'rov bo'yicha ma'lumotlarni uzatadi.


Yoki redux kabi davlat boshqaruv kutubxonasidan foydalaning


Turli yondashuvlarni sinab ko'rganimdan so'ng, Canvas komponenti tomonidan boshqariladigan vidjetlar haqidagi barcha ma'lumotlarga ega bo'lishni tanladim.


Ma'lumotlar strukturasi shunday ko'rinadi.

 [ { id: "", // id of the widget widgetType: WidgetClass, // base widget children: [], // children will also have the same datastructure as the parent parent: "", // id of the parent of the current widget initialData: {} // information about the widget's data that's about to be rendered eg: backgroundColor, foregroundColor etc. } ]

React Context menejerlari

Endi men yon panelga yuklangan aktivlarga vidjetlar asboblar paneli orqali kirishni xohlardim. Lekin har safar yon yorliqlarni almashtirganimda, qayta ko'rsatish yuklangan aktivlarning yo'qolishiga olib keldi.


Redux-ning eng katta cheklovlaridan biri shundaki, siz faqat seriyali ma'lumotlarni saqlashingiz mumkin. Rasm, video va boshqa aktivlar kabi seriyali bo'lmagan ma'lumotlarni reduxda saqlash mumkin emas. Bu turli komponentlar atrofida umumiy ma'lumotlarni uzatishni qiyinlashtiradi.


Buni bartaraf etishning usullaridan biri React Context-dan foydalanishdir. Qisqacha aytganda, React Context har bir darajadagi rekvizitlarni qo'lda o'tkazmasdan komponentlar daraxti orqali ma'lumotlarni uzatish usulini taqdim etadi.


Turli komponentlarda ma'lumotlarga ega bo'lish uchun men qilishim kerak bo'lgan narsa uni React kontekst provayderi atrofida o'rash edi.


Men ikkita narsa uchun o'z kontekst provayderlarimni yaratdim:

  1. Drag va drop - Yon paneldan sudrab olib tashlashni yoqish + pastki elementlarni sudrab olib tashlash.
  2. Fayl yuklash - Yuklangan fayllarni har bir vidjet uchun asboblar panelida foydalanish mumkin qilish.


Bu yerda sudrab olib tashlash uchun React kontekstidan qanday foydalanganimning oddiy misoli keltirilgan.

 import React, { createContext, useContext, useState } from 'react' const DragWidgetContext = createContext() export const useDragWidgetContext = () => useContext(DragWidgetContext) // Provider component to wrap around parts that need drag-and-drop functionality export const DragWidgetProvider = ({ children }) => { const [draggedElement, setDraggedElement] = useState(null) const onDragStart = (element) => { setDraggedElement(element) } const onDragEnd = () => { setDraggedElement(null) } return ( <DragWidgetContext.Provider value={{ draggedElement, onDragStart, onDragEnd }}> {children} </DragWidgetContext.Provider> ) }


Ha! bo'ldi shu. Endi qilishim kerak bo'lgan narsa uni kontekstga muhtoj bo'lgan komponentning atrofiga o'rash edi, bu mening holimda Canvas va yon panelda edi.

Kod yaratilmoqda

Mas'uliyat

Har bir vidjet oʻzini boshqacha tutganligi va oʻz atributlariga ega boʻlgani uchun men vidjetlar oʻz kodlarini yaratish uchun masʼul boʻlishi kerak, deb qaror qildim va kod mexanizmi faqat oʻzgaruvchilar nomlari toʻqnashuvlarini hal qiladi va kodni birlashtiradi.


Shunday qilib, men oldindan yaratilgan ko'plab vidjetlarni, shuningdek, uchinchi tomon UI plaginlarini qo'llab-quvvatlash uchun osongina kengaytira oldim.

Jonli efirda

Menda backend yoki ro'yxatdan o'tish yo'q edi va statik sahifalar uchun bepul xostingni ta'minlaydigan ko'plab kompaniyalar bor edi. Men avvaliga Versel bilan borishga qaror qilgandim, lekin ko'pincha agar juda ko'p so'rovlar bo'lsa, Vercel bepul shinalari tushib ketganini ko'rganman.


O'shanda men bu haqda bildim Cloudflares sahifalari taklif. Ularning bepul shinalarida deyarli hamma narsa cheksiz edi. Shunday qilib, cloudflare-dan foydalanish mening asosiy tanlovim bo'ldi.


Yagona kamchiliklari shundaki, qurilish vaqtlari juda sekin edi va hujjatlar juda oz edi.


Qurilish bosqichining eng zerikarli qismi qurilishdagi muvaffaqiyatsizlik edi, u Vercelda ishlagan, lekin cloudflare sahifalarida emas??? Jurnallar ham unchalik aniq emas edi. va bizda bepul shinalar oyiga atigi 500 ta ishlab chiqariladi, shuning uchun men juda ko'p isrof qilishni xohlamadim


Men soatlab harakat qildim, keyin bo'sh satrga uzluksiz integratsiyani o'rnatishga qaror qildim

 CI='' npm install


Va nihoyat jonli efirga chiqdi.
Jonli

Oylar davomida qanday rivojlanganligini ko'rishni xohlaysizmi?

Men hamma narsani omma oldida qurdim. Men sizni uning oddiy yon paneldan to'liq ishga tushirilgan Drag n drop quruvchisiga o'tishini ko'rishni xohlayman, siz to'liq tekshirishingiz mumkin. vaqt jadvali bu erda .


#ommaviy qurilish


Oh! yangilanishlar uchun kuzatib borishni unutmang

Yulduzli repo ⭐️


Agar sizga ushbu turdagi kontent yoqqan bo'lsa, men qanday qilib narsalarni rejalashtirish va qurish haqida chuqurroq ma'lumotga ega bo'lgan ko'proq bloglar yozaman, kuzatib borish uchun siz mening substack yangiliklar byulletenimga obuna bo'lishingiz mumkin :)