10天速通Tkinter库——Day6:《植物杂交实验室》整体框架介绍

2024-08-27 18:28

本文主要是介绍10天速通Tkinter库——Day6:《植物杂交实验室》整体框架介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

整体介绍

1. 应用程序主窗口

1.1 主页面初始化

1.2 数据加载

1.3 子页面初始化

1.4 页面跳转和程序关闭处理

 1.4 PVZ_HL.py完整代码

2. 动画加载

3. 游戏主界面

4. 通用组件

5. 总结


整体介绍

一不小心就拖更了五天,私密马赛。但你们知道这五天我都是怎么过的吗,我起早贪黑(起不来一点),每天勤勤恳恳撸代码,做设计(谁家好人用ppt做设计哇),只为完成《植物杂交实验室》这个小项目(其实这是我的暑假作业)。先给大家看看效果:

1. 加载界面是录的gif(绝对不是为了偷懒),写了一个可以显示gif的功能。

 2. 杂交实验室的主界面,包含了五个按钮“基础植物图鉴”、“杂交植物图鉴”、“杂交实验”,“试验记录”,“返回”,以及一个每1分钟更新一次的建议框(这个丑丑的),界面我还是能看的过去的。

 3. 基础植物图鉴,和《植物大战僵尸》差不多,但是没做植物描述的动态效果

4. 杂交植物图鉴,与《植物大战僵尸杂交版》相比多了一个更多按钮,会跳转至一个界面,包含亲本植物和杂交方法。

5. 杂交实验,这个本应该是项目的核心,但是由于时间问题,来不及训练一个AI生成器,于是乎我使用了最原始查找匹配。(这就是设计与实现的距离,绝对不是我想偷懒)

还有一些功能测试:清空、植物为空,杂交方式为空,杂交失败案例......

6. 历史记录

其实还有声音,自我感觉效果还是可以的,毕竟用的是Tkinter这个最基础的GUI库,而且除去学习tkinter库,只花了一个礼拜左右的时间。所有组件如下:

今天我们先对整体框架、加载动画、游戏主界面和部分通用组件进行介绍。项目结构如下:

  • data:两个json保存游戏数据,一个是杂交植物数据,一个是杂交记录数据
  • images:包括设计图片、植物卡片图片、植物描述信息图片、屏幕组件图片
  • sounds:使用到的音频,包括背景音乐、点击按钮音频等等
  • source:全部源码

1. 应用程序主窗口

这部分是对上图中的root进行初始化。

1.1 主页面初始化

import tkinter as tk
class PVZ_HL(tk.Tk):def __init__(self):super().__init__()# 窗口创建self.init_window()self.title(game_name)self.iconbitmap(icon_path)

首先我定义了一个名为PVZ_HL的类,它继承自tk.Tk,作为应用程序的主窗口。

    def init_window(self):"""窗口初始化"""self.resizable(width=False, height=False)self.configure(bg='black')screen_width = self.winfo_screenwidth()screen_height = self.winfo_screenheight()x = (screen_width - window_width) // 2y = (screen_height - window_height) // 2self.geometry(f"{window_width}x{window_height}+{x}+{y}")

init_window方法中,进行了以下操作来初始化窗口:

  1. self.resizable(width=False, height=False):这行代码禁用了窗口大小调整功能。width=False表示窗口宽度不可调整,height=False表示窗口高度不可调整。

  2. self.configure(bg='black'):这行代码设置了窗口的背景颜色为黑色。

  3. 获取屏幕尺寸并计算窗口位置:

    • screen_width = self.winfo_screenwidth() 获取当前屏幕的宽度。
    • screen_height = self.winfo_screenheight() 获取当前屏幕的高度。
    • x = (screen_width - window_width) // 2 计算窗口在水平方向上的位置,使其居中显示。window_width是窗口的宽度。
    • y = (screen_height - window_height) // 2 计算窗口在垂直方向上的位置,使其居中显示。window_height是窗口的高度。
  4. self.geometry(f"{window_width}x{window_height}+{x}+{y}")

    • 这行代码设置了窗口的几何位置和大小。f"{window_width}x{window_height}"定义了窗口的大小,+{x}+{y}定义了窗口相对于屏幕左上角的位置。

这部分内容在10天速通Tkinter库——Day 2:窗口及布局中都有讲解。

1.2 数据加载

第一部分:加载植物卡片和植物描述图片。

基础植物卡片和描述均为48张,图鉴矩阵是6*8的,于是乎定义了同样大小的变量存储。

杂交植物卡片和描述均为92张,定义了两倍的大小的变量来存储,空余为None。

        # 数据加载self.basal_plant_card = [[None for _ in range(8)] for _ in range(6)]self.basal_plant_describe = [[None for _ in range(8)] for _ in range(6)]self.hybrid_plant_card =  [[None for _ in range(8)] for _ in range(12)]self.hybrid_plant_describe =  [[None for _ in range(8)] for _ in range(12)]self.basal_plant_load()self.hybrid_plant_load()def basal_plant_load(self):"""基础植物卡片和说明加载"""for row in range(6):for col in range(8):self.basal_plant_card[row][col]= image_load(57,78,basal_card_path,col+1+row*8,".jpg")self.basal_plant_describe[row][col] = image_load(287,462,basal_describe_path,col+1+row*8,".png")def hybrid_plant_load(self):"""杂交植物卡片和说明加载"""for row in range(12):for col in range(8):self.hybrid_plant_card[row][col]= image_load(57,78,hybrid_card_path,col+1+row*8,".jpg")self.hybrid_plant_describe[row][col] = image_load(287,462,hybrid_describe_path,col+1+row*8,".png")if row==11 and col==3:break

上述方法中用到了一个image_load函数,定义如下:

def image_load(width,height,path,num,suffix):"""主要用于加载植物卡片和植物描述, 主路径相同, id命名"""full_path = path + str(num)+suffiximage = Image.open(full_path)image = image.resize((width, height), Image.Resampling.LANCZOS)photo = ImageTk.PhotoImage(image)return photo    

 第二部分:加载游戏数据,包括杂交植物数据和杂交记录数据

这两个我都是使用json文件存储的,所以加载也很简单

        self.hybridizationPlants = json_dataload(hybridizationplants_data_path)self.recorditem = json_dataload(record_data_path)

 json_dataload函数定义如下:

def json_dataload(path):with open(path, 'r', encoding='utf-8') as file:data_list = json.load(file)return  data_list

1.3 子页面初始化

根据思维导图,我一共创建了9个子页面

        self.children['loading_screen'] = LoadingScreen(self)self.children['main_screen'] = MainScreen(self)self.children['breeding_screen'] = BreedingScreen(self)self.children['plant_catalog_screen'] = PlantCatalogScreen(self)self.children['hybrid_catalog_screen'] = HybridCatalogScreen(self)self.children['more_information_screen'] = MoreInformation(self)self.children['experiment_screen'] = ExperimentScreen(self)self.children['result_screen'] = ResultScreen(self)self.children['record_screen'] = RecordScreen(self)

在Python的Tkinter库中,通过self.children['screen_name'] = ScreenClass(self)这样的语句,可以创建一个新的窗口实例,并将其作为属性添加到了主窗口的对象中。

每个子窗口类(如LoadingScreenMainScreen等)都是一个Tkinter窗口的子类,继承了Tkinter的窗口功能,并包含特定的界面元素或行为。比如子界面hybrid_catalog_screen就可以使用self.hybrid_plant_card和self.hybrid_plant_describe来展示图鉴。

父类窗口的属性变量对于各个子类实例来说就如同全局变量,当一个子类实例对其进行修改时,其他子类实例再使用时便是修改后的内容。也就是说,杂交实验和杂交记录可以直接修改self.hybridizationPlants和self.recorditem,而图鉴和历史记录界面使用时就是更新后的内容,极大的降低了数据流操作难度。

1.4 页面跳转和程序关闭处理

页面跳转:一般是通过点击按钮完成的,点击事件处理如下

    def switch_to_screen(self, screen_name):"""界面跳转"""for page in self.children.values():page.pack_forget()self.children[screen_name].pack()

