تحدثنا في المقال السابق عن الواجهات الرسومية للتطبيقات باستخدام TKinter، وتطرقنا للنافذة الرئيسية التي هي أساس أي تطبيق مكتوب باستخدام الواجهات وشرحنا مجموعة من خصائصها، سنكمل في هذا المقال ونتحدث عن العناصر التي نضعها على النافذة الرئيسية، والتي يطلق عليها مسمى Widgets.
هذه المقالة جزء من سلسلة مقالات تشرح أساسيات مكتبة TKinter لبناء واجهات رسومية في بايثون، وإليك فهرس السلسلة كاملة:
- واجهات المستخدم الرسومية في بايثون باستخدام TKinter.
- مدخل إلى عناصر واجهات المستخدم الرسومية Widgets في بايثون.
- حاوية العنوان label وصناديق المدخلات Entry في واجهة المستخدم الرسومية في بايثون.
- الأزرار Buttons ومربعات الرسائل messagebox في واجهة المستخدم الرسومية في بايثون.
- مربعات الاختيار وأزرار الانتقاء والقوائم في واجهة المستخدم الرسومية في بايثون.
Widgets
هي عبارة عن عناصر التحكم التي نضعها على النافذة ليتمكن المستخدم من التفاعل معها، حيث توضح له معنى أو تطلب منه أدخال أمر معين أو تأخذ منه أمرًا لتنفيذ مهمة مطلوبة مثل الأزرار، ومربعات الإدخال وحاويات العناوين ومربعات الإختيار والقوائم وغيرها، الجدول التالي يوضح مجموعة من أهم العناصر التي يمكننا إضافتها على النافذة:
اسم العنصر | الوصف | |
---|---|---|
Label | حاوية العنوان | يستخدم لعرض سلسلة نصية أو صورة . |
Message | الرسالة | شبيه بحاوية العنوان يستخدم لعرض سلسلة نصية مكونة من أكثر من سطر. |
Buttons | الأزرار | يستخدم لإضافة أزرار تفاعلية في النافذة عند النقر عليها يتم نداء دالة معينة تؤدي وظيفة معينة. |
Entry | صندوق المدخلات | يستخدم لقراءة المدخلات التي يكتبها المستخدم باستخدام لوحة المفاتيح |
Frame | الإطار | يستخدم لترتيب العناصر داخل النافذة بحيث يكون كالحاوية لهم. |
Menus | القوائم | تستخدم لعرض قائمة منسدلة أو منبثقة مكونة من مجموعة من أزرار القائمة. |
Menubutton | أزرار القائمة | عنصر عبارة عن مزيج يدمج ما بين الأزرار والقائمة بحيث يكون من ضمن مجموعة من الخيارات عند النقر عليه يتم تنفيذ أمر معين. |
ListBox | مربع القائمة | يستخدم لعرض قائمة يختار المستخدم منها عنصر. |
Checkbutton | صناديق التأشير | عبارة عن مربعات تسمح للمستخدم بأن يختار منها (تسمح بأكثر من خيار) وتكون بوضعية مفعل أو غير مفعل. |
Radiobutton | أزرار الانتقاء | شبيهة بصناديق التأشير تستخدم بالغالب كمجموعة خيارات لابد من اختيار واحد منها فقط. |
يوجد جيلين من العناصر في مكتبة Tkinter:
- العناصر الكلاسيكية التقليدية والتي تم طرحها عام 1991.
- العناصر الحديثة التي تمت إضافتها عام 2007 تسمى عناصر TTk اختصارًا لكلمة Tk themed تستبدل العديد من العناصر القديمة وليس كلها .
من مميزات استخدام الجيل الجديد من العناصر الحديثة أن مظهر العناصر يختلف باختلاف نظام تشغيل جهاز الحاسب الذي تعمل عليه ليصبح متوافقًا معه، كذلك تسمح العناصر الحديثة بالفصل بين خصائص مظهرها وبين الأوامر التفاعلية التي تقوم بها في ملفات تنسيق مختلفة عن بعضها، ويعتبر من الجيد دائمًا استخدام الجيل الجديد من العناصر باستخدام القالب tkinter.ttk، السطر التالي يستدعي العناصر الكلاسيكية والجديدة:
from tkinter import * from tkinter import ttk
توضح الشفرة التالية كيفية إنشاء حاوية عنوان Label و زرار Button باستخدام الطريقة الكلاسيكية:
from tkinter import * main_window = Tk() # النافذة الرئيسية main_window.title(" (الطريقة الكلاسيكية) ") classicL=Label(main_window, text='Classic Label') classicL.pack() classicB=Button(main_window, text='Classic Button') classicB.pack() main_window.mainloop()
توضح الشفرة التالية كيفية إنشائهما بإستخدام الطريقة الحديثة بإضافة اسم الصنف ttk قبل اسم العنصر:
from tkinter import ttk main_window = Tk() # النافذة الرئيسية main_window.title("(الطريقة الحديثة ) ") ThemedL=ttk.Label(main_window, text='Themed Label') ThemedL.pack() ThemedB=ttk.Button(main_window, text='Themed Button') ThemedB.pack() main_window.mainloop()
ستبدو المخرجات عند تشغيل الشيفرة بالشكل التالي:
الطريقة الحديثة والكلاسيكية لعناصر واجهات المستخدم
قد لا يبدو الاختلاف بينهما واضحًا، لكن كما سبق وقلنا يعتمد المظهر كثيرًا على نوع نظام التشغيل الذي تعمل عليه.
التحكم بخصائص العناصر
جميع هذه العناصر لها مجموعة متنوعة من الخصائص بخيارات مختلفة، تختلف باختلاف العناصر حسب ما يتميز به كل عنصر، كما توجد خصائص مشتركة بين غالبية العناصر مثل: لون الخلفية، ولون الخلفية عندما يكون العنصر فعالًا، والنص المكتوب، ولون النص ونوع الخط، ولون النص عندما يكون العنصر فعالًا، والعرض والارتفاع بالبكسل، وشكل المؤشر …إلخ. ويُسمح لنا بالتحكم فيها من خلال 3 طرق إما في وقت الإنشاء من خلال معاملات الدوال أو بعد إنشاء العنصر من خلال استخدام القواميس أو الدالة config
:
1. في وقت الإنشاء من خلال معاملات الدوال keyword arguments
وهذه هي الطريقة التي استخدمناها حتى الآن لوضع نص في حاوية العنوان أو في الزر كما في المثال السابق بتحديد اسم معامل الدالة بنوع الخاصية المطلوبة وهي text
ومن ثم إعطائه قيمة النص المطلوبة أو مثلًا خاصية لون الخط foreground
ونضعه مثلًا أزرق blue
.
L=Label(main_window, text='نص باللون الأزرق' ,foreground='blue')
سيبدو الشكل على النحو التالي :
إضافة خصائص وقت الإنشاء
2. بعد إنشاء العنصر من خلال استخدام القواميس dictionary index
تفعل الشفرة التالية نفس الشيء ولكن من خلال الاستفادة من فكرة القواميس، فنقوم بمعاملة العنصر كقاموس ونستخدم اسم الخاصية المراد وضع قيمة لها كمفتاح للقاموس ونضع القيمة المرغوبة على النحو التالي:
L=Label(main_window) L['text']='نص باللون الأزرق' ['foreground']= 'blue'
3. بعد إنشاء العنصر باستخدام الدالة config
سنكرر نفس ما قمنا به ولكن باستخدام الدالة config
وإرسال المعاملات المطلوب تعديلها بشكل مشابه للطريقة الأولى على النحو التالي:
L=Label(main_window) L.config(text='نص باللون الأزرق' ,foreground='blue')
كيفية وضع العناصر على النافذة
يوجد ثلاثة طرق مختلفة لوضع العناصر على النافذة الرئيسية باستخدام ثلاثة دوال:
-
الدالة
Pack
: تضع العناصر على النافذة في مجموعة من المربعات الطولية والأفقية وهي محدودة بأربعة خيارات: يمين، يسار، أسفل، أعلى النافذة. -
الدالة
Place
: تضع العناصر على النافذة باستخدام الإحداثيات السينية X والصادية Y في المستوي الثنائي. -
الدالة
grid
: تضع العناصر على النافذة باستخدام شبكة ثنائية مكونة من أعمدة وصفوف.
اقتباسملاحظة مهمة: لا ينبغي الدمج بين الدوال الثلاثة في نفس النافذة الرئيسية، بل يفضل اختيار واحدة منها والالتزام باستخدامها.
إضافة العناصر باستخدام الدالة Pack
تعد الدالة Pack
أسهل طريقة لوضع العناصر على النافذة، و ترتب العناصر بجانب بعضها البعض عموديًا أو افقيًا بدلًا من تحديد الموضع الدقيق للعنصر، بكل بساطة يتم نداء الدالة بعد اسم العنصر المطلوب وضعه على النافذة كما شاهدنا في الأمثلة السابقة على النحو التالي:
Widget_name.pack()
يمكن التحكم بمكان العنصر من خلال استخدام الخاصية side
والتي يمكننا إعطائها 4 قيم مختلفة:
Side = LEFT or RIGHT or TOP or BOTTOM
سنرسم نافذة رئيسية نضيف لها 3 حاويات عنوان Label
باسم L1,L2,L3
على الترتيب باستخدام الدالة Pack
نضع لكل حاوية نصًا بلون أبيض باستخدام الخاصية fg
وهي اختصار foreground
أي لون النص، وخلفية بلون مختلف لكل حاوية باستخدام الخاصية bg
وهي اختصار Background
أي لون الخلفية، واستخدمنا الخاصية pady
لتبعد كل حاوية عن الأخرى مسافة 20 بكسل على المحور الصادي، ستكون الشفرة على النحو التالي:
from tkinter import * main_window = Tk() L1 = Label(main_window, text="أحمر",bg="red", fg="white") L1.pack(pady=20, side= TOP) L2 = Label(main_window, text="أخضر", bg="green", fg="white") L2.pack(pady=20, side= TOP) L3 = Label(main_window, text="أزرق", bg="blue", fg="white") L3.pack(pady=20, side= TOP) main_window.mainloop()
سنعيد تشغيل الشيفرة أكثر من مرة وسنستخدم في كل مرة اتجاهًا مختلفًا للخاصية side
ونرى كيف تقوم الدالة بترتيبهم مع بعضهم البعض في النافذة، عموديا عند استخدام الخيار TOP
أو BOTTOM
وأفقيًا عند اختيار LEFT
أو RIGHT
سنحصل على النتائج التالية:
استخدام الدالة pack
كما أشرنا آنفًا، تترك الخاصية pad
مساحة حول العنصر بمحيطه الخارجي تتمثل فيه الخاصيتين التاليتين:
-
pady
تترك مساحة حول العنصر على الإحداثي الصادي . -
padx
تترك مساحة حول العنصر على الإحداثي السيني.
وتوجد أيضًا الخاصية ipad
التي تترك مساحة حول العنصر بمحيطه الداخلي تتمثل في الخاصيتين التاليتين:
-
ipady
تترك مساحة بين العنصر وحدوده الداخلية على المحور الصادي. -
ipadx
تترك مساحة بين العنصر وحدوده الداخلية على المحور السيني.
تضع الشفرة التالية حدودًا حول العنصر من محيطه الخارجي ومحيطه الداخلي:
from tkinter import * main_window = Tk() L1 = Label(main_window, text="أحمر",bg="red", fg="white") L1.pack(padx=150 , pady=50 ,ipadx=150,ipady=200 ,side= TOP) main_window.mainloop()
فنحصل على الشكل التالي:
استخدام الخاصية pad و ipad
إضافة العناصر باستخدام الدالة place
تستخدم الدالة place
الإحداثيات السينية والصادية لوضع العناصر على النافذة، فيبدأ رسم العنصر من الزاوية العلوية اليسرى، وسنعيد استخدام الشفرة السابقة مع تبديل الدالة Pack
إلى الدالة place
وسنحاول وضع العناصر أسفل بعضها البعض متدرجة فنكتب الشفرة على النحو التالي:
from tkinter import * main_window = Tk() L1 = Label(main_window, text="أحمر",bg="red", fg="white") L1.place(x=0, y=0) L2 = Label(main_window, text="أخضر", bg="green", fg="white") L2.place(x=50, y=40) L3 = Label(main_window, text="أزرق", bg="blue", fg="white") L3.place(x=110, y=80) main_window.mainloop()
ونحصل على النتيجة التالية:
استخدام الدالة place
قد لا يكون استخدام الدالة place
متوافقًا مع جميع شاشات الأجهزة، لو قمت بتشغيل الشفرة السابقة على جهاز يعمل بنظام تشغيل ويندوز بدقة شاشة 1024* 768 فستظهر العناصر بشكل متناسق، بينما لو اختلفت دقة الشاشة وكانت عالية الدقة مثلًا فستظهر العناصر شديدة الصغر ومتداخلة، وعلى العكس لو كانت الدقة منخفضة قد لا تظهر العناصر كاملة، لذلك يفضل تجنب استخدامها قدر المستطاع حتى لا نقع في مثل هذه المشاكل عند اختلاف الدقة.
إضافة العناصر باستخدام الدالة grid
تقسم الدالة grid
النافذة الرئيسية إلى مجموعة من الأعمدة والصفوف بشكل افتراضي، لتكون بشكل تقريبي كالشبكة فتوضع العناصر فيها بتحديد رقم العمود ورقم الصف، يبدأ الترقيم من الصفر، وسنعيد ترتيب عناصرنا كما المثال السابق باستخدام الدالة grid
على النحو التالي:
from tkinter import * main_window = Tk() L1 = Label(main_window, text="أحمر",bg="red", fg="white") L1.grid(row=0, column=0) L2 = Label(main_window, text="أخضر", bg="green", fg="white") L2.grid(row=1, column=3) L3 = Label(main_window, text="أزرق", bg="blue", fg="white") L3.grid(row=2, column=6) main_window.mainloop()
وسنحصل على نفس شكل النافذة السابق.
ومن الخصائص التي يمكن التحكم بها لهذه الشبكة هي عرض الأعمدة والصفوف وقد قدمت لنا مكتبة Tkinter دالتين للتحكم بإعدادات الشبكة قبل بدء وضع العناصر عليها وهما الدالة columnconfigure
والتي تأخذ رقم العمود والدالة rowconfigure
والتي تأخذ رقم الصف ومن ثم تُعطى الدالة العرض المراد تحديده لكلٍ منهما وتكتب على النحو التالي:
main_window.columnconfigure(index, weight) main_window.rowconfigure(index, weight)
حيث تمثل index
رقم الصف أو العمود وتمثل weight
العرض المراد تحديده لهما، بالطبع العرض يكون كنسبة وتناسب مع بقية الأعمدة في الشبكة. كما نستطيع أيضًا أن نستخدم مع هذه الدالة الخاصيتان pad
و ipad
بالنفس الطريقة التي سبق شرحها.
الإطارات Frames
تعد الإطارات من العناصر المهمة لواجهات المستخدم الرسومية، فهي تستخدم لتجميع وتنظيم العناصر الأخرى بداخلها فتكون بمثابة الحاوية لهم، وتكون بمثابة مساحات مستطيلة توضع على النافذة الرئيسية لتنظيم تخطيط النافذة وترتيب وضع أماكن بقية العناصر عليها، كما يمكننا إنشاء إطار بداخل إطار آخر مما يعطينا قدرة أكبر على الترتيب.
والإطارات بالنسبة للنافذة كما الهيكل العظمي للجسد يساعد على استقامته ويعطيه المظهر الملائم والهيئة المطلوبة.
إنشاء الإطار داخل النافذة
يجري اختيار اسم المتغير المطلوب ليمثل الإطار ويستخدم الصنف Frame من مكتبة Tkinter، ويعطى الصنف أولًا المكان الذي نريد وضع الإطار فيه وهو النافذة الرئيسية، ومن ثم بإمكاننا إضافة بقية الخصائص على النحو التالي:
First_frame= Frame (main_window)
خصائص الإطار
يمكننا تغيير الكثير من خصائص الإطار كتعديل عرض width وطول height الإطار وكذلك تغيير لون الخلفية bg، وسمك الحدود bd، ونوع الحدود relief حيث يمكن إعطاءها قيم مختلفة مثل:
raised, flat, ridge, groove , sunken.
الشفرة التالية ترسم إطارين على النافذة الرئيسية أحدهما أخضر على اليمين والآخر أزرق على اليسار باستخدام الدالة pack
:
from tkinter import * main_window = Tk() main_window.title(" الإطارات ") right_frame=Frame(main_window,width=300,height=300,bg='green') right_frame.pack(side='right') left_frame=Frame(main_window,width=300,height=300,bg='blue') left_frame.pack(side='left') main_window.mainloop()
عند تشغيل الشفرة نحصل على التالي:
نافذة بإطار
كما قلنا سابقًا، الهدف الأساسي من الإطارات تنظيم النافذة، سنقوم برسم نافذة تحتوي على عدة إطارات في كل اتجاه، و سنوزع العناصر فيها على النحو التالي:
from tkinter import * main_window = Tk() main_window.title(" الإطارات ") top_frame=Frame(main_window,bg='red') top_frame.pack(side='top') top_button=Button(top_frame,text=' زرار في إطار علوي' ) top_button.pack(padx = 40, pady = 40) right_frame=Frame(main_window,bg='green') right_frame.pack(side='right') right_button=Button(right_frame,text=' زرار في إطار على اليمين' ) right_button.pack(padx = 40, pady = 40) left_frame=Frame(main_window,bg='blue') left_frame.pack(side='left') right_button=Button(left_frame,text=' زرار في إطار على اليسار' ) right_button.pack(padx = 40, pady = 40) bottom_frame=Frame(main_window,bg='yellow') bottom_frame.pack(side='bottom') bottom_button=Button(bottom_frame,text=' زرار في إطار سفلي' ) bottom_button.pack(padx = 40, pady = 40) main_window.mainloop()
وسنحصل على الشكل التالي:
نافذة بإطارات ملونة
الإطارات بحاوية عنوان LabelFrame
هي نوع مخصص من الإطارات حيث تكون كالإطارات العادية من حيث أنها تكون حاوية لعناصر واجهات المستخدم الرسومية وتزيد عليها باحتوائها على حاوية عنوان تزيد من وضوح الهدف من الإطار وإظهارًا لمزيد من الترتيب في النوافذ المعقدة التي تحتوي الكثير من العناصر.
تُنشأ الإطارات بحاوية عنوان باختيار اسم المتغير المطلوب ليمثل الإطار ويُستخدم الصنف LabelFrame من مكتبة Tkinter لذلك، ويعطى الصنف أولًا المكان الذي نريد وضع الإطار فيه وهو النافذة الرئيسية، ومن ثم نعطيه النص الذي نريد إظهاره كعنوان للإطار باستخدام الخاصية text ومن ثم يمكننا إضافة بقية الخصائص على النحو التالي:
labeled_frame=LabelFrame(main_window,bd=10,text="test")
سنعيد كتابة الشفرة السابقة باستخدام الإطارات بحاوية عنوان، وتكون الشفرة كاملة على النحو التالي:
from tkinter import * main_window = Tk() main_window.title(" الإطارات ") top_frame=LabelFrame(main_window,text="علوي",bg='red') top_frame.pack(side='top') top_button=Button(top_frame,text=' زرار في إطار علوي' ) top_button.pack(padx = 40, pady = 40) right_frame=LabelFrame(main_window,text="أيمن",bg='green') right_frame.pack(side='right') right_button=Button(right_frame,text=' زرار في إطار على اليمين' ) right_button.pack(padx = 40, pady = 40) left_frame=LabelFrame(main_window,text="أيسر",bg='blue') left_frame.pack(side='left') right_button=Button(left_frame,text=' زرار في إطار على اليسار' ) right_button.pack(padx = 40, pady = 40) bottom_frame=LabelFrame(main_window,text="سفلي",bg='yellow') bottom_frame.pack(side='bottom') bottom_button=Button(bottom_frame,text=' زرار في إطار سفلي' ) bottom_button.pack(padx = 40, pady = 40) main_window.mainloop()
وسنحصل على الشكل التالي:
نافذة بإطار بحاوية عنوان
تطبيق الآلة الحاسبة (الجزء الثاني)
سنطبق ما تعلمناه في هذا المقال على تطبيق الآلة الحاسبة، فسنحاول تقسيم النافذة إلى جزئين جزء تعرض فيه المدخلات وهي نتيجة ما يتم النقر عليه، وجزء ثانيٍ وهو جزء الأزرار والعمليات، سنقسم الشاشة إلى إطارين باستخدام الخاصية LabelFrame، الأول للجزء العلوي ونعطيه اسم input_frame و نعنونه بالعنوان "المدخلات"، والآخر للجزء السفلي باسم btns_frame ونعنونه بالعنوان "لوحة الأرقام والعمليات"، سنستخدم هنا نوعين من الإضافة أولًا للإطارات باستخدام الدالة pack ومن ثم باستخدام الشبكة grid لبقية العناصر داخل الإطارات، نضيف هذا الجزء على الشفرة السابقة على النحو التالي:
from tkinter import * from ctypes import windll windll.shcore.SetProcessDpiAwareness(1) mycalculator = Tk() mycalculator.title("آلة حاسبة بسيطة") mycalculator.geometry("575x740") mycalculator.resizable(False, False) input_frame=LabelFrame(mycalculator,text="المدخلات",bd=3,width=575) input_frame.pack(side=TOP) btns_frame = LabelFrame(mycalculator,text=" لوحة الأرقام والعمليات ", bg="white",width=575,bd=3) btns_frame.pack() mycalculator.mainloop()
حددنا عرض الإطارات بنفس عرض النافذة، و بحدود bd بمقدار عرض 3، وضعنا خلفية الإطار الثاني بلون أبيض.
واجهة الآلة الحاسبة الثانية
عند تشغيل الشفرة قد لا تبدو مختلفة عن الشفرة السابقة وذلك نتيجة لعدم وضعنا أي عنصر داخل الإطارات فقد لا تبدو حدودها واضحة، سنكمل في المقال التالي تطبيقنا ونضع العناصر داخل النافذة لتظهر لنا الإطارات بصورة واضحة طبعًا بعد التعرف عليها.
سنتناول في المقال التالي حاوية العنوان وصناديق المدخلات وهي ما يحتوي عليه الإطار العلوي في نافذة الآلة الحاسبة.
المصادر
- Introduction to Tkinter.
- Python GUI with Tkinter.
- Ttk Widgets.
- Tkinter Pack.
- Tkinter Grid.
- Common Widget Properties.
- How To Position Widgets In Tkinter.
- Tkinter Frame.
- Python Tkinter Frame.
- Python - Tkinter LabelFrame.
- Introduction to Programming Using Python by Y. Daniel Liang ) Chapter 9 GUI Programming Using Tkinter).
- Tony Gaddis - Starting Out with Python, Global Edition (2018, Pearson Education),(Chapter 13 GUI Programming).
اقرأ أيضًا
- المقال التالي: حاوية العنوان label وصناديق المدخلات Entry في واجهة المستخدم الرسومية في بايثون
- المقال السابق: واجهات المستخدم الرسومية في بايثون باستخدام TKinter
- برمجة الواجهات الرسومية باستخدام Tkinter
- تعلم البرمجة
- النسخة العربية الكاملة من كتاب: البرمجة بلغة بايثون
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.