Если вы хотите расширить свои элементы дневника, лучше поместить элементы дневника во внешний файл и прочитать их в своей бэкэнд-библиотеке. Также вы должны поместить проверку ограничений в бэкэнд-библиотеку. Тогда ваше основное приложение не нужно будет менять из-за изменения элементов дневника.
Я изменил ваш бэкэнд (PhotoDiaryLib.py
) код, используя класс, как показано ниже:
from PIL import ImageTk, Image
import json
class PhotoDiary:
def __init__(self, width=500, height=500):
self.imageWidth = width
self.imageHeight = height
self.current = -1
self.diary = None
self.loadDiaries()
def loadDiaries(self):
with open('diaries.json') as f:
self.diaries = json.load(f)
def getDiaryList(self):
return self.diaries.keys()
def getDiaryImage(self, diary):
return self.diaries[diary]['image']
def setDiary(self, diary):
self.diary = diary
self.diaryDetails = self.diaries[diary]['items']
self.current = -1
def getImage(self, imageName):
originalImage = Image.open(imageName)
imageRatio = float(originalImage.size[0]) / float(originalImage.size[1])
if imageRatio > 1:
targetSize=(self.imageWidth, int(self.imageHeight/imageRatio))
else:
targetSize=(int(self.imageWidth*imageRatio), self.imageHeight)
resizedImage = originalImage.resize(targetSize, Image.ANTIALIAS)
return ImageTk.PhotoImage(resizedImage)
def get(self, index):
''' get the diary item at given index '''
if 0 <= index < len(self.diaryDetails):
self.current = index
details, imageName = self.diaryDetails[index]
return details, self.getImage(imageName)
return None, None
# navigation functions
next = lambda self: self.get(self.current+1)
previous = lambda self: self.get(self.current-1)
И diaries.json
содержит что-то вроде следующего:
{
"Fish": {
"image": "images/fish.jpg",
"items": [
["Test1", "images/1.jpg"],
["Test2", "images/2.jpg"],
["Test3", "images/3.jpg"],
["Test4", "images/4.png"]
]
},
"Birds": {
"image": "images/birds.jpg",
"items": [
...
]
},
"Mammals": {
"image": "images/mammals.jpg",
"items": [
...
]
},
"Snakes": {
"image": "images/snakes.jpg",
"items": [
...
]
}
}
Вы можете добавить больше элементов в файл JSON.
Затем измените ваше основное приложение, чтобы обслужить изменения бэкэнд-библиотеки:
from tkinter import *
from PIL import ImageTk,Image
from PhotoDiaryLib import PhotoDiary
class PhotoDiaryApp:
def __init__(self):
self.mainWindow = Tk()
self.mainWindow.title("Diary")
self.pd = PhotoDiary(500, 500)
self.current = StringVar()
# diary list
diaryFrame = Frame(self.mainWindow, bg='blue')
for i, item in enumerate(self.pd.getDiaryList()):
imgtk = ImageTk.PhotoImage(file=self.pd.getDiaryImage(item))
btn = Radiobutton(diaryFrame, text=item, image=imgtk, compound=TOP, indicatoron=0, variable=self.current, value=item)
btn.config(command=lambda d=item:self.changeDiary(d))
btn.grid(row=0, column=i, sticky='ew', ipadx=10)
btn.image = imgtk
if i == 0: self.current.set(item)
diaryFrame.pack(fill=X)
# diary detail frame
detailFrame = Frame(self.mainWindow)
detailFrame.pack(fill=BOTH, expand=1)
self.photoFrame = Frame(detailFrame)
self.labelFrame = Frame(detailFrame)
self.controlFrame = Frame(detailFrame)
self.canvasImage = Canvas(self.photoFrame, width=500, height=500)
self.canvasImage.pack()
self.photo = self.canvasImage.create_image(250, 250, image=None)
self.photoDetails = StringVar()
self.photoLabel = Label(self.labelFrame, textvariable=self.photoDetails)
self.photoLabel.pack()
self.previousButton = Button(self.controlFrame, command=self.previousEntry, text="Previous", width=10)
self.previousButton.pack(side='left')
self.previousNext = Button(self.controlFrame, command=self.nextEntry, text="Next", width=10)
self.previousNext.pack(side='left')
self.photoFrame.pack()
self.labelFrame.pack()
self.controlFrame.pack(pady=10)
# show first diary
self.changeDiary(self.current.get())
self.mainWindow.mainloop()
def changeDiary(self, diary):
#print(self.pd.diary, diary)
if self.pd.diary != diary:
print('Changed to diary:', diary)
self.pd.setDiary(diary)
self.nextEntry()
def updateDiary(self, details, image):
''' update photo details and image '''
if details and image:
self.photoDetails.set(details)
self.photoImage = image
self.canvasImage.itemconfig(self.photo, image=image)
def previousEntry(self):
self.updateDiary(*self.pd.previous())
def nextEntry(self):
self.updateDiary(*self.pd.next())
executeWindow = PhotoDiaryApp()