You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Tkinter多代宝可梦图片滚动器开发问题求助

宝可梦御三家图片滚动器问题求助

我是Python新手,想要制作一个每次显示3张图片的图片滚动器,用于切换展示不同世代的宝可梦御三家图片。我尝试将图片按世代分组存入列表,但功能无法正常实现,怀疑问题出在子列表的使用上,希望得到帮助。

原代码

import tkinter as tk
from tkinter import *
from PIL import *


win = tk.Tk()

win.iconbitmap(r'pikachu.ico')
win.title('choose your pokemon!')
text = tk.Label(win, text='choose your starter pokemon!', fg='white', bg='red', font=20)
gen = tk.Label(win, text='generation 1', font=14, pady=10, bg='red')
win.geometry('400x200')
win.maxsize(400, 200)
win.config(bg='red')
button = Button(win, text='next gen>')

# loading alllll images (load gifs once i find out how..)
img1 = PhotoImage(file='poke/1_bulbasaur.png')
img2 = PhotoImage(file='poke/1_charmander.png')
img3 = PhotoImage(file='poke/1_squirtle.png')
img4 = PhotoImage(file='poke/2_chikorita.png')
img5 = PhotoImage(file='poke/2_cyndaquil.png')
img6 = PhotoImage(file='poke/2_totodile.png')
img7 = PhotoImage(file='poke/3_treecko.png')
img8 = PhotoImage(file='poke/3_torchic.png')
img9 = PhotoImage(file='poke/3_mudkip.png')
img10 = PhotoImage(file='poke/4_turtwig.png')
img11 = PhotoImage(file='poke/4_chimchar.png')
img12 = PhotoImage(file='poke/4_piplup.png')
img13 = PhotoImage(file='poke/5_snivy.png')
img14 = PhotoImage(file='poke/5_tepig.png')
img15 = PhotoImage(file='poke/5_oshawott.png')
img16 = PhotoImage(file='poke/6_chespin.png')
img17 = PhotoImage(file='poke/6_fennekin.png')
img18 = PhotoImage(file='poke/6_froakie.png')
img19 = PhotoImage(file='poke/7_rowlet.png')
img20 = PhotoImage(file='poke/7_litten.png')
img21 = PhotoImage(file='poke/7_popplio.png')


# pokemon gen lists
gen1 = ['img1', 'img2', 'img3']
gen2 = ['img4', 'img5', 'img6']
gen3 = ['img7', 'img8', 'img9']
gen4 = ['img10', 'img11', 'img12']
gen5 = ['img13', 'img14', 'img15']
gen6 = ['img16', 'img17', 'img18']
gen7 = ['img19', 'img20', 'img21']

genlist = ['gen1', 'gen2', 'gen3', 'gen4', 'gen5', 'gen6', 'gen7']

counter = 0
def changegen():
    global counter
    if counter < len(genlist) - 1:
        counter += 1
    else:
        counter = 0
    text.configure(image=genlist[counter])
    gen.configure(text='generation ' + str(counter + 1))


button.pack(side=BOTTOM, command=changegen())
text.pack()
gen.pack()

win.mainloop()

问题分析与修正方案

核心问题点

  • 列表存储错误:你把图片变量名存成了字符串(如gen1 = ['img1', 'img2', 'img3']),这只是保存了变量名称的文本,并非实际的PhotoImage对象,无法直接用于图片显示。
  • 按钮绑定错误:button.pack(..., command=changegen())中加了括号,会在程序启动时直接执行changegen函数,而非点击按钮时触发,应改为command=changegen。
  • 显示逻辑错误:仅用一个标签无法同时展示3张图片,需要为每个御三家位置创建独立标签。
  • 图片引用回收:Tkinter的PhotoImage若没有持久引用会被垃圾回收,导致图片不显示,需确保图片对象被全局或容器保留。

修正后的代码

import tkinter as tk
from tkinter import *

win = tk.Tk()

win.iconbitmap(r'pikachu.ico')
win.title('choose your pokemon!')
title_label = tk.Label(win, text='choose your starter pokemon!', fg='white', bg='red', font=20)
gen_label = tk.Label(win, text='generation 1', font=14, pady=10, bg='red')
win.geometry('600x300')  # 调整窗口大小以容纳3张图片
win.maxsize(600, 300)
win.config(bg='red')

# 创建三个标签用于显示御三家图片
poke_labels = [tk.Label(win, bg='red') for _ in range(3)]

# 加载图片,直接存入世代列表(存储实际的PhotoImage对象)
gen_images = [
    [PhotoImage(file='poke/1_bulbasaur.png'),
     PhotoImage(file='poke/1_charmander.png'),
     PhotoImage(file='poke/1_squirtle.png')],
    [PhotoImage(file='poke/2_chikorita.png'),
     PhotoImage(file='poke/2_cyndaquil.png'),
     PhotoImage(file='poke/2_totodile.png')],
    [PhotoImage(file='poke/3_treecko.png'),
     PhotoImage(file='poke/3_torchic.png'),
     PhotoImage(file='poke/3_mudkip.png')],
    [PhotoImage(file='poke/4_turtwig.png'),
     PhotoImage(file='poke/4_chimchar.png'),
     PhotoImage(file='poke/4_piplup.png')],
    [PhotoImage(file='poke/5_snivy.png'),
     PhotoImage(file='poke/5_tepig.png'),
     PhotoImage(file='poke/5_oshawott.png')],
    [PhotoImage(file='poke/6_chespin.png'),
     PhotoImage(file='poke/6_fennekin.png'),
     PhotoImage(file='poke/6_froakie.png')],
    [PhotoImage(file='poke/7_rowlet.png'),
     PhotoImage(file='poke/7_litten.png'),
     PhotoImage(file='poke/7_popplio.png')]
]

counter = 0

def changegen():
    global counter
    # 切换世代计数器,实现循环切换
    counter = (counter + 1) % len(gen_images)
    # 更新三个标签的图片
    for idx, label in enumerate(poke_labels):
        label.config(image=gen_images[counter][idx])
    # 更新世代文本
    gen_label.config(text=f'generation {counter + 1}')

# 按钮绑定函数(不要加括号)
button = Button(win, text='next gen>', command=changegen)

# 布局组件
title_label.pack()
gen_label.pack()
# 横向排列三个图片标签
for label in poke_labels:
    label.pack(side=LEFT, padx=10)
button.pack(side=BOTTOM, pady=10)

# 初始化显示第一世代图片
for idx, label in enumerate(poke_labels):
    label.config(image=gen_images[0][idx])

win.mainloop()

关键修改说明

  1. 图片存储优化:将图片直接按世代存入二维列表gen_images,每个子列表对应一个世代的三张PhotoImage对象,避免字符串引用错误。
  2. 多标签显示:创建三个poke_labels标签,分别对应御三家的位置,实现同时显示3张图片。
  3. 按钮绑定修正:去掉command后的括号,确保点击按钮时才触发切换函数。
  4. 计数器简化:用counter = (counter + 1) % len(gen_images)实现循环切换,无需复杂的条件判断。
  5. 窗口大小调整:扩大窗口以容纳三张横向排列的图片,提升显示效果。

内容的提问来源于stack exchange,提问作者azzy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 23:00:03