该方法的工作原理:

  1. for page in self.children.values(): 这行代码遍历 self.children 字典中的所有值,其中每个值是一个界面(或窗口)对象。self.children 之前在代码中被用来存储不同的界面实例。
  2. page.pack_forget() 这行代码调用每个界面实例的 pack_forget 方法,该方法将界面从显示中移除,但不销毁界面实例(这点很重要)。这样做是为了隐藏所有当前显示的界面。
  3. self.children[screen_name].pack() 这行代码获取名为 screen_name 的界面实例,并调用它的 pack 方法,将其显示在屏幕上。screen_name 是一个字符串,是 self.children 字典中键的名称。

 程序关闭:关闭弹窗和数据保存

 关闭弹窗在之前的学习中有过介绍,数据保存就是保存更改后的json文件

        self.protocol("WM_DELETE_WINDOW", self.on_close)def on_close(self):"""游戏关闭,保存数据"""if messagebox.askokcancel("退出", "确定要退出游戏吗?"):self.destroy()json_datasave(hybridizationplants_data_path,self.hybridizationPlants)json_datasave(record_data_path,self.recorditem)pygame.quit()

json_datasave函数如下:

def json_datasave(path,datalist):with open(path, 'w', encoding='utf-8') as file:json.dump(datalist, file, indent=4)

 1.4 PVZ_HL.py完整代码

  • 调用的库、图片路径在constants.py中定义
  • 一些常用工具在tool.py中定义
  • 子窗口类在各自的.py中定义
from constants import *
from tool import *
from BreedingScreen import BreedingScreen
from LoadingScreen import LoadingScreen,MainScreen
from CatalogScreen import PlantCatalogScreen, HybridCatalogScreen, MoreInformation
from ExperimentScreen import ExperimentScreen,ResultScreen
from RecordScreen import RecordScreen
# 应用程序主窗口
class PVZ_HL(tk.Tk):def __init__(self):super().__init__()# 数据加载self.basal_plant_card = [[None for _ in range(8)] for _ in range(6)]self.basal_plant_describe = [[None for _ in range(8)] for _ in range(6)]self.hybrid_plant_card =  [[None for _ in range(8)] for _ in range(12)]self.hybrid_plant_describe =  [[None for _ in range(8)] for _ in range(12)]self.basal_plant_load()self.hybrid_plant_load()self.hybridizationPlants = json_dataload(hybridizationplants_data_path)self.recorditem = json_dataload(record_data_path)# 窗口创建self.init_window()self.title(game_name)self.iconbitmap(icon_path)self.protocol("WM_DELETE_WINDOW", self.on_close)     pygame.mixer.music.play(loops=-1)  # 无限循环播放self.children['loading_screen'] = LoadingScreen(self)self.children['main_screen'] = MainScreen(self)self.children['breeding_screen'] = BreedingScreen(self)self.children['plant_catalog_screen'] = PlantCatalogScreen(self)self.children['hybrid_catalog_screen'] = HybridCatalogScreen(self)self.children['more_information_screen'] = MoreInformation(self)self.children['experiment_screen'] = ExperimentScreen(self)self.children['result_screen'] = ResultScreen(self)self.children['record_screen'] = RecordScreen(self)def basal_plant_load(self):"""基础植物卡片和说明加载"""for row in range(6):for col in range(8):self.basal_plant_card[row][col]= image_load(57,78,basal_card_path,col+1+row*8,".jpg")self.basal_plant_describe[row][col] = image_load(287,462,basal_describe_path,col+1+row*8,".png")def hybrid_plant_load(self):"""杂交植物卡片和说明加载"""for row in range(12):for col in range(8):self.hybrid_plant_card[row][col]= image_load(57,78,hybrid_card_path,col+1+row*8,".jpg")self.hybrid_plant_describe[row][col] = image_load(287,462,hybrid_describe_path,col+1+row*8,".png")if row==11 and col==3:breakdef init_window(self):"""窗口初始化"""self.resizable(width=False, height=False)self.configure(bg='black')screen_width = self.winfo_screenwidth()screen_height = self.winfo_screenheight()x = (screen_width - window_width) // 2y = (screen_height - window_height) // 2self.geometry(f"{window_width}x{window_height}+{x}+{y}")def switch_to_screen(self, screen_name):"""界面跳转"""for page in self.children.values():page.pack_forget()self.children[screen_name].pack()def on_close(self):"""游戏关闭,保存数据"""if messagebox.askokcancel("退出", "确定要退出游戏吗?"):self.destroy()json_datasave(hybridizationplants_data_path,self.hybridizationPlants)json_datasave(record_data_path,self.recorditem)pygame.quit()if __name__ == '__main__':"""主程序入口"""app = PVZ_HL()app.mainloop()

