【问题标题】:Looping through tkinter buttons not working well循环通过 tkinter 按钮无法正常工作
【发布时间】:2021-06-07 10:16:43
【问题描述】:

我正在编写一个新代码来使用循环在按钮上显示 sqlite 搜索结果。除 1 个问题外,代码正常工作。我编写了一个函数来更改背景颜色并在将鼠标悬停在按钮上时播放声音。问题是,当我将鼠标悬停在结果的任何按钮上时,颜色只会在最后一个按钮上发生变化,尽管声音播放没有问题。以下是涉及的部分代码:

SearchSelection = SearchVar.get()
SearchParameter = txtSearch.get()
conn = sqlite3.connect("EasyClinic.db")
cursor = conn.cursor()
cursor.execute ("SELECT * FROM patients WHERE (%s) = (?)" %(SearchSelection), 
(SearchParameter,))
results = cursor.fetchall()
conn.commit()
conn.close()
if len(results) == 0:
    print ("No result found")
else:
    for result in results:
        ResultsButtons = tk.Button(canvasResult, text=result, bg=BackGroundColor, fg=ForeGroundColor, relief='flat', font=MyFont2, width=65, height=2)
        ResultsButtons.pack(pady=5)
        def on_enter_results(result):
            ResultsButtons['background'] = Hover
            winsound.PlaySound ('Hover.wav', winsound.SND_ASYNC)
        def on_leave_results(result):
            ResultsButtons['background'] = BackGroundColor  
        ResultsButtons.bind("<Enter>", on_enter_results)
        ResultsButtons.bind("<Leave>", on_leave_results)

请为您提供帮助 谢谢

【问题讨论】:

    标签: python loops tkinter


    【解决方案1】:

    您可以更改on_enter_results()on_leave_results()这两个函数,如下所示:

    def on_enter_results(event):
        # event.widget is the widget that triggers this event
        event.widget['background'] = Hover
        winsound.PlaySound ('Hover.wav', winsound.SND_ASYNC)
    
    def on_leave_results(event):
        event.widget['background'] = BackGroundColor
    

    实际上你可以将这两个函数移到 for 循环之外(即在 for 循环之前)。

    【讨论】:

    • 非常感谢。这解决了这个问题。问候
    【解决方案2】:

    问题是python总是用最新的按钮覆盖ResultsButtons变量,这在调用函数on_enter_results或on_leave_results时会出现问题,因为它使用了覆盖的ResultsButtons变量。解决方案是更直接地指定按钮并使用 lambda 函数将其传递给您的函数。我无法检查这段代码是否有效,因为我没有完整的示例,但这样的东西应该可以工作:

    if len(results) == 0:
        print ("No result found")
    else:
        def on_enter_results(event_info, resbutton):
            resbutton['background'] = Hover
            winsound.PlaySound ('Hover.wav', winsound.SND_ASYNC)
        def on_leave_results(event_info, resbutton):
            resbutton['background'] = BackGroundColor  
        for result in results:
            ResultsButton = tk.Button(canvasResult, text=result, bg=BackGroundColor, fg=ForeGroundColor, relief='flat', font=MyFont2, width=65, height=2)
            ResultsButton.pack(pady=5)
            ResultsButton.bind("<Enter>", lambda event_info, btn=ResultsButton: on_enter_results(btn))
            ResultsButton.bind("<Leave>", lambda event_info, btn=ResultsButton: on_leave_results(btn))
    

    为了更好地了解实际情况:Python FAQ

    【讨论】:

    • 我试过了,可惜没用
    • 我更改了答案,我认为现在应该可以了。请注意,我重命名了一些变量以明确 event_info 是一个参数 tkinter 总是传递给事件的回调。在这种情况下,这个变量没有被使用,但仍然应该被接收函数接受。
    【解决方案3】:

    已由 acw1668 解决。谢谢大家的支持

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-16
      • 2019-01-01
      相关资源
      最近更新 更多