基於Python制作一個相冊播放器

大傢好,我是小F。

對於相冊播放器,大傢應該都不陌生(用於瀏覽多張圖片的一個應用)。

當然還有視頻、音樂播放器,同樣是用來播放多個視頻、音樂文件的。

在Win10系統下,用【照片】這個應用打開一張圖片,就可以瀏覽該圖片所在文件夾中其它圖片瞭。

從上面的圖中發現,還有不少其它方面的功能,比如圖片裁剪、編輯、打印等。

今天小F就帶大傢學習一個Python制作相冊播放器的實戰項目。

功能嘛,當然沒有系統自帶的好,僅做學習哈。

默認5秒切換一張圖片,點擊向前按鈕,可以快速切換到下一張圖片。

主要使用到Pygame這個庫,創建一個圖形界面。

還有Tkinter庫,因為要添加一個圖片文件夾,使用tkinter的filedialog快速選取本地文件夾。

# 安裝
pip install pygame
pip install tkinter

好瞭,接下來就給大傢介紹一下。

導入相關庫

import os
import sys
import glob
import pygame
import tkinter
import os.path
from button import Button
from tkinter import filedialog

初始化,設置圖形界面的寬為1600,高為900。

添加標題欄圖表和標題欄文字,以及中文字體,這裡用宋體,所以界面顯得有些醜…

最後設置文字背景色和背景圖片

# 初始化
pygame.init()

# 設置寬, 高, 標題欄
WIDTH, HEIGHT = 1600, 900
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("相冊播放器 | 小F 2022")


# 添加中文字體
def bold_font(size):
    os.chdir(sys.path[0])
    return pygame.font.Font("assets/simhei.ttf", size)


def regular_font(size):
    return pygame.font.SysFont("simhei", size)

# 設置文字背景色, 背景圖片
BASE_TEXT_COLOR = "#6fffe9"
BACKGROUND_IMAGE = pygame.image.load("assets/background.png")
SCREEN.blit(BACKGROUND_IMAGE, (0, 0))
# 更新
pygame.display.update()

# 設置標題欄圖標
WINDOW_ICON = pygame.image.load("assets/window_icon.png")
pygame.display.set_icon(WINDOW_ICON)

效果如下,空空蕩蕩。

加載部分按鈕的圖標

# 設置按鈕背景色, 向後按鈕, 暫停按鈕, 播放按鈕, 向前按鈕, 加載新相冊按鈕
MAIN_MENU_BUTTON_BACKGROUND = pygame.image.load("assets/main_menu_button_bg.png")
REWIND_ICON_SURFACE = pygame.image.load("assets/rewind_icon.png")
PAUSE_ICON_SURFACE = pygame.image.load("assets/pause_icon.png")
PLAY_ICON_SURFACE = pygame.image.load("assets/play_icon.png")
SEEK_ICON_SURFACE = pygame.image.load("assets/seek_icon.png")
LOAD_NEW_ALBUM_SURFACE = pygame.image.load("assets/load_new_album_icon.png")

設置按鈕背景色,向後按鈕,暫停按鈕,播放按鈕,向前按鈕,加載新相冊按鈕。

其次定義各個按鈕的功能函數

# 加載按鈕函數
def load_button():
    # 打開文件管理器, 選擇文件夾
    filedialogwindow = tkinter.Tk()
    filedialogwindow.withdraw()
    filepath = filedialog.askdirectory(title="選擇你的相冊")
    filedialogwindow.destroy()
    album_player(filepath)


# 關閉按鈕
def quit_button():
    pygame.quit()
    sys.exit()


# 向後按鈕
def rewind_button(current_image_index):
    if current_image_index > 0:
        current_image_index -= 1
    rewind_button_pressed = True
    return rewind_button_pressed, current_image_index


# 向前按鈕
def seek_button(current_image_index, image_names):
    if current_image_index+1 < len(image_names):
        current_image_index += 1
    seek_button_pressed = True
    return seek_button_pressed, current_image_index


# 播放按鈕
def play_button():
    paused = False
    unpaused = True
    return paused, unpaused


# 暫停按鈕
def pause_button():
    paused = True
    unpaused = False
    return paused, unpaused

加載按鈕,添加相冊;

關閉按鈕,退出播放器;

向後按鈕,向後切換一張圖片;

向前按鈕,向前切換一張圖片;

播放按鈕,開始播放相冊中的圖片;

暫停按鈕,暫停相冊圖片的播放;

設置主界面,包含主頁標題欄,加載按鈕,關閉按鈕文字屬性。

同時還需要監聽鼠標點擊事件

# 主界面
def main_menu():
    # 主頁標題欄
    TITLE_TEXT_SURFACE = bold_font(120).render("相冊播放器", True, BASE_TEXT_COLOR)
    TITLE_TEXT_RECT = TITLE_TEXT_SURFACE.get_rect(center=(WIDTH/2, 175))
    SCREEN.blit(TITLE_TEXT_SURFACE, TITLE_TEXT_RECT)
    # 加載按鈕
    LOAD_BUTTON = Button(
        surface=MAIN_MENU_BUTTON_BACKGROUND, pos=(WIDTH/2, 415), text_input="加載",
        font=bold_font(100), base_color=BASE_TEXT_COLOR, hovering_color="white"
    )
    # 關閉按鈕
    QUIT_BUTTON = Button(
        surface=MAIN_MENU_BUTTON_BACKGROUND, pos=(WIDTH/2, 585), text_input="關閉",
        font=bold_font(100), base_color=BASE_TEXT_COLOR, hovering_color="white"
    )
    while True:
        # 監聽鼠標點擊事件
        current_mouse_pos = pygame.mouse.get_pos()
        LOAD_BUTTON.update(SCREEN)
        QUIT_BUTTON.update(SCREEN)
        # 根據鼠標點擊情況, 是否點擊右上角的關閉
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            # 根據鼠標點擊情況, 點擊加載或關閉按鈕
            if event.type == pygame.MOUSEBUTTONDOWN:
                if LOAD_BUTTON.check_for_input(current_mouse_pos):
                    load_button()
                if QUIT_BUTTON.check_for_input(current_mouse_pos):
                    quit_button()

        # 當鼠標放置在按鈕上, 按鈕顏色發生改變
        LOAD_BUTTON.change_color(current_mouse_pos)
        QUIT_BUTTON.change_color(current_mouse_pos)
        pygame.display.update()

根據鼠標點擊情況, 是否點擊右上角的關閉;

根據鼠標點擊情況, 點擊加載或關閉按鈕;

當鼠標放置在按鈕上, 按鈕顏色發生改變,變成白色。點擊關閉,應用會關閉掉。

最後是相冊播放器的功能函數,設置每5s切換一張圖片。

此外還要調整圖片的尺寸大小,方便在播放器中查看

