Advertisement
jimkilled

graphics v4

Dec 14th, 2020
700
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.70 KB | None | 0 0
  1. from tkinter import *
  2. from tkinter import ttk
  3. from math import *
  4.  
  5.  
  6. def initialize_window(window, title, size=(1024, 720), sizable=(False, False)):
  7.     '''
  8.    Устанавливает заголовок окна, размеры по осям X, Y и устанавливает возможность изменения по осям X, Y
  9.    args - window (Tk), title (str), size (tuple(int, int)), sizable (tuple(bool, bool))
  10.    return - None
  11.    '''
  12.     window.title(title)
  13.     window.geometry(f'{size[0]}x{size[1]}')
  14.     window.resizable(sizable[0], sizable[1])
  15.  
  16.  
  17. def initialize_widgets(window, start, size=(1024, 720)):
  18.     global canvas
  19.     canvas = Canvas(window, bg='#fff', width=size[0], height=size[1])
  20.     canvas.place(x=start[0], y=start[1])
  21.  
  22.     text = Label(window, text='y = ', font=('Arial', 13, 'bold'))
  23.     text.place(x=1130, y=347)
  24.  
  25.     global ent_func
  26.     ent_func = Entry(window, width='20')
  27.     ent_func.place(x=1168, y=350)
  28.  
  29.     but_func = Button(window, text='Сгенерировать', command=get_and_draw_graphic)
  30.     but_func.place(x=1175, y=374)
  31.  
  32.     but_erase_last_func = Button(window, text='Стереть', command=erase_graphic)
  33.     but_erase_last_func.place(x=1175, y=400)
  34.  
  35.     but_erase_all = Button(window, text='Стереть всё', command=erase_graphics)
  36.     but_erase_all.place(x=1175, y=426)
  37.  
  38.     but_hide_graph = Button(window, text='Скрыть', command=hide_graphic)
  39.     but_hide_graph.place(x=1175, y=452)
  40.  
  41.     text = Label(window, text='y =', font=('Arial', 13, 'bold'))
  42.     text.place(x=115, y=748)
  43.  
  44.     global func_listbox
  45.     func_listbox = Listbox(window, width=30, height=20, selectmode=EXTENDED)
  46.     func_listbox.place(x=1145, y=20)
  47.  
  48.     scroll = Scrollbar(window, command=func_listbox.yview, orient=VERTICAL)
  49.     scroll.place(x=1329, y=20)
  50.  
  51.     func_listbox.config(yscrollcommand=scroll.set)
  52.  
  53.     window.bind('<Return>', enter_function)
  54.  
  55.     global func_choose, ent_first_coef, ent_second_coef
  56.     ent_first_coef = Entry(window, width='3')
  57.     ent_first_coef.place(x=150, y=751)
  58.  
  59.     text = Label(window, text='*', font=('Arial', 13, 'bold'))
  60.     text.place(x=174, y=751)
  61.  
  62.     functions = [
  63.                 'acos(x)', 'acosh(x)', 'asin(x)', 'asinh(x)', 'atan(x)', 'atan2(x)', 'atanh(x)', 'ceil(x)',
  64.                 'cos(x)', 'cosh(x)', 'exp(x)', 'expm1(x)', 'fabs(x)', 'factorial(x)', 'log(x)', 'log10(x)',
  65.                 'log1p(x)', 'log2(x)','sin(x)','sinh(x)', 'sqrt(x)', 'tan(x)', 'tanh(x)', 'tau(x)', 'trunc(x)'
  66.                 ]
  67.  
  68.     func_choose = ttk.Combobox(window, values=functions, width=10)
  69.     func_choose.place(x=190, y=750)
  70.  
  71.     text = Label(window, text='+', font=('Arial', 13))
  72.     text.place(x=273, y=748)
  73.  
  74.     ent_second_coef = Entry(window, width='3')
  75.     ent_second_coef.place(x=290, y=751)
  76.  
  77.     but_func_choose = Button(window, text='Сгенерировать', command=get_choosen_graphic_n_draw)
  78.     but_func_choose.place(x=185, y=780)
  79.  
  80.  
  81.  
  82.     helpmenu = Menu(window)
  83.  
  84.  
  85. def get_and_draw_graphic():
  86.     func = ent_func.get()
  87.     if func in functions:
  88.         return
  89.     functions.append(func)
  90.     create_graphic(func, *params)  # params = (middle_cord_x, middle_cord_y, delay)
  91.     update_listbox('ADD')
  92.  
  93. def get_choosen_graphic_n_draw():
  94.     body_func = func_choose.get()
  95.     first_coef = ent_first_coef.get()
  96.     second_coef = ent_second_coef.get()
  97.  
  98.     if first_coef != '':
  99.         first_coef += ' * '
  100.  
  101.     if second_coef != '':
  102.         if '-' not in second_coef:
  103.             second_coef = ' + ' + second_coef
  104.         else:
  105.             second_coef = ' - ' + second_coef[1:]
  106.  
  107.     func = first_coef + body_func + second_coef
  108.     if func in functions:
  109.         return
  110.     functions.append(func)
  111.     create_graphic(func, *params)  # params = (middle_cord_x, middle_cord_y, delay)
  112.     update_listbox('ADD')
  113.  
  114.  
  115. def create_graphic_grid(delay, size=(1024, 720)):
  116.  
  117.     width = size[0]
  118.     height = size[1]
  119.  
  120.     middle_cord_x = (width)//2
  121.     middle_cord_y = (height)//2
  122.  
  123.     # Созадние осей графика
  124.     canvas.create_line(middle_cord_x, height, middle_cord_x, 0, width=3, arrow=LAST)
  125.     canvas.create_line(0, middle_cord_y, width, middle_cord_y, width=3, arrow=LAST)
  126.  
  127.     start_x = middle_cord_x % delay
  128.     start_y = middle_cord_y % delay
  129.  
  130.     # Создание сетки графика
  131.     # for i in range(start_x, width, delay):
  132.     #     canvas.create_line(i, y0, i, height, fill='grey')
  133.     # for i in range(start_y, height, delay):
  134.     #     canvas.create_line(x0, i, width, i, fill='grey')
  135.  
  136.     # Создание сетки графика, меток и цифр
  137.     for i in range(start_x, width, delay):
  138.         canvas.create_line(i, 0, i, height, fill='grey')                        # Создание линий сетки по оси OY
  139.         canvas.create_line(i, middle_cord_y-5, i, middle_cord_y+6, width=3)     # Создание меток (разделителей на оси OX)
  140.         text = (middle_cord_x - i) // delay
  141.         canvas.create_text(i-5, middle_cord_y+10, text=-text, fill='#f10', font=('Arial', 8, 'bold')) # Создание цифр на разделителях оси OX
  142.  
  143.     for i in range(start_y, height, delay):
  144.         canvas.create_line(0, i, width, i, fill='grey')                         # Создание линий сетки по оси OX
  145.         canvas.create_line(middle_cord_x-5, i, middle_cord_x+6, i, width=3)     # Создание меток (разделителей на оси OY)
  146.         text = (middle_cord_y - i) // delay
  147.         if text == 0:
  148.             continue
  149.         canvas.create_text(middle_cord_x-10, i, text=text, fill='#f10', font=('Arial', 8, 'bold'))    # Создание цифр на разделителях оси OY
  150.  
  151.  
  152.     global params
  153.     params = (middle_cord_x, middle_cord_y, delay)
  154.  
  155.  
  156. def enter_function(event):
  157.     get_and_draw_graphic()
  158.  
  159.  
  160. # Скрывает график удаляя линии рисунка
  161. def hide_graphic():
  162.     selection = func_listbox.curselection()
  163.     for i in range(len(selection)):
  164.         index_func = selection[i]
  165.         func = func_listbox.get(selection[i])[5:]
  166.  
  167.         if ' СКРЫТ' in func:
  168.             func = func[:-6]
  169.             show_graphic(func, index_func)
  170.  
  171.         else:
  172.             hided_graphics.append(func)
  173.             # Стерание графика выбранного графика
  174.             for line in graphics[func]:
  175.                 canvas.delete(line)
  176.  
  177.             graphics.pop(func)
  178.             func_listbox.delete(index_func)
  179.             func_listbox.insert(index_func,' y = ' + func + ' СКРЫТ')
  180.  
  181.  
  182. # Перерисовывает скрытый график
  183. def show_graphic(func, index_func):
  184.     hided_graphics.remove(func)
  185.     create_graphic(func, *params)
  186.     func_listbox.delete(index_func)
  187.     func_listbox.insert(index_func,' y = ' + func)
  188.  
  189.  
  190.  
  191. # Стерает выбранный график или последний, если график не выбран
  192. def erase_graphic():
  193.     global functions, hided_graphics
  194.     selection = func_listbox.curselection()
  195.  
  196.     if len(selection) == 0:
  197.         func = functions[-1]
  198.  
  199.         if func in hided_graphics:
  200.             return
  201.  
  202.         functions.pop()
  203.         index_func = len(functions)
  204.  
  205.         for line in graphics[func]:
  206.             canvas.delete(line)
  207.  
  208.         graphics.pop(func)
  209.         update_listbox('DELETEFUNC', index_func)
  210.  
  211.     else:
  212.         deleted_index = []
  213.         for i in selection:
  214.             index_func = selection[i]
  215.             func = func_listbox.get(selection[i])[5:]
  216.  
  217.             if ' СКРЫТ' in func:
  218.                 func = func[:-6]
  219.                 functions.remove(func)
  220.                 hided_graphics.remove(func)
  221.                 deleted_index.append(index_func)
  222.  
  223.             else:
  224.                 functions.remove(func)
  225.  
  226.                 for line in graphics[func]:
  227.                     canvas.delete(line)
  228.  
  229.                 graphics.pop(func)
  230.                 deleted_index.append(index_func)
  231.  
  232.         deleted_index.sort(reverse=True)
  233.         for i in deleted_index:
  234.             update_listbox('DELETEFUNC', i)
  235.  
  236.  
  237.  
  238. # def erase_last_graphic():
  239. #     last_func = functions[len(functions)-1]
  240. #     functions.pop()
  241. #     for line in graphics[last_func]:
  242. #         canvas.delete(line)
  243. #     graphics.pop(last_func)
  244. #     update_listbox('DELETELAST')
  245.  
  246. # Удаляет все графики, а также очищает массивы
  247. def erase_graphics():
  248.     global graphics, functions
  249.  
  250.     for function in graphics:
  251.         for line in graphics[function]:
  252.             canvas.delete(line)
  253.  
  254.     hided_graphics = []
  255.     functions = []
  256.     graphics = {}
  257.     update_listbox('DELETEALL')
  258.  
  259.  
  260. def create_graphic(func, middle_cord_x, middle_cord_y, delay):
  261.     graphic = []
  262.     for x in range(-10000, 10000):
  263.         try:
  264.             last_x = (x - 1)/100
  265.             last_y = set_y_func_value(last_x, func)
  266.             x /= 100                                   # Уменьшение x для получения более точного рисунка графика
  267.             y = set_y_func_value(x, func)
  268.             last_x, last_y = set_coordinat(last_x, last_y, middle_cord_x, middle_cord_y, delay)
  269.             # x = middle_cord_x + x*delay
  270.             # y = middle_cord_y - (y*delay)
  271.             x, y = set_coordinat(x, y, middle_cord_x, middle_cord_y, delay)
  272.             graphic.append(canvas.create_line(last_x, last_y, x, y, width=3))
  273.         except:
  274.             continue
  275.     graphics[func] = graphic
  276.  
  277.  
  278. def set_y_func_value(x, func):
  279.     # Преобразование текстовой функции в исполняемый код
  280.     y = eval(func)
  281.     return y
  282.  
  283.  
  284. def set_coordinat(x, y, middle_cord_x, middle_cord_y, delay):
  285.     x = middle_cord_x + x*delay
  286.     y = middle_cord_y - (y*delay)
  287.     return x, y
  288.  
  289.  
  290. def update_listbox(action, index=None):
  291.     # Удаляет все графики
  292.     if action == 'DELETEALL':
  293.         func_listbox.delete(0, func_listbox.size())
  294.     # Удаляет выбранный график
  295.     elif action == 'DELETEFUNC':
  296.         func_listbox.delete(index)
  297.     # Добавляет графиик
  298.     elif action == 'ADD':
  299.         func_listbox.insert(len(functions)-1, ' y = ' + str(functions[-1]) )
  300.  
  301.  
  302. def main():
  303.     global size
  304.     global graphics, functions, hided_graphics
  305.     graphics = {}
  306.     functions = []
  307.     hided_graphics =[]
  308.  
  309.     size_of_window = (1400, 1000)
  310.     root = Tk()
  311.     start = (10, 10)
  312.     initialize_window(root, 'Graphics', size_of_window)
  313.     initialize_widgets(root, start)
  314.  
  315.     delay = 40
  316.     create_graphic_grid(delay)
  317.     root.mainloop()
  318.  
  319.  
  320. if __name__ == "__main__":
  321.     main()
  322.  
  323. # made by Egor Golubev Lyceum №8
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement