GUI-ni ishlab chiqish

Endi bizda ishlaydigan dastur mavjud bo'lib, keling, yanada chiroyli grafik interfeysga e'tibor qaratamiz. Bizning birinchi qadamimiz interfeysimiz qanday ko'rinishini va ishlashini aniq belgilashimiz kerak. Interfeys matnga asoslangan versiyada topilgan turli xil usullarni qo'llab-quvvatlashi kerak, shuningdek, qo'shimcha yordamchi usullarga ega bo'lishi mumkin.

O'zaro aloqani loyihalash

Qo'llab-quvvatlanishi kerak bo'lgan asosiy usullardan boshlaylik va foydalanuvchi bilan o'zaro aloqaning qanday bo'lishini aniq belgilab olamiz. Shubhasiz, grafik interfeysda zarlarning yuzlari va joriy bal doimiy ravishda ko'rsatilishi kerak. Ushbu displeylarni o'zgartirish uchun setDice va setMoney usullari qo'llaniladi. Bu biz joylashtirishimiz kerak bo'lgan bitta chiqish usulini qoldiradi. Ushbu turdagi tinch ma'lumotlarga ishlov berishning keng tarqalgan usullaridan biri bu oynaning pastki qismidagi xabar. Bunga ba'zida holat satri deyiladi.

Foydalanuvchidan ma'lumot olish uchun biz tugmachalardan foydalanamiz. WantToPlay-da foydalanuvchi aforizmlarni siljitish yoki undan chiqish to'g'risida qaror qabul qilishi kerak. Ushbu tanlov uchun "Roll Dice" va "Chiqish" tugmachalarini kiritishimiz mumkin. Bu bizni foydalanuvchi zarlarni qanday tanlashi kerakligini aniqlashga imkon beradi.

SelectDice dasturini amalga oshirish uchun biz har bir o'lim uchun tugmachani taqdim eta olamiz va foydalanuvchiga kerakli zarlarni bosish uchun tugmachani bosishimiz mumkin. Agar foydalanuvchi zarlarni tanlab bo'lgach, tanlangan zarlarni siljitish uchun yana "Roll Dice" tugmasini bosishi mumkin. Ushbu g'oyani batafsil ishlab chiqishda, agar biz zarni tanlash paytida foydalanuvchiga o'z fikrini o'zgartirishga imkon bersak yaxshi bo'lar edi. Ehtimol, hozirda tanlangan matritsa tugmachasini bosish uning tanlanmagan bo'lishiga olib kelishi mumkin. Tugmani bosish ma'lum bir o'limni tanlaydigan / tanlamaydigan bir xil almashtirish vazifasini bajaradi. Foydalanuvchi "Roll Dice" tugmachasini bosish orqali ma'lum bir tanlovni amalga oshiradi.

SelectDice-ga bo'lgan qarashimiz interfeys uchun bir nechta o'zgartirishlarni taklif qiladi. Birinchidan, hozirda qaysi zarlar tanlanganligini foydalanuvchiga ko'rsatishning biron bir usuli bo'lishi kerak. Buni amalga oshirishning ko'plab usullari mavjud. Oddiy yondashuvlardan biri o'lim rangini o'zgartirishdir. Dumalash uchun tanlangan zarlar ustidagi pipslarni "kulrang" qilaylik. Ikkinchidan, foydalanuvchiga prokatni to'xtatishni xohlashini ko'rsatadigan yaxshi usul kerak. Ya'ni, ular xuddi turgan joylarida zarlar urilishini xohlashadi. Zarni tanlanmaganda, ularni "Zarlarni siljitish" tugmachasini bosish orqali biz buni hal qila olamiz, shuning uchun dasturdan zarlarni silamaslikni so'raymiz. Yana bir yondashuv zarlarni urilishiga olib keladigan bosish uchun alohida tugmachani taqdim etishdir. Oxirgi yondashuv biroz intuitiv / ma'lumotli ko'rinadi. Keling, interfeysga "Skor" tugmachasini qo'shaylik.

Endi bizda interfeys qanday ishlashi haqida asosiy fikr mavjud. Hali ham qanday ko'rinishini aniqlashimiz kerak. Vidjetlarning aniq tartibi qanday? 12.2-rasmda interfeys qanday ko'rinishi mumkinligi namunasi keltirilgan. Ishonchim komilki, sizdan ko'ra ko'proq badiiy ko'zga ega bo'lganlar yanada yoqimli interfeysni taklif qilishlari mumkin, ammo biz uni ushbu dizayndan foydalanamiz.

Vidjetlarni boshqarish

Biz ishlab chiqayotgan grafik interfeys tugmalar va zarlardan foydalanadi. Bizning maqsadimiz avvalgi boblarda ishlab chiqilgan ushbu vidjetlar uchun Button va DieView sinflarini qayta tiklashdir. Tugma sinfi mavjud bo'lib ishlatilishi mumkin va biz boshqarish uchun juda ko'p tugmachalarga ega bo'lganimiz sababli, biz 11-bobdan kalkulyator dasturida foydalangan yondashuvga o'xshash Tugmalar ro'yxatidan foydalanishimiz mumkin.

Shakl 12.2: Video zarlari uchun GUI interfeysi poker.

Kalkulyator dasturidagi tugmachalardan farqli o'laroq, bizning poker interfeysimiz tugmalari doimo faol bo'lmaydi. Masalan, zarlar tugmachalari faqat foydalanuvchi aslida zarlarni tanlash jarayonida bo'lganida faol bo'ladi. Agar foydalanuvchi kiritishni talab qilsa, ushbu o'zaro ta'sir uchun tegishli tugmalar faol bo'ladi, boshqalari esa faol bo'lmaydi. Ushbu xatti-harakatni amalga oshirish uchun biz PokerInterface sinfiga select deb nomlangan yordamchi usulni qo'shishimiz mumkin.

Tanlash usuli parametr sifatida tugma yorliqlari ro'yxatini oladi, ularni faollashtiradi va keyin foydalanuvchi ulardan birini bosishini kutadi. Funktsiyaning qaytish qiymati - bosilgan tugmaning yorlig'i. Biz har doim foydalanuvchi tomonidan kirish kerak bo'lganda tanlash usulini chaqira olamiz. Masalan, biz foydalanuvchidan "Roll Dice" yoki "Chiqish" tugmachasini tanlashini kutayotgan bo'lsak, biz quyidagi kodlar ketma-ketligidan foydalanamiz:

choice = self.choose (["Roll Dice", "Chiqish"]) if choice == "Roll Dice":

Agar tugmachalar tugmachalar deb nomlangan o'zgaruvchida saqlansa, quyidagilarni amalga oshirish mumkin:

def select (self, choices): tugmalar = self.buttons

# tanlash tugmachalarini faollashtiring, b tugmachalari uchun boshqalarni o'chiring:

agar b.getLabel () tanlovda bo'lsa:

# faol tugma bosilguncha sichqonchani bosish uchun 1:

p tugmalaridagi b uchun p = self.win.getMouse ():

b.getLabel () # funktsiyasidan bu erga qayting.

Bizning interfeysimizdagi boshqa vidjetlar so'nggi ikki bobda ishlab chiqilgan DieView bo'ladi. Asosan, biz avvalgi sinfdan foydalanamiz, ammo birozgina yangi funksiyalarni qo'shishimiz kerak. Yuqorida aytib o'tilganidek, biz matritsaning rangini o'zgartirib, uni qayta ishlash uchun tanlanganligini yoki yo'qligini bildiramiz.

Siz orqaga qaytib, DieView sinfini ko'rib chiqishni xohlashingiz mumkin. Esingizda bo'lsa, sinf konstruktori har xil qiymatdagi pips paydo bo'ladigan pozitsiyalarni ko'rsatish uchun kvadrat va etti doirani chizadi. SetValue usuli berilgan qiymatni ko'rsatish uchun mos piplarni yoqadi. Xotirangizni biroz yangilash uchun setValue usuli quyidagicha:

def setValue (o'zini, qiymati):

# Self.pips-da pip uchun barcha pipslarni o'chirib qo'ying:

# Self.onTable [value] da mos keladigan pipslarni qayta yoqing:

SetVolor usulini qo'shish orqali DieView sinfini o'zgartirishimiz kerak. Ushbu usul pipslarni chizish uchun ishlatiladigan rangni o'zgartirish uchun ishlatiladi. SetValue kodida ko'rib turganingizdek, pips rangi misol o'zgaruvchisi old fon qiymati bilan belgilanadi. Albatta, oldingi o'simlikning qiymatini o'zgartirish, yangi rang yordamida qayta chizilgunga qadar matritsaning ko'rinishini o'zgartirmaydi. SetColor algoritmi oddiy ko'rinadi. Bizga ikki bosqich kerak:

oldingi rangni yangi rangga o'zgartirish, o'limning joriy qiymatini qayta chizish

Afsuski, ikkinchi qadam biroz chayqalishni keltirib chiqaradi. Bizda allaqachon qiymatni tortadigan kod bor, ya'ni setValue. Lekin setValue bizdan qiymatni parametr sifatida yuborishni talab qiladi va DieView-ning joriy versiyasi bu qiymatni hech qaerda saqlamaydi. Tegishli pipslar yoqilgandan so'ng, haqiqiy qiymat bekor qilinadi.

SetColor-ni amalga oshirish uchun setValue-ni sozlashimiz kerak, shunda u joriy qiymatni eslab qoladi. Keyin setColor matritsani joriy qiymati yordamida qayta chizishi mumkin. SetValue-ga o'zgartirish oson; biz faqat bitta qatorni qo'shishimiz kerak.

Ushbu qator qiymat parametrini qiymat deb nomlangan misol o'zgaruvchisida saqlaydi.

SetValue-ning o'zgartirilgan versiyasi bilan setColor-ni amalga oshirish shabada.

def setColor (self, color): self.foreground = color self.setValue (self.value)

So'nggi satrda setValue chaqirilgandan (re) chizish uchun oxirgi marta setValue qanday chaqirilayotganiga e'tibor bering.

Interfeys yaratish

Endi bizda vidjetlar nazorat ostida bo'lsa, biz GUI poker interfeysini amalga oshirishga tayyormiz. Konstruktor bizning barcha vidjetlarimizni yaratadi, keyinchalik o'zaro ta'sir o'tkazish uchun interfeysni o'rnatadi.

self.win = GraphWin ("Dice Poker", 600, 400) self.win.setBackground ("green3")

banner = Matn (nuqta (300,30), "Python Poker Saloni")

self.msg = Matn (nuqta (300,380), "Zarlar jadvaliga xush kelibsiz")

self.addDiceButtons (nuqta (300,170), 75, 30)

b = Tugma (self.win, Point (300, 230), 400, 40, "Roll Dice") self.buttons.append (b)

b = Tugma (self.win, Point (300, 280), 150, 40, "Score") self.buttons.append (b)

b = Tugma (self.win, Point (570,375), 40, 30, "Chiqish") self.buttons.append (b)

self.money = Matn (nuqta (300,325), "100 dollar")

Interfeys elementlari qanday yaratilganligi va joylashtirilganligini tushunishingiz uchun ushbu kodni 12.2-rasm bilan taqqoslashingiz kerak.

Umid qilamanki, men zarlarning yaratilishini va ularga tegishli tugmachalarni bir nechta yordamchi usullarga aylantirganman. Bu erda kerakli ta'riflar mavjud:

def createDice (self, center, size): center.move (-3 * size, 0) self.dice = [] i uchun (5) oralig'ida:

view = DieView (self.win, center, size)

def addDiceButtons (o'zini, markazi, kengligi, balandligi): i uchun (1,6) center.move (-3 * width, 0):

b = Tugma (self.win, center, width, height, label)

Ushbu ikkita usul o'xshash, chunki ular beshta o'xshash vidjetni chizish uchun tsikldan foydalanadilar. Ikkala holatda ham keyingi vidjetning to'g'ri holatini hisoblash uchun Point o'zgaruvchisi, markazi ishlatiladi.

O'zaro aloqani amalga oshirish

Bizning GUI interfeysimiz uchun konstruktor shu qadar murakkab bo'lganidan, siz biroz qo'rqishingiz mumkin. Hatto oddiy grafik interfeyslar ham ko'plab mustaqil komponentlarni o'z ichiga oladi. Ularning barchasini sozlash va ishga tushirish ko'pincha interfeysni kodlashning eng zerikarli qismidir. Endi bizda bu qism yo'q, aslida o'zaro ta'sirni boshqaradigan kodni yozish juda qiyin bo'lmaydi, agar biz unga birma-bir hujum qilsak.

SetMoney va showResult oddiy chiqish usullaridan boshlaylik. Ushbu ikkita usul bizning interfeys oynamizda ba'zi matnlarni aks ettiradi. Bizning konstruktorimiz tegishli Matn moslamalarini yaratish va joylashtirish bo'yicha g'amxo'rlik qilganligi sababli, bizning barcha usullarimiz mos ob'ektlar uchun setText usullarini chaqirishdir.

def setMoney (self, amt):

def showResult (self, msg, ball): agar ball>0:

text = "% s! Siz $% d"% yutasiz (msg, ball) boshqa:

text = "Siz% s aylantirdingiz"% (msg) self.msg.setText (matn)

Shunga o'xshash ruhda, setDice chiqish usuli zarda DieView moslamalarini setValue uslubiga qo'ng'iroq qilishi kerak. Buni for loop yordamida qilishimiz mumkin.

def setDice (self, values): i (5) oralig'ida:

Loop tanasidagi chiziqni yaxshilab ko'rib chiqing. Ith qiymatini ko'rsatish uchun ith die ni o'rnatadi.

Ko'rib turganingizdek, interfeys qurilgandan so'ng uni funktsional qilish juda qiyin emas. Bizning chiqish usullarimiz bir nechta satr kodlari bilan yakunlandi. Kirish usullari biroz murakkabroq.

WantToPlay usuli foydalanuvchi "Roll Dice" yoki "Chiqish" tugmachasini bosishini kutadi. Buning uchun biz tanlagan yordamchimiz usulidan foydalanishimiz mumkin.

return ans == "Dice roll"

Foydalanuvchi tegishli tugmani bosishini kutgandan so'ng, ushbu usul msg matnini bo'sh satrga o'rnatish orqali avvalgi natijalar kabi har qanday xabarni o'chiradi. So'ngra usul mantiqiy qiymatni return tomonidan qaytarilgan yorlig'i tekshirib qaytaradi.

Bu bizni selectDice uslubiga olib keladi. Bu erda biz foydalanuvchilarning yanada kengroq o'zaro ta'sirini amalga oshirishimiz kerak. SelectDice usuli foydalanuvchi aylantirmoqchi bo'lgan zarlar indekslari ro'yxatini qaytaradi.

Bizning GUI-da foydalanuvchi zarlarni tegishli tugmachalarni bosish orqali tanlaydi. Biz tanlangan zarlarning ro'yxatini saqlashimiz kerak. Har safar tugmachani bosish paytida u tanlanadi (indeks ro'yxatga qo'shiladi) yoki tanlanmagan (indeks ro'yxatdan o'chiriladi). Bundan tashqari, tegishli DieView-ning rangi o'lim holatini aks ettiradi. O'zaro aloqa foydalanuvchi rulon tugmachasini yoki ball tugmachasini bosganda tugaydi. Agar aylantirish tugmasi bosilsa, usul tanlangan indekslar ro'yxatini qaytaradi. Agar ball tugmasi bosilsa, funktsiya pleyerning aylantirilganligini bildiruvchi bo'sh ro'yxatni qaytaradi.

Zarlarni tanlashni amalga oshirishning bir usuli. Ushbu koddagi sharhlar algoritmni tushuntiradi:

# choices - bu tanlangan zar tanlovlari indekslari ro'yxati = [] # Hali hech bir zar tanlanmagan 1:

# foydalanuvchi to'g'ri tugmani bosishini kuting b = self.choose (["Die 1", "Die 2", "Die 3", "Die 4", "Die 5", "Roll Dice", "Score") )

agar b [0] == "D": # Foydalanuvchi o'lish tugmachasini bosdi i = eval (b [4]) - 1 # Agar tanlovda bo'lsa, indeks indeksiga tarjima qilish yorlig'i: # Hozir tanlangan, uni choices.remove (i ) self.dice [i] .setColor ("qora")

else: # Hozirda tanlanmagan, uni tanlang choices.append (i)

self.dice uchun d uchun:

# Foydalanuvchi "Roll" yoki "Score" -ni bosdi

# Barcha zarlarning ko'rinishini qaytaring

# Bal bosildi, tanlovlarni e'tiborsiz qoldiring

# Ba'zilar bo'lmasa, rulonni qabul qilmang

# zar tanlangan

Bu bizning dasturimizni yakunlaydi. Bizning interfeys sinfimizning etishmayotgan yagona qismi bu yaqin usul. Grafik versiyani yopish uchun biz faqat grafik oynani yopishimiz kerak.

Va nihoyat, bizda grafik poker o'ynash dasturini boshlash uchun bir nechta satr kerak. Ushbu kod matnli versiyaning boshlang'ich kodiga o'xshaydi, faqat biz TextInterface o'rniga GraphicsInterface-dan foydalanamiz.

inter = GraphicsInterface () ilova = PokerApp (inter) app.run ()

Endi bizda to'liq, foydalanish mumkin bo'lgan video zarlar poker o'yini mavjud. Albatta, o'yinimizga juda yaxshi qo'ng'iroqni chop etish, qoidalar bo'yicha yordam berish va yuqori ballarni kuzatib borish kabi ko'plab qo'ng'iroq va hushtaklar etishmayapti. Ushbu misolni nisbatan sodda tutishga harakat qildim, shu bilan birga ob'ektlardan foydalangan holda GUIlarni loyihalashdagi muhim masalalarni tasvirlab berdim. Yaxshilashlar siz uchun mashq sifatida qoldirilgan. Ular bilan zavqlaning!

Mening racquetball va video poker amaliy tadqiqotlaridagi maqsadi OOD nima ekanligini bilish uchun sizga lazzat berish edi. Aslida, siz ko'rgan narsalar ushbu ikkita dasturni loyihalash jarayonining distillashidir. Asosan, men sizni ikkita tugallangan dizaynning algoritmlari va mantiqiy asoslarini ko'rib chiqdim. Men har bir qarorni, yolg'on boshlash va yo'l bo'ylab aylanishni hujjatlashtirmadim. Bunday qilish ushbu bobning hajmini kamida uch baravar oshirishi kerak edi. Siz meniki haqida o'qish bilan emas, balki o'zingizning qarorlaringizni qabul qilish va o'z xatolaringizni aniqlash orqali yaxshiroq o'rganasiz.

Shunga qaramay, bu kichik misollar ob'ektga yo'naltirilgan yondashuvning katta kuchi va jozibasini aks ettiradi. Umid qilamanki, nima uchun OO texnikasi dasturiy ta'minotni ishlab chiqishda standart amaliyotga aylanib borayotganini ko'rasiz. Xulosa shuki, OO yondashuvi bizga yanada ishonchli va tejamkor bo'lgan murakkab dasturiy ta'minotni ishlab chiqarishda yordam beradi. Biroq, men ob'ektiv yo'naltirilgan rivojlanish deb hisoblanadigan aniq narsani aniqlay olmadim.

Aksariyat OO guruslari rivojlanishni ob'ektiv yo'naltirilgan uchta xususiyati haqida gapirishadi: inkapsulyatsiya, polimorfizm va meros. Men ushbu kontseptsiyalarni juda ko'p ishlab chiqishni xohlamayman, lekin sizning ob'ektga yo'naltirilgan dizayn va dasturlash bilan tanishishingiz ushbu atamalar nimani anglatishini hech bo'lmaganda tushunmasdan to'liq bo'lmaydi.