Считывание программой файл, может кто знает решение?
Получилось создать окна для построения квадратов и записать их координат в файл, но кто знает как сделать так чтобы программа смогла прочитать эти координаты и нарисовать по ним квадраты? Может найдется человек которому в кайф исправить код и помочь мне сократить его (очень нужно сдать лабораторную), а то чтобы вывести второй квадрат написала полный бред. По нажатию на кнопку ОК координаты сохраняются в файл, лучше всего набирать:
Координаты первого квадрата: 2 2 4
Координаты другого квадрата: 0 0 1
Спасибо)
import tkinter as tk
import tkinter.messagebox as tkmb
class MyWindow(tk.Frame):
def __init__(self):
self.root=tk.Tk()
super().__init__(self.root)
menu_main=tk.Menu(self.root)
self.root.config(menu=menu_main)
menu1=tk.Menu(menu_main)
menu_main.add_cascade(label="File",menu=menu1)
menu1.add_command(label="Quit",command=self.ext)
menu2=tk.Menu(menu_main)
menu_main.add_cascade(label="Edit",menu=menu2)
menu2.add_command(label="Input square",command=self.inp)
self.canva=tk.Canvas(self.root,width=600,height=600,bg="white")
self.canva.pack()
self.xa=0
self.ya=0
self.xb=0
self.yb=0
self.xc=0
self.yc=0
self.xd=0
self.yd=0
self.xas=0
self.yas=0
self.xbs=0
self.ybs=0
self.xcs=0
self.ycs=0
self.xds=0
self.yds=0
self.show()
self.root.mainloop()
def show(self):
self.canva.delete("all")
self.canva.create_line(self.scale(self.xa),self.scale(self.ya),
self.scale(self.xb),self.scale(self.yb))
self.canva.create_line(self.scale(self.xb),self.scale(self.yb),
self.scale(self.xc),self.scale(self.yc))
self.canva.create_line(self.scale(self.xc),self.scale(self.yc),
self.scale(self.xd),self.scale(self.yd))
self.canva.create_line(self.scale(self.xa),self.scale(self.ya),
self.scale(self.xd),self.scale(self.yd))
self.canva.create_line(self.scale(self.xas),self.scale(self.yas),
self.scale(self.xbs),self.scale(self.ybs))
self.canva.create_line(self.scale(self.xbs),self.scale(self.ybs),
self.scale(self.xcs),self.scale(self.ycs))
self.canva.create_line(self.scale(self.xcs),self.scale(self.ycs),
self.scale(self.xds),self.scale(self.yds))
self.canva.create_line(self.scale(self.xas),self.scale(self.yas),
self.scale(self.xds),self.scale(self.yds))
def scale(self,value):
return 300+60*value
def ext(self):
if tkmb.askyesno("Exit","Do you want to exit?"):
self.root.destroy()
def inp(self):
child(self)
class child(tk.Toplevel):
def __init__(self,mother):
super().__init__()
self.mother=mother
self.geometry('300x170+300+250')
self.resizable(False,False)
self.grab_set()
self.focus_set()
self.label1=tk.Label(self,text="XA=")
self.entry1=tk.Entry(self,width=3,font=10)
self.label1.grid(row=0,column=0)
self.entry1.grid(row=0,column=1)
self.label2=tk.Label(self,text="YA=")
self.entry2=tk.Entry(self,width=3,font=10)
self.label2.grid(row=0,column=2)
self.entry2.grid(row=0,column=3)
self.label3=tk.Label(self,text="XB=")
self.entry3=tk.Entry(self,width=3,font=10)
self.label3.grid(row=0,column=4)
self.entry3.grid(row=0,column=5)
self.label4=tk.Label(self,text="XA=")
self.entry4=tk.Entry(self,width=3,font=10)
self.label4.grid(row=1,column=0)
self.entry4.grid(row=1,column=1)
self.label5=tk.Label(self,text="YA=")
self.entry5=tk.Entry(self,width=3,font=10)
self.label5.grid(row=1,column=2)
self.entry5.grid(row=1,column=3)
self.label6=tk.Label(self,text="XB=")
self.entry6=tk.Entry(self,width=3,font=10)
self.label6.grid(row=1,column=4)
self.entry6.grid(row=1,column=5)
self.button1=tk.Button(self,text="Cancel")
self.button1.grid(row=4,column=6)
self.button1.bind("<Button-1>",self.ext)
self.button2=tk.Button(self,text="Ok")
self.button2.grid(row=4,column=7)
self.button2.bind("<Button-1>",self.saveext)
def ext(self,event):
self.destroy()
def saveext(self,event):
self.todestroy=True
file = open('text.txt','a+')
file.write("\nКоординаты первого квадрата: "+ self.entry1.get()+" "+self.entry2.get()+"
"+self.entry3.get()+"\n"+"Координаты другого квадрата: "+self.entry4.get()+" "+self.entry5.get()+"
"+self.entry6.get() + '\n'+"------------------------------------------------")
file.close()
try:
if self.entry1.get()!="":
self.mother.xa=float(self.entry1.get())
except ValueError:
self.todestroy=False
tkmb.showinfo("Error",ValueError)
try:
if self.entry2.get()!="":
self.mother.ya=float(self.entry2.get())
except ValueError:
self.todestroy=False
tkmb.showinfo("Error",ValueError)
try:
if self.entry3.get()!="":
self.mother.xb=float(self.entry3.get())
except ValueError:
self.todestroy=False
tkmb.showinfo("Error",ValueError)
try:
if self.entry4.get()!="":
self.mother.xas=float(self.entry4.get())
except ValueError:
self.todestroy=False
tkmb.showinfo("Error",ValueError)
try:
if self.entry5.get()!="":
self.mother.yas=float(self.entry5.get())
except ValueError:
self.todestroy=False
tkmb.showinfo("Error",ValueError)
try:
if self.entry6.get()!="":
self.mother.xbs=float(self.entry6.get())
except ValueError:
self.todestroy=False
tkmb.showinfo("Error",ValueError)
a=self.mother.xa-self.mother.xb
self.mother.xb=self.mother.xa-a
self.mother.yb=self.mother.ya
self.mother.xc=self.mother.xa-a
self.mother.yc=self.mother.ya+a
self.mother.xd=self.mother.xa
self.mother.yd=self.mother.ya+a
self.mother.show()
a=self.mother.xas-self.mother.xbs
self.mother.xbs=self.mother.xas-a
self.mother.ybs=self.mother.yas
self.mother.xcs=self.mother.xas-a
self.mother.ycs=self.mother.yas+a
self.mother.xds=self.mother.xas
self.mother.yds=self.mother.yas+a
self.mother.show()
if self.todestroy:
self.destroy()
MyWindow()
Ответы (1 шт):
Ну вот как-то так. Хранит и рисует сколько угодно квадратов. Сколько можно ввести квадратов за раз тоже настраивается через константу в коде.
В общем, используйте списки, кортежи, словари. Итерируйтесь по ним при помощи циклов. И тогда не придётся писать кучу однотипных строк кода отличающихся в одной букве и путаться в десятках переменных.
import tkinter as tk
import tkinter.messagebox as tkmb
class MyWindow(tk.Frame):
FILENAME = "text.txt"
def __init__(self):
self.root = tk.Tk()
super().__init__(self.root)
self.root.protocol("WM_DELETE_WINDOW", self.ext) # перехват закрытия окна
menu_main=tk.Menu(self.root)
self.root.config(menu=menu_main)
for m_lbl, submenu in {"File": {"Quit" : self.ext},
"Edit": {"Input square": self.inp,
"Delete last" : self.del_last}}.items():
menu = tk.Menu(menu_main, tearoff=False)
menu_main.add_cascade(label=m_lbl, menu=menu)
for lbl, cmd in submenu.items():
menu.add_command(label=lbl, command=cmd)
self.canva=tk.Canvas(self.root, width=600, height=600, bg="white")
self.canva.pack()
self.rects = [] # хранит квадраты в виде троек чисел: [X, Y, Size]
def run(self):
self.load()
self.show()
self.root.mainloop()
def show(self):
self.canva.delete("all")
for rect in self.rects:
coords = [rect[0] , rect[1] , # XY одного угла
rect[0]+rect[2], rect[1]+rect[2]] # XY другого
self.canva.create_rectangle(*map(self.scale, coords)) # применяем масштабирование на список координат
def scale(self, value):
return 300+60*value
def ext(self):
if tkmb.askyesno("Exit", "Do you want to exit?"):
self.root.destroy()
def inp(self):
child(self)
def del_last(self):
if len(self.rects):
self.rects.pop()
self.save()
self.show()
def save(self):
with open(self.FILENAME, 'w') as file:
for i, rect in enumerate(self.rects):
file.write(f"Координаты {i+1}-го квадрата: {' '.join(map(str, rect))}\n")
def load(self):
try:
with open(self.FILENAME, 'r') as file:
for line in file.read().splitlines():
if line.startswith('Координаты '):
self.rects.append(list(map(float, line.split(" ")[3:6])))
except FileNotFoundError:
pass
class child(tk.Toplevel):
NUM_RECTS_TO_ASK = 2 # сколько можно ввести квадратов одновременно
def __init__(self,mother):
super().__init__()
self.mother = mother
self.geometry('300x170+300+250')
self.resizable(False, False)
self.grab_set()
self.focus_set()
self.entry = []
for i in range(self.NUM_RECTS_TO_ASK):
self.entry.append([])
for n, text in enumerate(["XA", "YA", "XB"]):
label = tk.Label(self, text=f"{text}=")
self.entry[i].append(tk.Entry(self, width=3, font=10))
label.grid(row=i, column=n*2)
self.entry[i][n].grid(row=i, column=n*2+1)
for n, (text, func) in enumerate({"Cancel": self.ext,
"Ok" : self.saveext}.items()):
button = tk.Button(self, text=text)
button.grid(row=self.NUM_RECTS_TO_ASK, column=6+n)
button.bind("<Button-1>", func)
def ext(self, event):
self.destroy()
def saveext(self, event):
while True:
try:
for entry in self.entry:
rect = [entry[n].get() for n in range(3)]
if all(rect):
rect = list(map(float, rect))
rect[2] -= rect[0] # длина стороны квадрата
self.mother.rects.append(rect)
except ValueError:
tkmb.showinfo("Error", ValueError)
return
else:
break
self.mother.save()
self.destroy()
self.mother.show()
wnd = MyWindow()
wnd.run()
Координаты 1-го квадрата: 1.0 1.0 1.0
Координаты 2-го квадрата: 2.0 2.0 2.0
Координаты 3-го квадрата: -1.0 -1.0 -1.0
Координаты 4-го квадрата: 2.0 -2.0 -1.0
Координаты 5-го квадрата: -1.7 2.1 2.0
Координаты 6-го квадрата: -2.0 -2.0 4.0
Координаты 7-го квадрата: -1.2 -1.2 2.4
