10天速通Tkinter库——Day7:主菜单及图鉴

news/2024/9/18 12:26:29/ 标签: python, tkinter

本篇博客我将介绍Tkinter实践项目《植物杂交实验室》中的杂交实验室主菜单、基础植物图鉴、杂交植物图鉴、杂交植物更多信息四个页面的制作。

它们作为主窗口的子页面实例,除了继承主窗口的基础设置(如图标、标题、尺寸等等)、还可以使用主窗口的属性和方法(如数据变量self.hybridizationPlants、页面跳转方法switch_to_screen等等),以及在constants.py中的常量定义和tool.py中定义的通用组件。具体实现见博客10天速通Tkinter库——Day6:项目整体框架介绍

目录

1. 杂交实验室主界面

2. 基础植物图鉴

3. 杂交植物图鉴和更多信息界面

3.1 杂交植物图鉴

3.2 更多信息页面

4. 总结


1. 杂交实验室主界面

bcc94b0d241346318e654c0902732942.png

这个界面非常简单:背景图片 + 五个按钮 + 一个框

8cd2c64220fb4e74af59fb3c73a257b0.png

首先创建一个名为BreedingScreen的类,这个类继承自Tkinter的Frame类,并且使用create_background加载一张背景图片。

class BreedingScreen(tk.Frame):"""杂交实验室主菜单界面"""def __init__(self, parent):super().__init__(parent)self.breeding_background = create_background(self,breedingScreen_path)

 然后是五个按钮,直接使用create_button生成,并且定义点击事件函数,就是调用root.switch_to_screen方法:

        # 基础植物图鉴按钮self.base_catalog_button = create_button(self,dark_image_path=plantCatalogButton1_path,light_image_path=plantCatalogButton2_path,width=360,height=180,locate_x=81,locate_y=104,command=self.on_base_catalog_button_click)# 杂交植物图鉴按钮self.hybrid_catalog_button = create_button(self,dark_image_path=hybridCatalogButton1_path,light_image_path=hybridCatalogButton2_path,width=360,height=180,locate_x=460,locate_y=104,command=self.on_hybrid_catalog_button_click)# 杂交实验室按钮self.experiment_button = create_button(self,dark_image_path=experimentButton1_path,light_image_path=experimentButton2_path,width=360,height=180,locate_x=81,locate_y=293,command=self.on_experiment_button_click)# 杂交历记录按钮self.record_button = create_button(self,dark_image_path=historyButton1_path,light_image_path=historyButton2_path,width=360,height=180,locate_x=450,locate_y=293,command=self.on_record_button_click)# 杂交建议显示器self.advice_text()# 关闭界面self.close_button = close_button(self,close1_1_path,close1_2_path)self.pack()def on_base_catalog_button_click(self):# 点击基础植物图鉴按钮的事件处理self.master.switch_to_screen('plant_catalog_screen')def on_hybrid_catalog_button_click(self):# 点击杂交植物图鉴按钮的事件处理self.master.children['hybrid_catalog_screen'].card_button_matrix(page=0)self.master.switch_to_screen('hybrid_catalog_screen')def on_experiment_button_click(self):# 点击杂交实验按钮的事件处理self.master.switch_to_screen('experiment_screen')def on_record_button_click(self):# 点击杂交记录按钮的事件处理self.master.children['record_screen'].all_record(page=0)self.master.switch_to_screen('record_screen')