# 相冊播放器功能函數
def album_player(folder_path):
    SCREEN.blit(BACKGROUND_IMAGE, (0, 0))

    image_file_paths = []
    image_names = []
    current_image_index = 0
    paused = False
    unpaused = False
    seek_button_pressed = False
    rewind_button_pressed = False

    # 添加加載按鈕後, 得到的圖片文件夾路徑
    os.chdir(folder_path)
    for file in glob.glob("*"):
        current_image_path = f"{folder_path}/{file}"
        # 圖片路徑列表
        image_file_paths.append(current_image_path)
        # 圖片名稱列表
        image_names.append(file)

    # 向後按鈕
    REWIND_BUTTON = Button(
        surface=REWIND_ICON_SURFACE, pos=(WIDTH/2-100, HEIGHT-150), text_input="",
        font=bold_font(100), base_color=BASE_TEXT_COLOR, hovering_color="white"
    )
    # 暫停按鈕
    PAUSE_BUTTON = Button(
        surface=PAUSE_ICON_SURFACE, pos=(WIDTH/2, HEIGHT-150), text_input="",
        font=bold_font(100), base_color=BASE_TEXT_COLOR, hovering_color="white"
    )
    # 播放按鈕
    PLAY_BUTTON = Button(
        surface=PLAY_ICON_SURFACE, pos=(WIDTH/2, HEIGHT-150), text_input="",
        font=bold_font(100), base_color=BASE_TEXT_COLOR, hovering_color="white"
    )
    # 向前按鈕
    SEEK_BUTTON = Button(
        surface=SEEK_ICON_SURFACE, pos=(WIDTH/2+100, HEIGHT-150), text_input="",
        font=bold_font(100), base_color=BASE_TEXT_COLOR, hovering_color="white"
    )
    # 加載新相冊按鈕
    LOAD_NEW_ALBUM_BUTTON = Button(
        surface=LOAD_NEW_ALBUM_SURFACE, pos=(WIDTH-325, HEIGHT-150), text_input="",
        font=bold_font(100), base_color=BASE_TEXT_COLOR, hovering_color="white"
    )

    # 獲取時間, 設置每5s切換一張圖片
    previous_time = pygame.time.get_ticks()
    COOLDOWN = 5000

    # 設置圖片名稱文字屬性
    photo_title_text_surface = bold_font(90).render(image_names[current_image_index], True, BASE_TEXT_COLOR)
    photo_title_text_rect = photo_title_text_surface.get_rect(center=(WIDTH/2, 150))

    # 圖片張圖顯示
    image_count_text_surface = regular_font(80).render(f"圖片 {current_image_index+1}/{len(image_names)}", True, BASE_TEXT_COLOR)
    image_count_text_rect = image_count_text_surface.get_rect(center=(300, 755))

    # 獲取圖片寬高屬性, 窗口顯示不合適, 調整大小
    new_image_surface = pygame.image.load(image_file_paths[current_image_index])
    if new_image_surface.get_height() > 500:
        new_image_surface = pygame.transform.scale(new_image_surface, (new_image_surface.get_width() * (500/new_image_surface.get_height()), 500))
    elif new_image_surface.get_width() > 800:
        new_image_surface = pygame.transform.scale(new_image_surface, (800, new_image_surface.get_height() * (800/new_image_surface.get_width())))
    new_image_rect = new_image_surface.get_rect(center=(WIDTH/2, HEIGHT/2))

    SCREEN.blit(new_image_surface, new_image_rect)
    SCREEN.blit(photo_title_text_surface, photo_title_text_rect)
    SCREEN.blit(image_count_text_surface, image_count_text_rect)

    REWIND_BUTTON.update(SCREEN)
    PAUSE_BUTTON.update(SCREEN)
    SEEK_BUTTON.update(SCREEN)
    LOAD_NEW_ALBUM_BUTTON.update(SCREEN)

    pygame.display.update()

    # 監聽鼠標點擊事件
    while True:
        for event in pygame.event.get():
            # 根據鼠標點擊情況, 是否點擊右上角的關閉
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                # 根據鼠標點擊情況, 做向前, 向後, 暫停, 開始等切換圖片操作
                current_mouse_pos = pygame.mouse.get_pos()
                if REWIND_BUTTON.check_for_input(current_mouse_pos):
                    rewind_button_pressed, current_image_index = rewind_button(current_image_index)
                if SEEK_BUTTON.check_for_input(current_mouse_pos):
                    seek_button_pressed, current_image_index = seek_button(current_image_index, image_names)
                if paused:
                    if PLAY_BUTTON.check_for_input(current_mouse_pos):
                        paused, unpaused = play_button()
                else:
                    if PAUSE_BUTTON.check_for_input(current_mouse_pos):
                        paused, unpaused = pause_button()
                if LOAD_NEW_ALBUM_BUTTON.check_for_input(current_mouse_pos):
                    load_button()

        current_time = pygame.time.get_ticks()

        # 切換圖片, 一定時間、點擊向後按鈕、點擊向前按鈕、點擊開始按鈕
        if current_time - previous_time >= COOLDOWN or rewind_button_pressed or seek_button_pressed or paused or unpaused:
            unpaused = False
            if current_image_index < len(image_file_paths)-1 and not seek_button_pressed and not rewind_button_pressed and not paused:
                current_image_index += 1

            SCREEN.blit(BACKGROUND_IMAGE, (0, 0))
            REWIND_BUTTON.update(SCREEN)
            if paused:
                PLAY_BUTTON.update(SCREEN)
            else:
                PAUSE_BUTTON.update(SCREEN)
            SEEK_BUTTON.update(SCREEN)
            LOAD_NEW_ALBUM_BUTTON.update(SCREEN)

            new_image_surface = pygame.image.load(image_file_paths[current_image_index])
            if new_image_surface.get_height() > 500:
                new_image_surface = pygame.transform.scale(new_image_surface, (new_image_surface.get_width() * (500/new_image_surface.get_height()), 500))
            elif new_image_surface.get_width() > 800:
                new_image_surface = pygame.transform.scale(new_image_surface, (800, new_image_surface.get_height() * (800/new_image_surface.get_width())))
            new_image_rect = new_image_surface.get_rect(center=(WIDTH/2, HEIGHT/2))

            SCREEN.blit(new_image_surface, new_image_rect)

            photo_title_text_surface = bold_font(90).render(image_names[current_image_index], True, BASE_TEXT_COLOR)
            photo_title_text_rect = photo_title_text_surface.get_rect(center=(WIDTH/2, 150))

            SCREEN.blit(photo_title_text_surface, photo_title_text_rect)

            image_count_text_surface = regular_font(80).render(f"圖片 {current_image_index+1}/{len(image_names)}", True, BASE_TEXT_COLOR)
            image_count_text_rect = image_count_text_surface.get_rect(center=(300, 755))

            SCREEN.blit(image_count_text_surface, image_count_text_rect)

            pygame.display.update()
            previous_time = pygame.time.get_ticks()
            seek_button_pressed = False
            rewind_button_pressed = False

同樣也有監聽鼠標點擊事件,根據鼠標點擊情況,做向前、向後、暫停、開始等切換圖片操作。

最終效果如下

到此這篇關於基於Python制作一個相冊播放器的文章就介紹到這瞭,更多相關Python相冊播放器內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: