الواجهة الرسومية في بايثون 2 - رسم خط ملون

البرنامج الذي سنقوم بتحليل كيفية عمله سيقوم برسم خط عند الضغط على الزر'أرسم خط'  كما يسمح بتغيير اللون عند اختيار زر'لون آخر'




نص البرنامج

# -*- coding:Latin-1 -*-
# Petit exercice utilisant la bibliothèque graphique Tkinter
from Tkinter import *
from random import randrange
# --- définition des fonctions gestionnaires d'événements : ---
def drawline():
    "Tracé d'une ligne dans le canevas can1"
    global x1, y1, x2, y2, coul
    can1.create_line(x1,y1,x2,y2,width=2,fill=coul)
    # modification des coordonnées pour la ligne suivante :
    y2, y1 = y2+10, y1-10
def changecolor():
    "Changement aléatoire de la couleur du tracé"
    global coul
    pal=['purple','cyan','maroon','green','red','blue','orange','yellow']
    c = randrange(8)         # => génère un nombre aléatoire de 0 à 7
    coul = pal[c]
#------ Programme principal -------
# les variables suivantes seront utilisées de manière globale :
x1, y1, x2, y2 = 10, 190, 190, 10      # coordonnées de la ligne
coul = 'dark green'                  # couleur de la ligne
# Création du widget principal ("maître") :
fen1 = Tk()
# création des widgets "esclaves" :
can1 = Canvas(fen1,bg='dark grey',height=200,width=200)
can1.pack(side=LEFT)
bou1 = Button(fen1,text='Quitter',command=fen1.quit)
bou1.pack(side=BOTTOM)
bou2 = Button(fen1,text='Tracer une ligne',command=drawline)
bou2.pack()
bou3 = Button(fen1,text='Autre couleur',command=changecolor)
bou3.pack()
fen1.mainloop()   # démarrage du réceptionnaire d’événements
fen1.destroy()    # destruction (fermeture) de la fenêtre
الشرح

كما هو واضح من خلال شرح كيفية عمل البرنامج فإنه يقوم على وظيفتين أساسيتين رسم خط و اختيار لون و هما يتمان عبر الوظيفتان/Functions  الأولى هي ()drawline و الثانية ()changecolor المسؤولتان عن اعطاء الأحداث evenements/events

في البداية قمنا باستدعاء وحدة Tkinter التي تسمح لنا بعمل واجهة رسومية ثم استدعاء وحدة random التي تسمح لنا باختيار رقم عشوائي. ثم قمنا برسم كافة عناصر الواجهة widgets.

عبر fen1.mainloop() الموجودة باﻷخير أصبح بإمكاننا استقبال كافة اﻷحداث و الأمر الذي يليها لا يحدث إلا عند الخروج من الحلقة boucle/loop.

command الموجودة بالبرنامج تسمح باختيار ماذا سيفعل الزر button عند الضغط عليه,
global مهمتها تعريف الوظيفة Function بالتحديد يوجد نوعان من المتغيرات variable الأولى محلية و الثانية عمومية أي يمكن استعمالها على امتداد البرنامج, أعتقد أنها تقابل مصطلح public في الجافا.


أسئلة: أسئلة بسيطة إن إستطعت الإجابة عليها فقد فهمت مبدأ عمل البرنامج,

1. كيف نغير البرنامج بحيث لا يظهر الألوان التالية cyan, maroon و green؟
2. كيف تجعل الخطوط متوازية؟
3. إن قمنا بتغيير هذا السطر
can1 = Canvas(fen1,bg='dark grey',height=200,width=200)
ب
can1 = Canvas(fen1,bg='dark grey',height=600,width=500)
ماذا سيحدث؟
4.  إن قمنا بتغيير هذا السطر 
can1.create_line(x1,y1,x2,y2,width=2,fill=coul)
ب
can1.create_rectangle(x1,y1,x2,y2,width=2,fill=coul)
ماذا سيحدث؟
5. و أخيرا سؤال التحدي هل أنت قادر على صنع الدوائر الأولمبية في مستطيل أبيض مع زر للخروج.
ب- حاول تغيير البرنامج بحيث يحتوي على 5 أزرار كل زر يظهر أحد الدوائر اﻷولمبية

مؤشرات لمساعدتك في حل المسألة:
أ- بالنسبة للجزء اﻷول : سنقوم برسمها جميعا برسم كل دائرة على حدة مثال
coord = [[20,30], [120,30], [220, 30], [70,80], [170,80]]
- المستطيل اﻷبيض هو خلفية للمعطى canvas و ليس مستطيل في حد ذاته
- سنستعمل حلقة while i < 5 لتفادي تكرار رسم الدوائر
داخل while نجد 
   x1, y1 = coord[i][0], coord[i][1]
    can.create_oval(x1, y1, x1+100, y1 +100, width =2, outline =coul[i])
مع إضافة شيئ آخر بسيط أترك اكتشافه لكم نستعمله دائما مع while.
- الجزء الصعب موجود لم يتبقى إلاّ القليل.
ب- سنقوم برسم كل حلقة في وظيفة def مستقلة يتم استدعائها من خلال button.


ملاحظة: أي أسئلة أخرى تتعلق بهذا البرنامج يمكنكم طرحها علي من خلال التعليقات و الذي يبقى مفتوحا لكافة الزوار الكرام وسأجيبكم عنها فور قرائتها.