最后需要单独实现的是循环建议框,这个框的构成有一点点复杂。因为我没有发现任何一种组件可以单独实现“背景+文字+无边框”,也可能我略有一点强迫症。于是我选择使用label加载背景,使用button显示文字,尽可能组合起来不违和。

    def advice_text(self):image = Image.open(advice_background_path)# 将图片转换为Tkinter可以使用的格式image = image.resize((663, 89), Image.Resampling.LANCZOS)photo = ImageTk.PhotoImage(image)background_label = tk.Label(self, image=photo,bd=0)background_label.place(x=106,y=470)self.photo = photosuggestions = ["你可以尝试不同的杂交方式", "也许使用不同类型的植物效果会更好!", "当亲本植物超过四种,会发生糟糕的事!", "如果没有想法,就去看看历史记录吧!", "你需要避免完全相反的属性,比如冰与火"]random_index = random.randint(0, len(suggestions)-1)suggestion = suggestions[random_index]button = tk.Button(self,text=suggestion,font=("Times New Roman", 19, "bold"),fg="gold",width=39,height=1,bd=0,background="saddlebrown",command=None,activebackground="saddlebrown")button.place(x=145,y=492)self.after(60000,self.advice_text)
  1. suggestions列表包含了五条建议文本。
  2. random.randint(0, len(suggestions)-1):生成一个随机数,作为suggestions列表的索引。
  3. suggestion = suggestions[random_index]:根据随机索引选择一条建议。
  4. 创建一个Tkinter的Button组件,用于显示建议文本。这里设置了按钮的字体、颜色、大小、背景色等属性。
  5. button.place(x=145,y=492):将按钮放置在窗口的指定位置。
  6. self.after(60000, self.advice_text):设置一个定时器,60000毫秒(即一分钟)后再次调用advice_text方法。

2. 基础植物图鉴

0d597889ff4e4419816980c48fc471f1.gif

 这个界面看似内容很少,但是,按钮矩阵的实现还是稍微带点难度。

181d88c06b5d4087b103b456d1400080.png

 创建一个名为PlantCatalogScreen的类,这个类继承自Tkinter的Frame类。

class PlantCatalogScreen(tk.Frame):"""基础植物图鉴1. 卡片矩阵2. 植物说明"""def __init__(self, parent):super().__init__(parent)self.breeding_background = create_background(self,basalcatalog_background_path)self.close_button = close_button(self,close2_1_path,close2_2_path,clear=94)self.back_button = back_button(self,back2_1_path,back2_2_path,clear=94)self.empty_describe = empty_describe(self)

类的初始化:

  1. create_background:加载一张背景图片。
  2. close_button:创建了一个关闭按钮。
  3. back_button:创建了一个返回按钮。
  4. empty_describe:创建了一个空白描述区域,用于在没有具体植物信息时显示。
    def card_button_matrix(self):"""创建基础植物卡片矩阵"""card_frame = tk.Frame(self)card_frame.place(x=28,y=88)for row in range(6):for col in range(8):def on_click(row, col):card_music.play()"""卡片点击事件, 展示植物说明"""label = tk.Label(self, image=self.master.basal_plant_describe[row][col], bd=0)label.place(x=530, y=94)                button = tk.Button(card_frame, image=self.master.basal_plant_card[row][col])button.config(borderwidth=0,highlightthickness=0)button.grid(row=row, column=col,sticky="NSEW")button.bind('<Button-1>', lambda event, r=row, c=col: on_click(r, c))
  1. card_button_matrix 方法:这个方法用于创建植物卡片矩阵。

    • card_frame:创建了一个新框架用于放置卡片按钮。

    • 使用 grid 布局管理器来放置卡片按钮,每行有8个按钮,共6行。

    • 对于每个卡片按钮,定义了一个点击事件处理器 on_click。当卡片被点击时:

      • 播放音效(card_music.play())。
      • 显示植物的详细说明。这通过创建一个新的标签(tk.Label)并设置其图像(self.master.basal_plant_describe[row][col])来实现。
  2. 卡片按钮的创建:每个卡片按钮都是一个 tk.Button 实例,它使用了原始卡片图片,并设置了边框宽度和高亮厚度为0,以使按钮看起来更简洁。

    • 每个按钮都绑定了一个点击事件处理器 on_click,处理器接收行和列作为参数,并在按钮被点击时调用。
  3. 卡片和描述的图片是主界面初始化时加载的,使用self.master.basal_plant_describe和self.master.basal_plant_card进行调用。

