Advertisement
jimkilled

GRAPHICS V8 main.py

Dec 21st, 2020
616
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.13 KB | None | 0 0
  1. # GRAPHICS V8 main.py
  2. from tkinter import *
  3. from tkinter import ttk
  4. from tkinter import colorchooser
  5. from graphics import *
  6. from math import *
  7.  
  8.  
  9. def initialize_window(window, title, size=(1024, 720), sizable=(False, False)):
  10.     '''
  11.    Устанавливает заголовок окна, размеры по осям X, Y и устанавливает возможность изменения по осям X, Y
  12.    args - window (Tk), title (str), size (tuple(int, int)), sizable (tuple(bool, bool))
  13.    return - None
  14.    '''
  15.     window.title(title)
  16.     window.geometry(f'{size[0]}x{size[1]}')
  17.     window.resizable(sizable[0], sizable[1])
  18.  
  19.  
  20. def initialize_widgets(window, start, size=(1024, 720)):
  21.     MARK = Label(window, text='By George Golubev Lyceum №8. 2020', font=('Arial', 10, 'bold'))
  22.     MARK.place(x=1150, y=840)
  23.  
  24.     global canvas
  25.     canvas = Canvas(window, bg='#fff', width=size[0], height=size[1])
  26.     canvas.place(x=start[0], y=start[1])
  27.  
  28.     global text_func
  29.     text_func = Label(window, text='y(x) =', font=('Arial', 13, 'bold'))
  30.     text_func.place(x=1040, y=354)
  31.  
  32.     but_func = Button(window, text='Сгенерировать', command=get_choosen_graphic_n_draw)
  33.     but_func.place(x=1165, y=380)
  34.  
  35.     but_erase_last_func = Button(window, width=11, text='Стереть', command=erase_graphic)
  36.     but_erase_last_func.place(x=1295, y=40)
  37.  
  38.     but_erase_all = Button(window, width=11, text='Стереть всё', command=erase_graphics)
  39.     but_erase_all.place(x=1295, y=70)
  40.  
  41.     but_hide_graph = Button(window, width=11, text='Скрыть', command=hideshow_graphic)
  42.     but_hide_graph.place(x=1295, y=100)
  43.  
  44.  
  45.     # Отображение
  46.     global func_listbox
  47.     func_listbox = Listbox(window, width=25, height=20, selectmode=EXTENDED)
  48.     func_listbox.place(x=1135, y=20)
  49.  
  50.  
  51.     # Виджеты, отвечающие за ввод пользователем функции
  52.     global func_choose,  chosen_type_func, func_type_choose, ent_first_coef, ent_second_coef
  53.     ent_first_coef = Entry(window, width=3)      
  54.     ent_first_coef.place(x=1095, y=357)
  55.  
  56.     text = Label(window, text='*', font=('Arial', 13, 'bold'))
  57.     text.place(x=1120, y=357)
  58.  
  59.     functions = [
  60.                 'acos(x)', 'acosh(x)', 'asin(x)', 'asinh(x)', 'atan(x)', 'atan2(x,x)', 'atanh(x)', 'ceil(x)',
  61.                 'cos(x)', 'cosh(x)', 'exp(x)', 'expm1(x)', 'fabs(x)', 'factorial(x)', 'log(x)', 'log10(x)',
  62.                 'log1p(x)', 'log2(x)','sin(x)','sinh(x)', 'sqrt(x)', 'tan(x)', 'tanh(x)', 'tau(x)', 'trunc(x)'
  63.                 ]
  64.     func_choose = ttk.Combobox(window, values=functions, width=20)
  65.     func_choose.place(x=1140, y=356)
  66.  
  67.     chosen_type_func = StringVar()
  68.     types = ['SIMPLE', 'POLAR']
  69.  
  70.     func_type_choose = ttk.Combobox(window, textvar=chosen_type_func, values=types, width=10)
  71.     func_type_choose.place(x=1140, y=420)
  72.     func_type_choose.current(0)
  73.     chosen_type_func.trace('w', change_func_type)
  74.  
  75.     text = Label(window, text='+', font=('Arial', 13))
  76.     text.place(x=1290, y=354)
  77.  
  78.     ent_second_coef = Entry(window, width=3)
  79.     ent_second_coef.place(x=1310, y=356)
  80.  
  81.     # Изменение цвета графика
  82.     global color, but_color
  83.     color = '#000000'
  84.     but_color = Button(window, command=get_color, width=2, height=1, bg=color)
  85.     but_color.place(x=1300, y=380)
  86.  
  87.     # Масштабирование графика
  88.     global scale, graphic_scale
  89.     graphic_scale = 1
  90.     scale = 1
  91.     #BINDINGS
  92.     window.bind('<Return>', enter_function)
  93.     window.bind('<MouseWheel>', mouse_wheel)
  94.  
  95. def mouse_wheel(event):
  96.     '''
  97.    Приближение или отдаление графика функции с помощью колёсика мыши
  98.    '''
  99.     global scale, graphic_scale
  100.     # -120 down, 120 up
  101.     if event.delta == 120:
  102.         # Используется в set_coordinat для корректирования значений x и y при масштабировании
  103.         graphic_scale *= 2
  104.     elif event.delta == -120 and scale >= -1:
  105.         graphic_scale /= 2
  106.  
  107.     if event.delta == 120:
  108.         canvas.scale('all', 512, 360, 2, 2)
  109.     elif event.delta == -120:
  110.         canvas.scale('all', 512, 360, 0.5, 0.5)
  111.  
  112. def change_func_type(index, value, op):
  113.     '''
  114.    Меняет текст перед окном ввода функции
  115.    '''
  116.     if func_type_choose.get() == 'POLAR':
  117.         text_func.config(text='r(t) =')
  118.     elif func_type_choose.get() == 'SIMPLE':
  119.         text_func.config(text='y(x) =')
  120.  
  121.  
  122. def create_graphic_grid(delay, size=(1024, 720)):
  123.  
  124.     width = size[0]
  125.     height = size[1]
  126.  
  127.     middle_cord_x = (width)//2
  128.     middle_cord_y = (height)//2
  129.  
  130.     # Созадние осей графика
  131.     canvas.create_line(middle_cord_x, height, middle_cord_x, 0, width=3, arrow=LAST)
  132.     canvas.create_line(0, middle_cord_y, width, middle_cord_y, width=3, arrow=LAST)
  133.  
  134.     start_x = middle_cord_x % delay
  135.     start_y = middle_cord_y % delay
  136.  
  137.     # Создание сетки графика, меток и цифр
  138.     for i in range(start_x, width, delay):
  139.         canvas.create_line(i, 0, i, height, fill='grey')                        # Создание линий сетки по оси OY
  140.         canvas.create_line(i, middle_cord_y-5, i, middle_cord_y+6, width=3)     # Создание меток (разделителей на оси OX)
  141.         text = (middle_cord_x - i) // delay
  142.         canvas.create_text(i-5, middle_cord_y+10, text=-text, fill='#f10', font=('Arial', 8, 'bold')) # Создание цифр на разделителях оси OX
  143.  
  144.     for i in range(start_y, height, delay):
  145.         canvas.create_line(0, i, width, i, fill='grey')                         # Создание линий сетки по оси OX
  146.         canvas.create_line(middle_cord_x-5, i, middle_cord_x+6, i, width=3)     # Создание меток (разделителей на оси OY)
  147.         text = (middle_cord_y - i) // delay
  148.         if text == 0:
  149.             continue
  150.         canvas.create_text(middle_cord_x-10, i, text=text, fill='#f10', font=('Arial', 8, 'bold'))    # Создание цифр на разделителях оси OY
  151.  
  152.  
  153.     global params
  154.     params = (middle_cord_x, middle_cord_y, delay)
  155.  
  156.  
  157. def get_color():
  158.     global color
  159.     color = colorchooser.askcolor()[1]
  160.     but_color.config(bg=color)
  161.  
  162.  
  163. def enter_function(event):
  164.     get_choosen_graphic_n_draw()
  165.  
  166.  
  167. def get_choosen_graphic_n_draw():
  168.     body_func = func_choose.get()
  169.     first_coef = ent_first_coef.get()
  170.     second_coef = ent_second_coef.get()
  171.  
  172.     if first_coef != '':
  173.         first_coef += ' * '
  174.  
  175.     if second_coef != '':
  176.         if '-' not in second_coef:
  177.             second_coef = ' + ' + second_coef
  178.         else:
  179.             second_coef = ' - ' + second_coef[1:]
  180.  
  181.     func = Graphic(first_coef + body_func + second_coef, type_func=func_type_choose.get())
  182.  
  183.     if func.function in graphs:
  184.         return
  185.  
  186.     functions.append(func)
  187.     graphs.append(func.function)
  188.     draw_graphic(func)  # params = (middle_cord_x, middle_cord_y, delay)
  189.     update_listbox('ADD', func)
  190.  
  191.  
  192. def hideshow_graphic():
  193.     selection = func_listbox.curselection()
  194.     for index in selection:
  195.         func = functions[index]
  196.  
  197.         if func.hided == True:
  198.             show_graphic(func, index)
  199.         else:
  200.             hide_graphic(func, index)
  201.  
  202.  
  203.  
  204. def hide_graphic(func, index):
  205.     '''
  206.    Скрывает график удаляя линии рисунка
  207.    args - func (Grpahic), index (Int)
  208.    return - None
  209.    '''
  210.     func.hided = True
  211.     delete_graphic_lines(func)
  212.     graphics.pop(func)
  213.     func_listbox.delete(index)
  214.     if func.type == 'SIMPLE':
  215.         func_listbox.insert(index,' y(x) = ' + func.function + ' СКРЫТ')
  216.     elif func.type == 'POLAR':
  217.         func_listbox.insert(index,' r(t) = ' + func.function + ' СКРЫТ')
  218.  
  219.  
  220. def show_graphic(func, index):
  221.     '''
  222.    Показывает график перерисовывая его
  223.    args - func (Grpahic), index (Int)
  224.    return - None
  225.    '''
  226.     func.hided = False
  227.     draw_graphic(func)
  228.     func_listbox.delete(index)
  229.     if func.type == 'SIMPLE':
  230.         func_listbox.insert(index,' y(x) = ' + func.function)
  231.     elif func.type == 'POLAR':
  232.         func_listbox.insert(index,' r(t) = ' + func.function)
  233.  
  234.  
  235. def delete_graphic_lines(func):
  236.     '''
  237.    Удаляет линии заданного графика
  238.    args - func (Grpahic)
  239.    return - None
  240.    '''
  241.     for line in graphics[func]:
  242.         canvas.delete(line)
  243.  
  244.  
  245. # Стерает выбранный график или последний, если график не выбран
  246. def erase_graphic():
  247.     global functions
  248.     selection = func_listbox.curselection()
  249.  
  250.     if len(selection) == 0:
  251.  
  252.         func = functions[-1]
  253.         functions.pop()
  254.         graphs.pop()
  255.  
  256.         index_func = len(functions)
  257.         delete_graphic_lines(func)
  258.         if not func.hided:
  259.             graphics.pop(func)
  260.         update_listbox('DELETEFUNC', index_func)
  261.  
  262.     else:
  263.         deleted_index = []
  264.         for i in sorted(list(selection), reverse=True):
  265.             index_func = i
  266.             func = functions[i]
  267.  
  268.             if func.hided:
  269.                 functions.remove(func)
  270.                 graphs.remove(func.function)
  271.                 deleted_index.append(index_func)
  272.             else:
  273.                 functions.remove(func)
  274.                 graphs.remove(func.function)
  275.                 delete_graphic_lines(func)
  276.                 graphics.pop(func)
  277.                 deleted_index.append(index_func)
  278.  
  279.         deleted_index.sort(reverse=True)
  280.         for i in deleted_index:
  281.             update_listbox('DELETEFUNC', i)
  282.  
  283.  
  284. # Удаляет все графики, а также очищает массивы
  285. def erase_graphics():
  286.     global graphics, functions, graphs
  287.  
  288.     for function in graphics:
  289.         delete_graphic_lines(function)
  290.  
  291.     graphs = []
  292.     functions = []
  293.     graphics = {}
  294.     update_listbox('DELETEALL')
  295.  
  296.  
  297. def draw_graphic(func):
  298.     global color
  299.     '''
  300.    Рисует график по точкам
  301.    args - func (Grpahic)
  302.    return - None
  303.    '''
  304.     graphic = []
  305.     x_dots = func.dots[0]
  306.     y_dots = func.dots[1]
  307.     for i in range(1, len(x_dots)-1):
  308.         try:
  309.             if x_dots[i] != None and x_dots[i-1] != None:
  310.                 last_x, last_y = set_coordinat(x_dots[i-1], y_dots[i-1], *params)
  311.                 x, y = set_coordinat(x_dots[i], y_dots[i], *params)
  312.                 graphic.append(canvas.create_line(last_x, last_y, x, y, fill=color, width=3))
  313.         except Exception:
  314.             continue
  315.     graphics[func] = graphic
  316.  
  317.  
  318. def set_coordinat(x, y, middle_cord_x, middle_cord_y, delay):
  319.     '''
  320.    Устанавливает координаты точки на графике
  321.    args - x (int), y (int), middle_cord_x (int), middle_cord_y (int), delay(int)
  322.    return - x (int), y (int)
  323.    '''
  324.     x = middle_cord_x + x*delay*graphic_scale
  325.     y = middle_cord_y - y*delay*graphic_scale
  326.     return x, y
  327.  
  328.  
  329. def update_listbox(action, func=None, index=None):
  330.     '''
  331.    args - action (str), index (int)
  332.    return - None
  333.    '''
  334.     # Удаляет все графики
  335.     if action == 'DELETEALL':
  336.         func_listbox.delete(0, func_listbox.size())
  337.     # Удаляет выбранный график
  338.     elif action == 'DELETEFUNC':
  339.         func_listbox.delete(index)
  340.     # Добавляет графиик
  341.     elif action == 'ADD':
  342.         if func.type == 'SIMPLE':
  343.             func_listbox.insert(len(functions)-1,' y(x) = ' + func.function)
  344.         elif func.type == 'POLAR':
  345.             func_listbox.insert(len(functions)-1,' r(t) = ' + func.function)
  346.  
  347.  
  348. def main():
  349.     global graphics, functions, graphs
  350.     graphics = {}
  351.     functions = []
  352.     graphs = []
  353.  
  354.     size_of_window = (1400, 900)
  355.     root = Tk()
  356.     start = (10, 10)
  357.     initialize_window(root, 'Graphics', size_of_window)
  358.     initialize_widgets(root, start)
  359.  
  360.     delay = 40
  361.     create_graphic_grid(delay)
  362.     root.mainloop()
  363.  
  364.  
  365. if __name__ == "__main__":
  366.     main()
  367.  
  368. # made by George Golubev Lyceum №8
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement