'tkinter progress bar to update while a function is running

I'm currently building an app where it sends an email to a specific email address within a mysql database with a click on a button. The interface uses a listbox to list all businesses and once you click on a business, you can click a button that says something like 'send email.'

I've got all this working but I want to add a progress bar in the footer of my GUI so that it updates while the function runs. I have been looking around Stackoverflow and many other resources and I know that I need to use the 'indeterminate' mode and consider threading but I am not quite getting it!

Currently I only have the progress bar showing but other than that I can't get it to 'link' to the function!

Function code that is called when the button is clicked:

def send_logins(retailer):
    c.execute("""SELECT Retailer, Retailer_Name, Contact, E_Mail, Account_ID, Password FROM Retailers where Retailer = ? """, (retailer[0]))
    users = c.fetchall()

    # Create a secure SSL context
    context = ssl.create_default_context()
    with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
        try:
            server.login(sender_email, password)
        except SMTPAuthenticationError:
            print("Username and/or password you entered is incorrect")
        try:
            missing = []
            for Retailer, Retailer_Name, Contact, E_Mail, Account_ID, Password in users:
                valid = True
                if not Retailer_Name:
                    missing.append("Business has no name!")
                    valid = False
                if not Account_ID:
                    missing.append("Business has no username!")
                    valid = False
                if not Password:
                    missing.append("Business has no password!")
                    valid = False
                if not E_Mail:
                    missing.append("Business has no email address!")
                    valid = False
                if valid:
                    server.sendmail(
                            sender_email,
                            E_Mail.split(';'),
                            message.as_string().format(
                                Retailer_Name=Retailer_Name,
                                Contact=Contact,
                                E_Mail=E_Mail,
                                previous_month=previous_month,
                                year=year,
                                Account_ID=Account_ID,
                                Password=Password),
                    )
                    server.sendmail(
                            sender_email,
                            E_Mail.split(';'),
                            message2.as_string().format(
                                Retailer_Name=Retailer_Name,
                                Contact=Contact,
                                E_Mail=E_Mail,
                                previous_month=previous_month,
                                year=year,
                                Account_ID=Account_ID,
                                Password=Password),
                    )
                    if valid:
                        print("Emails sent to " + str(Contact) + " at " + str(Retailer_Name))
                        sent_outcome_label.config(text="Emails sent to " + str(Contact) + " at " + str(Retailer_Name))
                        missing_fields_label.config(text="")
                else:
                    print("Emails not sent to " + str(Retailer_Name) + "!")
                    sent_outcome_label.config(text="Emails not sent to " + str(Contact) + " at " + str(Retailer_Name) + ":")
                    missing_fields_label.config(text=("\n".join(missing)))
                    print(missing)
        except SMTPException as e2:
            print(e2)
        except Exception as e:
            print("Emails not sent!")
            print(e)

Here is the code for the function button:

# Send login details button
send_login_button = ttk.Button(frame_send_logins, text="Yes", width=10, command=lambda: 
send_logins(retailer))
send_login_button.grid(row=1, column=0, padx=10, sticky=W)

And finally the code for displaying the progress bar:

# Create progress bar
pbar = ttk.Progressbar(frame_footer, orient='horizontal', mode='indeterminate')
pbar.grid(row=0, column=0, sticky=W)

Any help or pointers will be greatly appreciated! Thanks!



Sources

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

Source: Stack Overflow

Solution Source