Men so'nggi bir necha hafta davomida Python uchun Drag and Drop quruvchisi ustida ishlayapman.
Bu yerda tekshirishingiz mumkin
Manba kodi:
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
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.
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.
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.
Shunday qilib, iyul oyining oxirida men loyiha ustida ishlashga qaror qildim
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 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.
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
Lekin men dastlabki versiyani yaratish uchun python dan foydalanish cheklovlarini tezda angladim.
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.
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.
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.
Ehtiyojlarni qondirish uchun kengaytirilishi mumkin bo'lgan asosiy abstraktsiya haqida ko'p vaqt o'tdi.
Figmaga o'xshash kattalashtirish va panorama qilish mumkin bo'lgan kanvasga ega bo'lishni xohlardim.
Boshqa barcha vidjetlar uzaytirilishi mumkin bo'lgan asosiy vidjet.
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.
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 🙄
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.
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
Men Fabric.Js bilan tajriba o'tkazishga harakat qildim va buni ko'rib turganingizdek fabric.js da to'liq amalga oshirishga harakat qildim.
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.
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
Ishni boshlaganimda men bir nechta kutubxonalarni tadqiq qildim, masalan
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.
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. } ]
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:
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.
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.
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
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.
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.
#ommaviy qurilish
Oh! yangilanishlar uchun kuzatib borishni unutmang
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 :)