2. 动画加载

在创建 LoadingScreen 类时,我定义了一个游戏加载界面,该界面继承自 tk.Frametk.Frame 是 Tkinter 中的一个基础组件,用于创建窗口中的容器,可以包含其他控件。在创建 LoadingScreen 类的实例时,这些实例将作为游戏主界面的一个子组件存在。

class LoadingScreen(tk.Frame):"""游戏加载界面:一段加载动画"""def __init__(self, parent):super().__init__(parent)

 加载动画实现如下:

        self.loading_label = tk.Label(self)self.loading_label.pack()self.loading_image = Image.open(loading_path )self.loading_photo = ImageTk.PhotoImage(self.loading_image)self.loading_label.config(image=self.loading_photo)def update_loading(i):if i < 103:self.loading_image.seek(i)self.loading_photo = ImageTk.PhotoImage(self.loading_image)self.loading_label.config(image=self.loading_photo)self.after(66, update_loading, i + 1)else:self.loading_label.config(image=tk.PhotoImage())self.update_idletasks()self.on_loading_complete()update_loading(0)self.pack()
  1. 首先创建了一个 tk.Label 组件 self.loading_label 并进行了布局。
  2. 然后打开了一个指定路径的图像 self.loading_image ,并将其转换为 ImageTk.PhotoImage 类型 self.loading_photo ,设置为 self.loading_label 的图像。
  3. 接着定义了一个名为 update_loading 的函数,用于逐步更新加载动画的图像帧。如果当前帧索引 i 小于 103 ,就更新图像并通过 self.after 方法每隔 66 毫秒调用自身来更新下一帧。当 i 达到 103 时,清除加载动画的图像,并调用 self.update_idletasks 来处理闲置任务,然后调用 self.on_loading_complete 表示加载完成。
  4. 最后调用 update_loading(0) 启动加载动画,并对当前组件进行布局。
    def on_loading_complete(self):"""点击杂交实验室按钮的事件处理"""self.master.switch_to_screen('main_screen')

 这里使用self.master调用父类的方法进行页面跳转,使用父类属性也是如此。

3. 游戏主界面

游戏主界面非常简单,包含一个背景图片和一个杂交实验室进入按钮

class MainScreen(tk.Frame):"""原游戏主界面:包含一个“杂交实验室”按钮"""def __init__(self, parent):super().__init__(parent)self.mainmenu = create_background(self,image_path=mainscreen_path)self.menu_button = create_button(self,dark_image_path=menubutton1_path,light_image_path=menubutton2_path,width=133,height=106,locate_x=450,locate_y=478,command=self.on_breeding_button_click)self.pack()def on_breeding_button_click(self):# 点击杂交实验室按钮的事件处理self.master.switch_to_screen('breeding_screen')

 创建背景函数非常简单,加载一张图片,使用Label铺满全屏

def create_background(root,image_path):# 加载图片背景image = Image.open(image_path)image = image.resize((880, 600), Image.Resampling.LANCZOS)photo = ImageTk.PhotoImage(image)label = tk.Label(root, image=photo)label.photo = photolabel.pack()

 我在之前的文章中就吐槽过Tkinter库的按钮丑丑的,边框和透明无法处理,于是在博客10天速通Tkinter库——Day 4:花样button中提出了两种解决方案。在本项目中,全部按钮都要使用背景图片,于是乎用了Label来实现,并且是明暗两张图片,增加视觉效果。

def create_button(root,dark_image_path, light_image_path,width,height,locate_x,locate_y,command):"""创建按钮:加载暗和明亮两张图片, 模拟点击效果"""img_dark = Image.open(dark_image_path)img_light = Image.open(light_image_path)img_dark = img_dark.resize((width, height), Image.Resampling.LANCZOS)img_light = img_light.resize((width, height), Image.Resampling.LANCZOS)photo_dark = ImageTk.PhotoImage(img_dark)photo_light = ImageTk.PhotoImage(img_light)def on_enter(event):label.config(image=photo_light)def on_leave(event):label.config(image=photo_dark)def on_click(event):button_music.play()command()# 创建Label作为按钮label = tk.Label(root, image=photo_dark, cursor="hand2",bd=0)label.photo = photo_dark  # 保持对图像的引用label.place(x=locate_x,y=locate_y)# 绑定鼠标事件label.bind("<Enter>", on_enter)label.bind("<Leave>", on_leave)label.bind("<Button-1>", on_click)  # 绑定鼠标左键点击事件

4. 通用组件

所有方法都在tool.py中定义,一部分在上文中已经介绍了,由于close_button和back_button几乎在每一页中都有使用,就详细定义了。

from constants import *def create_background(root,image_path):# 加载图片背景image = Image.open(image_path)image = image.resize((880, 600), Image.Resampling.LANCZOS)photo = ImageTk.PhotoImage(image)label = tk.Label(root, image=photo)label.photo = photolabel.pack()def create_button(root,dark_image_path, light_image_path,width,height,locate_x,locate_y,command):"""创建按钮:加载暗和明亮两张图片, 模拟点击效果"""img_dark = Image.open(dark_image_path)img_light = Image.open(light_image_path)img_dark = img_dark.resize((width, height), Image.Resampling.LANCZOS)img_light = img_light.resize((width, height), Image.Resampling.LANCZOS)photo_dark = ImageTk.PhotoImage(img_dark)photo_light = ImageTk.PhotoImage(img_light)def on_enter(event):label.config(image=photo_light)def on_leave(event):label.config(image=photo_dark)def on_click(event):button_music.play()command()# 创建Label作为按钮label = tk.Label(root, image=photo_dark, cursor="hand2",bd=0)label.photo = photo_dark  # 保持对图像的引用label.place(x=locate_x,y=locate_y)# 绑定鼠标事件label.bind("<Enter>", on_enter)label.bind("<Leave>", on_leave)label.bind("<Button-1>", on_click)  # 绑定鼠标左键点击事件def close_button(root,path_1,path_2,clear=0):"""关闭按钮"""def on_close_button_click():# 点击关闭按钮的事件处理if clear==2:root.on_clear_button_click()root.method_choose_optionmenu()root.pack()elif clear==94 or clear==82:root.empty_describe = empty_describe(root,Y=clear)root.pack() root.master.switch_to_screen('main_screen')create_button(root,dark_image_path=path_1,light_image_path=path_2,width=85,height=25,locate_x=770,locate_y=567,command=on_close_button_click)       def back_button(root,path_1,path_2,clear=0):"""返回按钮"""def on_back_button_click():# 点击返回按钮的事件处理 if clear==2:root.on_clear_button_click()root.method_choose_optionmenu()root.pack()elif clear==94 or clear==82:root.empty_describe = empty_describe(root,Y=clear)root.pack()     root.master.switch_to_screen('breeding_screen')create_button(root,dark_image_path=path_1,light_image_path=path_2,width=85,height=25,locate_x=24,locate_y=567,command=on_back_button_click)         def empty_describe(root,Y=94):"""空白植物描述基础植物图鉴和杂交植物图鉴的位置不同, 用参数Y区分"""image = Image.open(emptydescribe_path)image = image.resize((287, 462), Image.Resampling.LANCZOS)photo = ImageTk.PhotoImage(image)label = tk.Label(root, image=photo,bd=0)label.photo = photolabel.place(x=530,y=Y)def json_dataload(path):with open(path, 'r', encoding='utf-8') as file:data_list = json.load(file)return  data_listdef json_datasave(path,datalist):with open(path, 'w', encoding='utf-8') as file:json.dump(datalist, file, indent=4)def image_load(width,height,path,num,suffix):"""主要用于加载植物卡片和植物描述, 主路径相同, id命名"""full_path = path + str(num)+suffiximage = Image.open(full_path)image = image.resize((width, height), Image.Resampling.LANCZOS)photo = ImageTk.PhotoImage(image)return photo    def id_to_photo(id,data):"""根据id查找图片, 在图鉴中使用"""hang =  (id-1)//8lie = id-hang*8-1return data[hang][lie]

 常量定义:constants.py

import random
import json
import tkinter as tk
from tkinter import ttk,messagebox
from PIL import Image, ImageTk
import pygame# music
pygame.init()
BGM = pygame.mixer.music.load(r'sounds\bgm.ogg')
button_music = pygame.mixer.Sound(r'sounds\buttonclick.ogg')
card_music = pygame.mixer.Sound(r'sounds\card.ogg')
success_music = pygame.mixer.Sound(r'sounds\success.ogg')
fail_music = pygame.mixer.Sound(r'sounds\fail.ogg')
worning_music = pygame.mixer.Sound(r'sounds\worning.ogg')game_name = "植物杂交实验室"
window_width = 880
window_height = 600hybridizationplants_data_path = r"data\hybridizationPlants.json"
record_data_path = r"data\record.json"
"""
杂交规则:
1. 基础杂交方式
2. 加强杂交方式
3. 单株变异
4. 僵尸感染
5. 神秘结果
"""# common
icon_path = r"images\Screen\common\PVZ.ico"
loading_path = r"images\Screen\common\loading.gif"
back1_1_path = r"images\Screen\common\back1_1.png"
back1_2_path = r"images\Screen\common\back1_2.png"
close1_1_path = r"images\Screen\common\close1_1.png"
close1_2_path = r"images\Screen\common\close1_2.png"
back2_1_path = r"images\Screen\common\back2_1.png"
back2_2_path = r"images\Screen\common\back2_2.png"
close2_1_path = r"images\Screen\common\close2_1.png"
close2_2_path = r"images\Screen\common\close2_2.png"
emptydescribe_path= r"images\Screen\common\emptydescribe.png"# 游戏主界面
mainscreen_path = r"images\Screen\mainmenu\mainmenu.gif"
menubutton1_path = r"images\Screen\mainmenu\menubutton1.png"
menubutton2_path = r"images\Screen\mainmenu\menubutton2.png"# 杂交实验室
breedingScreen_path= r"images\Screen\breeding\BreedingScreen.png"
plantCatalogButton1_path = r"images\Screen\breeding\PlantCatalogButton1.png"
plantCatalogButton2_path = r"images\Screen\breeding\PlantCatalogButton2.png"
hybridCatalogButton1_path = r"images\Screen\breeding\HybridCatalogButton1.png"
hybridCatalogButton2_path = r"images\Screen\breeding\HybridCatalogButton2.png"
experimentButton1_path = r"images\Screen\breeding\ExperimentButton1.png"
experimentButton2_path = r"images\Screen\breeding\ExperimentButton2.png"
historyButton1_path = r"images\Screen\breeding\HistoryButton1.png"
historyButton2_path = r"images\Screen\breeding\HistoryButton2.png"
advice_background_path = r"images\Screen\breeding\adviceLabel.png"# 基础植物图鉴
basalcatalog_background_path = r"images\Screen\basalcatalog\background.png"
basal_describe_path = "images\\Plantsdescribe\\basalPlants\\"
basal_card_path = "images\\PlantsCard\\basalPlants\\"# 杂交植物图鉴
hybridCatalog_background_path = r"images\Screen\hybridcatalog\background.png"
ahead1_1_path = r"images\Screen\hybridcatalog\ahead1.png"
ahead1_2_path = r"images\Screen\hybridcatalog\ahead2.png"
next1_1_path = r"images\Screen\hybridcatalog\next1.png"
next1_2_path = r"images\Screen\hybridcatalog\next2.png"
init_card_path = "images\\Screen\\init_card\\"
hybrid_describe_path = "images\\Plantsdescribe\\hybridizationPlants\\"
hybrid_card_path = "images\\PlantsCard\\hybridizationPlants\\"# 更多信息
morebutton1_path = r"images\Screen\HybridCatalog\more1.png"
morebutton2_path = r"images\Screen\HybridCatalog\more2.png"
mor_background_path = r"images\Screen\more\background.png"
more_method_path = "images\\Screen\\more\\method"# 杂交实验
experiment_background_path = r"images\Screen\experiment\background.png"
start1_path = r"images\Screen\experiment\start1.png"
start2_path = r"images\Screen\experiment\start2.png"
clearButton1_path = r"images\Screen\experiment\clear_1.png"
clearButton2_path = r"images\Screen\experiment\clear_2.png"
emptycard_path = r"images\Screen\experiment\emptycard.png"
# 杂交结果
result_background_path= r"images\Screen\result\background.png"
result_back1_path = r"images\Screen\result\back1.png"
result_back2_path = r"images\Screen\result\back2.png"
result_path = "images\\Screen\\result\\result"
emptyresult_path = r"images\Screen\result\emptyresult.png"# 杂交历史记录
record_background_path = r"images\Screen\record\background.png"
ahead2_1_path = r"images\Screen\record\ahead_1.png"
ahead2_2_path = r"images\Screen\record\ahead_2.png"
next2_1_path = r"images\Screen\record\next_1.png"
next2_2_path = r"images\Screen\record\next_2.png"
method_path = "images\\Screen\\record\\method_"
emptymethod_path = r"images\Screen\record\emptymethod.png"

5. 总结

本篇内容主要对项目的整体框架进行介绍,包括主窗口初始化,加载界面和游戏主界面的实现,以及对定义的一些常用组件进行说明。

其实只需要掌握两部分内容:

  1. 基础组件和页面布局:图片加载、组件参数、布局方法和位置
  2. 主窗口与子窗口的关系:子窗口可以继承主窗口的属性和方法,并通过按钮点击事件实现子窗口之间的跳转

下期预告:基础植物图鉴、杂交植物图鉴、杂交植物更多信息三个页面的实现。

这篇关于10天速通Tkinter库——Day6:《植物杂交实验室》整体框架介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112432

相关文章

mybatis的整体架构

mybatis的整体架构分为三层: 1.基础支持层 该层包括:数据源模块、事务管理模块、缓存模块、Binding模块、反射模块、类型转换模块、日志模块、资源加载模块、解析器模块 2.核心处理层 该层包括:配置解析、参数映射、SQL解析、SQL执行、结果集映射、插件 3.接口层 该层包括:SqlSession 基础支持层 该层保护mybatis的基础模块,它们为核心处理层提供了良好的支撑。

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

图神经网络模型介绍(1)

我们将图神经网络分为基于谱域的模型和基于空域的模型,并按照发展顺序详解每个类别中的重要模型。 1.1基于谱域的图神经网络         谱域上的图卷积在图学习迈向深度学习的发展历程中起到了关键的作用。本节主要介绍三个具有代表性的谱域图神经网络:谱图卷积网络、切比雪夫网络和图卷积网络。 (1)谱图卷积网络 卷积定理:函数卷积的傅里叶变换是函数傅里叶变换的乘积,即F{f*g}

cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个?

跨平台系列 cross-plateform 跨平台应用程序-01-概览 cross-plateform 跨平台应用程序-02-有哪些主流技术栈? cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个? cross-plateform 跨平台应用程序-04-React Native 介绍 cross-plateform 跨平台应用程序-05-Flutte

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

数据治理框架-ISO数据治理标准

引言 "数据治理"并不是一个新的概念,国内外有很多组织专注于数据治理理论和实践的研究。目前国际上,主要的数据治理框架有ISO数据治理标准、GDI数据治理框架、DAMA数据治理管理框架等。 ISO数据治理标准 改标准阐述了数据治理的标准、基本原则和数据治理模型,是一套完整的数据治理方法论。 ISO/IEC 38505标准的数据治理方法论的核心内容如下: 数据治理的目标:促进组织高效、合理地

Mysql BLOB类型介绍

BLOB类型的字段用于存储二进制数据 在MySQL中,BLOB类型,包括:TinyBlob、Blob、MediumBlob、LongBlob,这几个类型之间的唯一区别是在存储的大小不同。 TinyBlob 最大 255 Blob 最大 65K MediumBlob 最大 16M LongBlob 最大 4G