- 3.2 Користувальницькі підпрограми і моделювання. модуль Tkinter
- 3.2.1 Моделювання математичних функцій
3.2 Користувальницькі підпрограми і моделювання. модуль Tkinter
Набагато більш серйозними можливостями, ніж модуль turtle, володіє модуль Tkinter. Основне призначення цього модуля - створення графічних інтерфейсів (GUI - Graphical User Interface) для програм на Python. Але завдяки наявності елемента графічного інтерфейсу (або, як кажуть, "віджета") canvas ( "полотно") Tkinter можна застосовувати для малювання на підставі координат, розрахованих за формулами, використовуючи доступні елементи векторної графіки - криві, дуги, еліпси, прямокутники тощо .
Розглянемо задачу побудови графіка деякої функції по обчислюваним точкам за допомогою Tkinter.
Оскільки Tkinter дозволяє працювати з елементами GUI, створимо вікно заданого розміру, встановимо для нього заголовок і колір фону "полотна", а також забезпечимо вікно програмної "кнопкою". На "полотні" визначимо систему координат і намалюємо "косинусоид".
import Tkinter
import math
# Tk = Tkinter.Tk () tk.title ( "Sample") # button = Tkinter.Button (tk) button [ "text"] = "Закрити" button [ "command"] = tk.quit button.pack () # canvas = Tkinter.Canvas (tk) canvas [ "height"] = 360 canvas [ "width"] = 480 canvas [ "background"] = "# eeeeff" canvas [ "borderwidth"] = 2 canvas.pack () # canvas.create_text (20, 10, text = "2 0, 10") canvas.create_text (460, 350, text = "460, 350") # points = [] ay = 150 y0 = 150 x0 = 50 x1 = 470 dx = 10 #for n in range (x0, x1, dx):
y = y0-ay * math.cos (n * dx) pp = (n, y) points.append (pp) # canvas.create_line (points, fill = "blue", smooth = 1) # y_axe = [] yy = (x0, 0) y_axe.append (yy) yy = (x0, y0 + ay) y_axe.append (yy) canvas.create_line (y_axe, fill = "black", width = 2) # x_axe = [] xx = (x0, y0) x_axe.append (xx) xx = (x1, y0) x_axe.append (xx) canvas.create_line (x_axe, fill = "black", width = 2) # tk.mainloop ()Мал. 3.4. Вікно Tkinter з кнопкою і графіком
Подивимося на результат ( Мал. 3.4 ), І розберемо текст прикладу.
Отже, перші три рядки програми зрозумілі - встановлюється кодова сторінка і підключаються бібліотеки. Оскільки в прикладі повинні використовуватися тригонометричні функції, необхідно підключити модуль math.
Потім створюється так зване "кореневе" вікно - кажучи науковою мовою, "екземпляр интерфейсного об'єкта Tk", який являє собою просто вікно без вмісту. Для цього вікна встановлюється значення властивості title (створюється заголовок).
Далі починається заповнення вікна інтерфейсними об'єктами ( "віджетами" - widgets). В даному прикладі використовується два об'єкти - кнопка і "полотно". Для розміщення об'єкта у вікні використовується метод pack (), а порядок об'єктів визначається порядком виконання цієї функції.
Кнопка створюється як екземпляр об'єкта Button модуля Tkinter, пов'язаний з "кореневих" вікном. Для кнопки можна встановити текст напису (властивість text) і зв'язати кнопку з виконанням будь-якої команди (функції або процедури), встановивши значення властивості command.
У наведеному прикладі кнопка пов'язана з командою закриття вікна і припинення роботи інтерпретатора, проте ніщо не заважає також закривати вікно нашого "додатка" звичайним чином - за допомогою стандартної кнопки закриття вікна у верхньому правому куті.
Після створення і розміщення кнопки створюється полотно. Для елемента (об'єкта) canvas вказуються висота, ширина, колір фону і відступ від кордонів вікна (таким чином, розміри вікна виходять дещо більше, ніж розміри об'єкта canvas). Розміри вікна автоматично підлаштовуються так, щоб забезпечити розміщення всіх об'єктів (елементів інтерфейсу).
Перш ніж приступати до малювання, досліджуємо систему координат. Оскільки розміри вікна вже нами задані, корисно визначити, де знаходиться точка з координатами (0, 0). Як видно з спроб вивести значення координат за допомогою методу canvas.create_text (), початок координат знаходиться в верхньому лівому кутку полотна.
Тепер, визначившись з координатами, можна вибрати масштабні коефіцієнти і зсуви і сформувати координати точок для малювання кривої.
При використанні методу canvas. create_line () в якості координат потрібно список пар точок (кортежів) (x, y). Цей список формується в циклі з кроком dx.
Для лінії графіка встановлюються колір і режим згладжування. Згладжування забезпечує деяку "плавність" кривої. Якщо його прибрати, лінія буде складатися з відрізків прямих. Крім того, для ліній можна встановлювати товщину, як це показано на прикладі осей координат.
3.2.1 Моделювання математичних функцій
Нехай потрібно побудувати графік функції, обраній із заданого списку. Тут потрібно вже використання додаткових інтерфейсних елементів модуля Tkinter, а також створення власних (призначених для користувача) процедур або функцій для полегшення розуміння коду.
Результат розв'язання задачі (варіант зовнішнього вигляду "додатка") показаний на Мал. 3.5 .
Для вибору виду математичної функції використовується список, що розкривається, після вибору виду функції і натискання на кнопку "Намалювати" на "полотні" схематично зображується графік цієї функції. Кнопка "Закрити" закриває наше "додаток". Тепер подивимося на код.
import Tkinter
import math
# # Користувальницькі процедуриdef plot_x_axe (x0, y0, x1):
x_axe = [] xx = (x0, y0) x_axe.append (xx) xx = (x1, y0) x_axe.append (xx) canvas.create_line (x_axe, fill = "black", width = 2) #def plot_y_axe (x0, y0, y1):
y_axe = [] yy = (x0, y1) y_axe.append (yy) yy = (x0, y0) y_axe.append (yy) canvas.create_line (y_axe, fill = "black", width = 2) #def plot_func0 (x0, x1, dx, y0, y1):
x0i = int (x0) x1i = int (x1) y0i = int (y0) y1i = int (y1) a = y1 b = (y0-y1) / (x1-x0) points = []for x in range (x0i, x1i, dx):
y = int (a + b * x) pp = (x, y) points.append (pp) # canvas.create_line (points, fill = "blue", smooth = 1) plot_y_axe (x0i, y0i, y1i) plot_x_axe ( x0i, y0i, x1i) #def plot_func1 (x0, x1, dx, y0, y1):
x0i = int (x0) x1i = int (x1) y0i = int (y0) y1i = int (y1) a = y0 b = y0-y1 points = []for x in range (x0i, x1i, dx):
y = int (a-y1i * b / x) pp = (x, y) points.append (pp) # canvas.create_line (points, fill = "blue", smooth = 1) plot_y_axe (x0i, y0i, y1i) plot_x_axe (x0i, y0i, x1i) #def plot_ func2 (x0, x1, dx, y0, y1):
x0i = int (x0) x1i = int (x1) y0i = int (y0) y1i = int (y1) a = (y0-y1) / (15 * x1) b = 1 + ((y0-y1) / (x1 -x0)) points = []for x in range (x0i, x1i, dx):
y = y0i-int (a * (x-x0i) ** b) pp = (x, y) points.append (pp) # canvas.create_line (points, fill = "blue", smooth = 1) plot_y_axe (x0i , y0i, y1i) plot_x_axe (x0i, y0i, x1i) #def plot_ func3 (x0, x1, dx, y0, y1):
x0i = int (x0) x1i = int (x1) y0i = int (y0) y1i = int (y1) ay = 150 y0i = 150 points = []for x in range (x0i, x1i, dx):
y = y0i-ay * math.cos (x * dx) pp = (x, y) points.append (pp) # canvas.create_line (points, fill = "blue", smooth = 1) plot_y_axe (x0i, 0, y0i + ay) plot_x_axe (x0i, y0i, x1i) #def DrawGraph ():
fn = func.get () f = fn [0] x0 = 50.0 y0 = 250.0 x1 = 450.0 y1 = 50.0 dx = 10 #if f == "0":
canvas.delete ( "all") plot_ func0 (x0, x1, dx, y0, y1)elif f == "1":
canvas.delete ( "all") plot_ func1 (x0, x1, dx, y0, y1)elif f == "2":
canvas.delete ( "all") plot_ func2 (x0, x1, dx, y0, y1)& nbs