3. 杂交植物图鉴和更多信息界面

05d59a22a1d9438fa919cbf21428aa8b.gif

3.1 杂交植物图鉴

这个界面复杂的点在于:

  1. 杂交植物数据是动态的
  2. 上下页需要切换

c2502b8f80c34709b1691de820aaa176.png

先来看看杂交植物json数据:

    {"id": 1,"parent_base_plant_ids": [ 1, 2 ],"hybridization_method": 1,"new_hybrid": false}

 字段分别是植物id,亲本植物id列表,获得的杂交方法,以及是否为新植物。而图鉴界面只加载new_hybrid值为false的植物,亲本植物id列表和杂交方法会传给更多信息页面。

class HybridCatalogScreen(tk.Frame):"""基础植物图鉴1. 卡片矩阵(翻页功能, 包含两个页面)2. 植物说明3. 更多信息"""def __init__(self, parent):super().__init__(parent)self.breeding_background = create_background(self,hybridCatalog_background_path)self.close_button = close_button(self,close2_1_path,close2_2_path,clear=82)self.back_button = back_button(self,back2_1_path,back2_2_path,clear=82)        self.empty_describe = empty_describe(self,Y=82)

 同样的,创建一个杂交植物图鉴类,包括对父类的tk.Frame的继承、加载一张背景图片,一个关闭按钮、一个返回按钮以及一张空白描述图片。

        self.ahead_buttton = create_button(self,dark_image_path=ahead1_1_path,light_image_path=ahead1_2_path,width=110,height=27,locate_x=265,locate_y=566,command=self.on_ahead_button_click)self.next_buttton = create_button(self,dark_image_path=next1_1_path,light_image_path=next1_2_path,width=110,height=27,locate_x=377,locate_y=566,command=self.on_next_button_click)

这是上一页和下一页按钮的创建,点击事件定义如下:

    def on_ahead_button_click(self):"""上一页按钮点击事件"""if self.page==1:self.page_change = Trueself.page=0self.card_button_matrix(page=self.page)self.empty_describe = empty_describe(self,Y=82)self.pack()self.page_change = Falsedef on_next_button_click(self):"""下一页按钮点击事件"""if self.page==0 and self.plants_num>48:self.page_change = Trueself.page=1self.card_button_matrix(page=self.page)self.empty_describe = empty_describe(self,Y=82)self.pack()self.page_change = False

on_ahead_button_click 方法

  • 功能: 当用户点击“上一页”按钮时,此方法被调用。它检查当前页面是否为第一页(self.page==1),如果是,则更新页面状态和执行以下操作:
    • 设置 page_change 标记为 True,用于后续方法或逻辑中,以识别页面是否已改变。
    • 将页面设置为第0页(self.page=0),这意味着回到卡片矩阵的第一页。
    • 调用 card_button_matrix 方法,参数为当前页面和初始化标志(page=self.page, init=1),用于重新生成或更新卡片矩阵的布局。
    • 更新空描述区域(self.empty_describe = empty_describe(self,Y=82)),用于显示或更新页面空闲区域的内容。
    • 调用 pack 方法,重新布局并显示界面元素。

on_next_button_click 方法

  • 功能: 当用户点击“下一页”按钮时,此方法被调用。它检查当前页面是否为最后一页(self.page==0)且总植物数量大于48(超过一页),如果是,则更新页面状态和执行以下操作:
    • 设置 page_change 标记为 True
    • 将页面设置为第1页(self.page=1),这意味着显示卡片矩阵的第二页。
    • 同样,调用 card_button_matrix 方法,参数为当前页面和初始化标志(page=self.page, init=1)。
    • 更新空描述区域(self.empty_describe = empty_describe(self,Y=82))。
    • 调用 pack 方法,重新布局并显示界面元素。
        self.init_card_photo = [[None for _ in range(8)] for _ in range(6)] # 卡片矩阵背景self.old_hybrid_plant = [[0 for _ in range(8)] for _ in range(12)]  # 杂交前可展示植物idself.new_hybrid_plant = [[0 for _ in range(8)] for _ in range(12)]  # 杂交后可展示植物id# 卡片矩阵初始化self.plants_num = 0self.page = 0self.page_change = Falseself.card_frame = tk.Frame(self,bd=0)self.card_frame.place(x=28,y=89)self.init_card_matrix()self.card_button_matrix(page=0,init=1)# 记录植物亲本及杂交方法信息self.method = 0self.basal_plant_ids = [0,0,0,0]self.pack()
  1.  self.init_card_photo:这个属性用于初始化矩阵按钮背景,因为定义矩阵Frame时,有时按钮会有空缺,于是乎就使用对应位置的背景填充
  2. self.old_hybrid_plant和self.new_hybrid_plant都用于记录需要显示的植物ID。因为由于杂交实验会更新杂交植物数据,因此用来判断哪些位置更新了,只改变更新位置,减少页面刷新时的多于操作。
  3. self.plants_num记录解锁的杂交植物数量
  4. self.page用来记录页号,有0,1两页
  5. self.page_change判断页面是否切换,True和False两个值

接着是加载初始按钮矩阵背景和按钮矩阵的实现

    def init_card_matrix(self):"""加载卡片矩阵空白背景"""for row in range(6):for col in range(8):self.init_card_photo[row][col]= image_load(57,78,init_card_path,col+1+row*8,".jpg")  def data_load(self,hybridizationplants):"""加载展示杂交植物卡片"""self.plants_num=0; row = 0; col = 0for plant in hybridizationplants:if plant.get('new_hybrid')==False: self.plants_num += 1self.new_hybrid_plant[row][col] = plant.get("id")         col += 1if col==8:row += 1col = 0
  1. init_card_matrix函数加载48张按钮背景图片
  2. data_load用于获取最新的杂交植物信息
    def card_button_matrix(self,page=0,init=0):"""创建杂交植物卡片矩阵1. 保存上一次卡片数据2. 加载最新卡片数据3. 只改变更新部分的按钮图片4. 使用self.page加载不同页面的数据"""if init==0: for row in range(12):for col in range(8):self.old_hybrid_plant[row][col] = self.new_hybrid_plant[row][col]self.data_load(self.master.hybridizationPlants)for row in range(6):for col in range(8):if self.new_hybrid_plant[row+page*6][col]!=self.old_hybrid_plant[row+page*6][col] or \(self.page_change==True and self.new_hybrid_plant[row+page*6][col]!=0): card_photo = id_to_photo(self.new_hybrid_plant[row+page*6][col],self.master.hybrid_plant_card)button = tk.Button(self.card_frame, image=card_photo)button.config(borderwidth=0,highlightthickness=0)button.grid(row=row, column=col,sticky="NSEW")def on_click(row, col):card_music.play()describe_photo = id_to_photo(self.new_hybrid_plant[row+page*6][col],self.master.hybrid_plant_describe)label = tk.Label(self, image=describe_photo, bd=0)label.place(x=530, y=82)id = self.new_hybrid_plant[row+page*6][col]self.basal_plant_ids = self.master.hybridizationPlants[id-1].get("parent_base_plant_ids")self.method = self.master.hybridizationPlants[id-1].get("hybridization_method")button.bind('<Button-1>', lambda event, r=row, c=col: on_click(r, c))elif self.new_hybrid_plant[row+page*6][col]==0 :label = tk.Label(self.card_frame,image=self.init_card_photo[row][col],bd=0)label.grid(row=row, column=col,sticky="NSEW")

card_button_matrix用于创建卡片按钮矩阵,对其进行详解

  • 这个方法接受两个参数:page 和 initpage 用于指定加载哪个页面的数据,init 用于指定是否是初始化操作,初始化只有主界面初始化时用到一次。
  • 如果 init 参数为0,表示不是初始化操作,则将 self.new_hybrid_plant 的数据保存到 self.old_hybrid_plant 中,以便后续比较。
  • 调用 self.data_load 方法来加载最新的杂交植物数据。
  • 创建按钮和布局:
    • 遍历卡片矩阵的每一行和每一列。
    • 如果 self.new_hybrid_plant 中的数据与 self.old_hybrid_plant 不同,或者页面有变化且卡片不为空,则创建一个新的按钮。
    • 使用 id_to_photo 函数将植物ID转换为对应的图片,并设置按钮的图片。
    • 配置按钮无边框和边框厚度。
    • 使用 grid 方法将按钮放置在卡片框架中,并设置粘性(sticky)属性。
  • 绑定点击事件:
    • 定义了一个 on_click 函数,当按钮被点击时触发。
    • 播放音效card_music.play()
    • 获取描述图片并显示。
    • 获取植物ID,并更新亲本植物ID列表和杂交方法。
    • 将 on_click 函数绑定到按钮的鼠标左键点击事件。
  • 显示空白卡片:
    • 如果 self.new_hybrid_plant 中对应的单元格为0,表示没有植物数据,则显示一个初始卡片图片。

这个函数应该是本项目中最难的一个,重构了好几次,最终还挺满意。

        self.more_button = create_button(self,dark_image_path=morebutton1_path,light_image_path=morebutton2_path,width=138,height=40,locate_x=603,locate_y=542,command=self.on_more_button_click)     

 最后就是这个更多信息按钮,以及点击事件处理函数。

def on_more_button_click(self):"""查看更多信息按钮点击事件"""if self.method!=0 and self.basal_plant_ids[0]!=0:self.master.children['more_information_screen'].information_show(self.method,self.basal_plant_ids)self.master.switch_to_screen('more_information_screen') self.method=0self.basal_plant_ids = [0,0,0,0]     
  • 这段代码首先检查 self.method 和 self.basal_plant_ids 是否有有效的值。self.method 应该是杂交方法的信息,而 self.basal_plant_ids 是一个包含亲本植物ID的列表。
  • 如果这两个值都不为0(即有效),则调用 self.master.children['more_information_screen'].information_show(self.method,self.basal_plant_ids) 方法来展示更多信息,并将界面切换到 more_information_screen
  • self.master 指的是创建这个 MoreInformation 实例的窗口的主窗口实例。self.master.children 是一个字典,其中包含了主窗口中所有子窗口的引用。
  • information_show 方法是 MoreInformation 类中的一个方法,用于展示杂交方法和亲本植物信息。
  • 重置变量:
    • 在检查和可能的屏幕切换之后,代码将 self.method 设置为0,并将 self.basal_plant_ids 重置为一个包含四个0的列表。
    • 这一步的目的是为了清除之前的信息,以便在用户再次点击“查看更多信息”按钮时,可以显示新的信息。

3.2 更多信息页面

这个页面很简单,组件如下:

baa6f855fb0644e4aaf86276828559cc.png

初始化和上述页面差不多,加载背景图片,创建返回按钮和空的描述信息图片,返回按钮的点击事件是返回杂交植物图鉴。

class MoreInformation(tk.Frame):"""杂交植物更多信息界面,包括杂交方法和亲本植物说明"""def __init__(self, parent):super().__init__(parent)self.more_background = create_background(self,mor_background_path)self.back_button = create_button(self,dark_image_path=back1_1_path,light_image_path=back1_2_path,width=85,height=25,locate_x=24,locate_y=567,command=self.on_back_button_click)self.empty_information = self.empty_information_load()self.pack()def empty_information_load(self):"""加载空的描述卡片"""image = Image.open(emptydescribe_path)image = image.resize((212, 308), Image.Resampling.LANCZOS)photo = ImageTk.PhotoImage(image)return photo  def on_back_button_click(self):# 返回杂交植物图鉴界面self.master.switch_to_screen('hybrid_catalog_screen')

唯一重点就是下面这个信息展示方法:

    def information_show(self,method,basal_plant_ids):"""展示杂交方法"""self.method = image_load(560,120,more_method_path,method,".png")label = tk.Label(self,image=self.method,bd=0)label.place(x=160,y=82)"""展示亲本植物信息"""self.basal_plant_describe = [None for _ in range(4)]self.card_frame = tk.Frame(self,bd=0)self.card_frame.place(x=15,y=202)for col in range(4):if col<len(basal_plant_ids) and basal_plant_ids[col]!=0:self.basal_plant_describe[col] = image_load(212,308,basal_describe_path,basal_plant_ids[col],'.png')label = tk.Label(self.card_frame,image=self.basal_plant_describe[col] ,bd=0)label.grid(row=0, column=col,sticky="NSEW")else:label = tk.Label(self.card_frame,image=self.empty_information,bd=0)label.grid(row=0, column=col,sticky="NSEW")  

第一部分:展示杂交方法

  1. 加载方法图片:使用image_load函数加载一个名为method的图片,图片的大小为560x120像素,图片路径为more_method_path,图片格式为.png。加载后的图片被存储在self.method变量中。
  2. 显示图片:创建一个tk.Label对象,将加载的图片显示在界面上。图片放置在坐标(160, 82)的位置。

第二部分:展示亲本植物信息

  1. 初始化亲本植物描述列表:创建一个长度为4的列表self.basal_plant_describe,用于存储每个亲本植物的描述图片。
  2. 创建卡片框架:在界面上创建一个tk.Frame,用于放置亲本植物的描述图片。这个框架位于坐标(15, 202)。
  3. 循环遍历亲本植物ID:通过一个循环遍历basal_plant_ids列表中的每个亲本植物ID。对于每个ID:
    1. 检查ID有效性:如果ID在列表中有效(即在列表的范围内且不为0),则加载对应的亲本植物描述图片。
    2. 加载图片:使用image_load函数加载一个名为basal_plant_ids[col]的图片,图片的大小为212x308像素,图片路径为basal_describe_path。加载后的图片被存储在self.basal_plant_describe[col]中。
    3. 显示图片:创建一个tk.Label对象,将加载的图片显示在卡片框架中。图片放置在网格布局的第0行和第col列上。
    4. 处理无效ID:如果ID无效,则加载一个名为self.empty_information的图片,表示没有可用的亲本植物信息。
  4. 网格布局管理:使用grid方法将图片放置在卡片框架中,sticky="NSEW"表示图片会填充其网格单元格的全部空间。

4. 总结

到这里,我们就实现了杂交实验室主界面、基础植物图鉴和杂交植物图鉴,以及更多信息页面。

简单的关闭和返回按钮我们可以直接使用tool.py中定义的方法,至于较难的卡片按钮矩阵,我们定义了Frame,然后双循环遍历杂交植物数据,创建按钮并绑定点击事件,并且对于杂交植物图鉴,还实现了上下页面跳转的功能,并且对页面更新也做了处理,消除了一开始的白屏卡顿。

下期预告:杂交实验、杂交历史记录页面的实现。

感谢大家支持!

 


http://www.ppmy.cn/news/1516398.html

相关文章

使用C++开发黑神话悟空类似3A如何避免内存泄漏

智能指针&#xff1a;使用C11或更高版本中的智能指针&#xff08;如std::unique_ptr、std::shared_ptr和std::weak_ptr&#xff09;来自动管理内存。这些智能指针在超出作用域时会自动释放它们所管理的内存。 RAII&#xff08;Resource Acquisition Is Initialization&#xf…

Java开发程序员职业发展路径

入行阶段&#xff1a;后端 3年 目标 在这一阶段&#xff0c;你将专注于后端开发&#xff0c;特别是Java编程语言及其相关技术栈。 主要任务和技能 掌握Java基础: 理解Java语言的核心概念&#xff0c;如OOP&#xff08;面向对象编程&#xff09;、数据结构、算法等。学习后端…

【Rust练习】10.元组

练习题来自&#xff1a;https://practice-zh.course.rs/compound-types/tuple.html 1 元组中的元素可以是不同的类型。元组的类型签名是 (T1, T2, …), 这里 T1, T2 是相对应的元组成员的类型. fn main() {let _t0: (u8,i16) (0, -1);// 元组的成员还可以是一个元组let _t1:…

相关性分析

斯皮尔曼、皮尔逊、肯德尔、点双列相关分析、偏相关分析、距离相关分析、双变量回归分析和互信息。 特性斯皮尔曼相关分析&#xff08;Spearman Correlation&#xff09;皮尔逊相关分析&#xff08;Pearson Correlation&#xff09;肯德尔相关分析&#xff08;Kendall’s Tau&…

华为OD题目 csv格式的数据 字符串 用C没写出来

这题对于嵌入式mcu的人来说&#xff0c;太难为了。不想解了&#xff0c;烂摆。有心情再说把。 将一个csv格式的数据文件中包含有单元格引用的内容替换为对应单元格内容的实际值。 Comma seprated values&#xff08;CSV&#xff09;逗号分隔值&#xff0c;csv格式的数据文件使用…

nodemon学习(一)简介、安装、配置、使用

nodemon用来监视node.js应用程序中的任何更改并自动重启服务,非常适合用在开发环境中。以前&#xff0c;我们开发一个node后端服务时&#xff0c;每次更改文件&#xff0c;均需重启一下&#xff0c;服务才能生效。这使我们的开发效率降低了很多。nodemon的出现&#xff0c;可以…

Catf1ag CTF Crypto(六)

前言 Catf1agCTF 是一个面向所有CTF&#xff08;Capture The Flag&#xff09;爱好者的综合训练平台&#xff0c;尤其适合新手学习和提升技能 。该平台由catf1ag团队打造&#xff0c;拥有超过200个原创题目&#xff0c;题目设计注重知识点的掌握&#xff0c;旨在帮助新手掌握C…

ffmpeg.exe命令行常见应用

基本转换&#xff1a; ffmpeg -i input.mp4 output.avi将input.mp4文件转换为output.avi文件。 提取音频&#xff1a; ffmpeg -i input.mp4 -vn output.mp3从input.mp4文件中提取音频并保存为output.mp3文件。 视频剪辑&#xff1a; ffmpeg -i input.mp4 -ss 00:00:30 -t 00:…

深入探讨Java多线程

我的主页&#xff1a;2的n次方_ 1. 多线程的概念 多线程是指在同一个程序中同时执行多个线程的技术。线程是操作系统能够独立调度和执行的最小单位。在Java中&#xff0c;线程由Thread类来表示&#xff0c;所有的线程都是通过这个类或其子类来创建和控制的。通过合理的多线…

codetop标签动态规划大全C++讲解(上)!!动态规划刷穿地心!!学吐了家人们o(╥﹏╥)o

主要供自己回顾学习&#xff0c;会持续更新&#xff0c;题源codetop动态规划近半年 1.零钱兑换2.零钱兑换II3.面试题08.11.硬币4.单词拆分5.最长递增子序列6.最长递增子序列的个数7.得到山形数组的最少删除次数8.最长公共子序列9.最长重复子数组10.最长等差数列11.最大子数组和…

Docker数据卷使用手册

目录 目标 前言 概念 官方文档 匿名卷&#xff08;Anonymous Volumes&#xff09; 简介 案例 命名卷&#xff08;Named Volumes&#xff09; 简介 案例 目标 掌握Volume命令通过演示案例&#xff0c;理解数据卷种类与各自的用途。 前言 我们在很多网上教程上可以看到…

前端宝典十:webpack性能优化最佳实践

Webpack 内置了很多功能。 通常你可用如下经验去判断如何配置 Webpack&#xff1a; 想让源文件加入到构建流程中去被 Webpack 控制&#xff0c;配置 entry&#xff1b;想自定义输出文件的位置和名称&#xff0c;配置 output&#xff1b;想自定义寻找依赖模块时的策略&#xff…

云计算day31

⼀、Docker 1、Docker介绍.pdf 1、Docker 是什么&#xff1f; Docker 是⼀个开源的应⽤容器引擎&#xff0c;可以实现虚拟化&#xff0c;完全采⽤“沙 盒”机制&#xff0c;容器之间不会存在任何接⼝。 Docker 通过 Linux Container&#xff08;容器&#xff09;技术将任意…

如何在Docker中部署Eureka Server:容器化微服务注册中心

在现代微服务架构中&#xff0c;服务注册和发现是至关重要的。Eureka Server 是一个由 Netflix 开发的开源服务注册和发现工具&#xff0c;它允许微服务实例在运行时动态地注册和查询其他服务。将 Eureka Server 部署在 Docker 中可以提高其可移植性和可维护性&#xff0c;同时…

Django 后端架构开发:手机与邮箱验证码接入、腾讯云短信SDK和网易邮箱

Django 后端架构开发&#xff1a;手机与邮箱验证码接入、腾讯云短信SDK和网易邮箱接入 &#x1f31f; 手机短信与邮箱短信验证码的应用场景 在现代应用中&#xff0c;短信和邮箱验证码是用户验证和安全管理的关键组成部分。它们广泛应用于注册、登录、找回密码等场景&#xf…

elasticsearch -- RestClient操作文档

RestClient操作文档 为了与索引库操作分离&#xff0c;我们再次参加一个测试类&#xff0c;做两件事情&#xff1a; 初始化RestHighLevelClient我们的酒店数据在数据库&#xff0c;需要利用IHotelService去查询&#xff0c;所以注入这个接口 package cn.itcast.hotel;import…

机器学习:opencv图像识别--图片专项

目录 前言 一、读取图片 1.安装opencv库 2.读取彩色图片 3.读取灰度图 二、RGB 1.RGB的概念 2.颜色通道&#xff1a; 3.图像表示 4.代码实现单通道图像 三、ROI 1.代码实现 四、图片打码 五、图片组合 六、图片缩放 总结 前言 OpenCV&#xff08;Open Source C…

Nginx 丢弃指定响应头

如果想丢弃服务器响应回来的某个头&#xff0c;可以使用Nginx进行代理该服务器&#xff0c;再进行配置 Nginx中丢弃指定响应头 Nginx 中拦截某个响应并丢弃特定的响应头&#xff0c;可以使用 proxy_hide_header 指令。 修改 Nginx 配置 在您的 Nginx 配置文件中&#xff08…

WPF—DispatcherTimer定时器

WPF—DispatcherTimer定时器 WPF界面是没有timer控件的,Winform有。但是我们可以使用DispatcherTimer来实现定时器。 在WPF应用程序中&#xff0c;DispatcherTimer是一种常用的计时器工具&#xff0c;它可以在指定的时间间隔触发事件。以下是一个简单的使用DispatcherTimer的…

SpringBoot项目如何使用和打包本地第三方jar包

有时候我们引用了maven仓库不存在的第三方jar&#xff0c;项目打包后jar包里没有引用的jar&#xff0c;解决方法往下看。 一、目录介绍 SpringBoot项目通过idea打成jar包部署。 将项目打成jar包后&#xff0c;所有引用的jar都存在于BOOT-INF\lib下&#xff1a; 如果存在本地…