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

树莓派上Tkinter按钮命令无法执行问题求助

树莓派Tkinter GUI按钮无响应,仅断点调试时正常的问题

项目概况

我正在开发一款MP3片段选择播放应用,运行在配备7英寸触摸屏和piAMP+扩展板的树莓派4上:

  • GUI基于tkinter开发,pygame处理音频,通过GPIO引脚实现音量调节
  • 用户可通过GUI上下箭头按钮选择片段,播放/停止按钮控制播放
  • 完整脚本在PC端PyCharm调试(注释GPIO代码)时完全正常,但移植到树莓派用Thonny调试时,GUI能加载但所有按钮均无响应

关键现象

  • 从Thonny或命令行执行时,GUI正常显示,但GUI按钮和GPIO按钮均无响应
  • 在Thonny调试中,若在root.mainloop()处设置断点,脚本暂停后恢复,前后选择、播放/停止按钮及对应代码均可正常工作
  • 在root.update()和root.mainloop()之间添加time.sleep(5)或root.after(2500),问题依旧

代码设计细节

  1. 最初计划用列表框显示歌曲,但无法实现选中项高亮,因此改用label_list字典(存储网格位置和tkinter.ttk.Label对象)配合current变量管理选中状态
  2. previous函数通过修改标签的前景色和背景色切换高亮效果,并更新current(当前选中歌曲的索引)
  3. 播放选中歌曲时,直接从songs列表获取MP3文件名,和label_list无关,但无断点时播放功能同样无法激活

极简复现代码

# Import tkinter (GUI), pygame (Audio) and csv (to parse file into a list of dict
import tkinter as tk            # Display library, using grid placement
from tkinter import ttk         # This includes newer methods for labels

# Variable declarations and defaults
label_list = {}                 # Initialize the list of song labels (in grid)
set_volume = 0.1        # Default volume, 10%
current = 0         # Index corresponding the current (highlighted) song

songs = [{'Index': 0, 'Program': "Song1", 'File': 'song1.mp3'},
{'Index': 1, 'Program': 'Song2', 'File': 'song2.mp3'},
{'Index': 2, 'Program': 'Song3', 'File': 'song3.mp3'},
{'Index': 3, 'Program': 'Song4', 'File': 'song4.mp3'},
{'Index': 4, 'Program': 'Song5', 'File': 'song5.mp3'}]

def previous():
    # Decrement the current index (song), restore the old, highlight the new
    global label_list           # This is a list of dictionaries
    global current              # This is the index corresponding to the current song
    # Revert the current song to default colors
    print("Got to previous")
    label_list[(0, current)].config(background='White', foreground='Black')
    if current == 0:
        current = 4  # Last song in the queue, ie wrap-around
    else:
        current -= 1  # Decrement by 1
    # Reverse-video the new current song
    label_list[(0, current)].config(background='Black', foreground='White')

def main():
    # Create the root window
    global songs
    root = tk.Tk()
    root.title("Help Me")
    root.geometry('600x400')
    root.config(bg='White')     # Default to using white, not system background

    # Create the GUI as a 6 row x 3 column Grid
    for grid_row in range(6):
        root.rowconfigure(grid_row, weight=1)
    root.columnconfigure(0, weight=3)  # The intent was to make this column wider
    root.columnconfigure(1, weight=1)  # This is actually a spacer between song and arrow
    root.columnconfigure(2, weight=1)  # These are the arrow buttons

    # Locate songs on grid, column 1
    for song_row in songs:
        if song_row['Index'] == 0:
            # Start with making this row reverse-video
            song_label = ttk.Label(root, text=song_row['Program'], background='Black', foreground='White')
        else:
            song_label = ttk.Label(root, text=song_row['Program'], background='White', foreground='Black')
        # Assign the song_label to a list which can later be manipulated
        label_list[(0, song_row['Index'])] = song_label
        # Assign the song_row contents to the grid at the row/column
        song_label.grid(column=0, row=song_row['Index'], sticky=tk.EW, padx=5, pady=5)

    # locate arrow up/down buttons on column 2 - spanning 2 rows down, u2191 is ascii up arrow
    song_prev = ttk.Button(root, text='\u2191', command=previous)
    song_prev.grid(column=2, row=1, columnspan=2, sticky=tk.EW, padx=5, pady=5)

    # This sets the program to run continuously
    root.update()
    print("Got to mainloop")
    root.mainloop()
    
if __name__ == '__main__':
    main()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 05:13:16