'My code should play audio clip after the Dice Roll "Stop" is displayed and Button disabled. But audio plays before and "Stop" displayed afterwards

strong text The following code works fine except for one thing. The audio should play after the win result.. i.e after the "Roll the Dice " button display changes to "Stop" and the button is disabled. However the reverse happens.. So what's Wrong? What should be changed? Is there a way to call two functions sequentially using Lambda function? will appreciate some help

program for a simple set of 2 Dices play. No 6 from Both Dice wins. Disables the Dice Roll

#button and Dice Roll Buttondisplays "Stop". No of attempts also displayed as well.
# Since two Dices are involved other than  "Roll the Dice " button all labels are used twice
# to show the result of these two Dices
           
import tkinter as tk
import random
from tkinter import *
from playsound2 import playsound
import time
            
         
# flashing text part of the code
flash_delay = 500
            
# msec between colour change
flash_colours = ('Yellow', 'red') # Two colours to swap between
            
def flashColour(object, colour_index):
    object.config(foreground = flash_colours[colour_index])
    window.after(flash_delay, flashColour, object, 1 - colour_index)
                
            
# roll function called by btn_roll
a=7
def roll(a):
    lbl_result["text"] = str(random.randint(1, 6))
    lbl_resultA["text"] = str(random.randint(1, 6))
                
    if  lbl_result["text"] == "6" and lbl_resultA["text"] == "6":
        lbl_result1["text"] = " U Win"
        lbl_resultB["text"] = " U Win"     
                           
        flashColour(lbl_result1, 0)
        flashColour(lbl_resultB, 0)
        btn_roll["text"] = "Stop"
        btn_roll['state'] = DISABLED
        play(a)       
    else:
        lbl_result1["text"] = "Try Again"        
        flashColour(lbl_result1, 0)
        lbl_resultB["text"] = "Try Again"
        flashColour(lbl_resultB, 0)                  
            
# Clicked functions to count no  of clicks activated till button displays "Stop".       
count = 0
            
def clicked(): 
    if lbl_result["text"] <= ("6")and lbl_result["text"] <= ("6"):
        global count            
        count = count + 1            
        lbl_result3.configure(text=f'No of clicks = {count} ')
                    
                    
count1 = 0      
def clicked1(): 
    if lbl_resultA["text"] <= ("6") and lbl_result["text"] <= ("6"):
        global count1            
        count1 = count1 + 1            
        lbl_resultC.configure(text=f'No of clicks = {count1} ')
        return count1           
           
# play function to play a sound clip once the button displays stop. I want this to happen after the button diplay turns stop and is disabled. But this always happens before that..**

# if no of clicks before reaching 6-6 on both Dices is less than 35 this function plays "good job" audio clip.
#otherwise " finally" clip 
r=7        
def play(r):                
    if  count1 <=35 :
        playsound ('C:/Users/mural/C Language/goodjob.mp3')
    else: playsound ('C:/Users/mural/C Language/finally.mp3')        
    
 # Main tKinter Block                   
window = tk.Tk()
window.title("DICE GAME")         
            
            
window.columnconfigure(3, weight=1, minsize=150)
window.rowconfigure(3, weight=1, minsize=50)
frame = tk.Frame(master=window)
frame1 = tk.Frame(master=window)
frame2= tk.Frame(master=window)
frame3= tk.Frame(master=window)
frame.grid(row=0, column=0, padx=5, pady=5)
frame1.grid(row=0, column=1, padx=5, pady=5)
frame2.grid(row=0,column=2,padx=5, pady=5)
            
btn_roll = tk.Button(master =frame,bg ="YELLOW",fg = "BLUE",text="Roll the Dice ",font= ('ARIAL 15 underline'),width = 12,height =1,relief = tk.RAISED,command=lambda :[roll(a),clicked(),clicked1()],state =  NORMAL)              
lbl_result = tk.Label(master = frame2,width = 2,height =1,text = "HI",bg="GREEN",fg="YELLOW",font = (" ARIAL ITALICS",15))
lbl_resultA = tk.Label(master = frame1,width = 2,height =1,text = "HI",bg="GREEN",fg="YELLOW",font = (" ARIAL ITALICS",15))
lbl_result1 = tk.Label(master =frame2,text = "Start",font = (" ARIAL ITALICS",8),width = 6,height =2,bg="BLUE",fg="YELLOW")        
lbl_resultB = tk.Label(master =frame1,text = "Start",font = (" ARIAL ITALICS",8),width = 6,height =2,bg="BLUE",fg="YELLOW")                
lbl_result3 = tk.Label(master =frame2,text = "No of Attempts",relief = tk.GROOVE,font = (" ARIAL ITALICS",8),width =12,height =1,bg="BLUE",fg="YELLOW")                
lbl_resultC = tk.Label(master =frame1,text = "No of Attempts",relief = tk.GROOVE,font = (" ARIAL ITALICS",8),width =12,height =1,bg="BLUE",fg="YELLOW")        
            
btn_roll.pack(padx=5,pady=5)       
lbl_result.pack(padx=5, pady=5)       
lbl_result1.pack(padx=5, pady=5)       
lbl_result3.pack(padx=5, pady=5)       
lbl_resultA.pack(padx=5, pady=5)       
lbl_resultB.pack(padx=5, pady=5)       
lbl_resultC.pack(padx=5, pady=5)       
            
window.mainloop()  


Solution 1:[1]

By using after method ( which is built-in in python3) I could resolve this issue

# roll function called by btn_roll
a=7
def roll(a):
lbl_result["text"] = str(random.randint(1, 6))
lbl_resultA["text"] = str(random.randint(1, 6))
            
if  lbl_result["text"] == "6" and lbl_resultA["text"] == "6":
    lbl_result1["text"] = " U Win"
    lbl_resultB["text"] = " U Win"     
                       
    flashColour(lbl_result1, 0)
    flashColour(lbl_resultB, 0)
    btn_roll["text"] = "Stop"
    btn_roll['state'] = DISABLED
    window.after(500,play(a)) # using after the sound plays only after display changes

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1