首页 > 解决方案 > Tkinter 中的日记

问题描述

大家好,有作业日记,我已经创建了我的日记,但我担心的是,我的教授希望我们在这个文件中制作 4 篇日记。请帮我在里面添加额外的日记。我真的不知道。希望这个网站得到我正在寻找的东西

标签: python-3.xtkinter

解决方案


如果您想扩展您的日记项目,最好将日记项目放在外部文件中并在您的后端库中读取它们。此外,您还应该将边界检查放在后端库中。那么你的主应用程序将不需要因为日记项目的变化而改变。

我已经使用如下类修改了您的后端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()

推荐阅读