I'm having problems with the progress bar in my project :(

Introduction:

I made a small program to send notice via email to each member in a list (Excel file - sequential reading user name of account in excel file will be made ​​by the program)and the attached file corresponding to each user (Ex: User1 file 1, User 2 file).

Requirement:

Creat ProgressBar corresponds to an email sent successfully.

Ex:
ProgressBar: run corresponding description label below
Label:1 mail sent/2 mail sent .... Finished!

Best Regards!

Dani AI

Generated

A concise, practical pattern to send personalized emails with per-recipient attachments and show progress in a GUI. This builds on ' high-level suggestion: gather the list up front, run the sends in a background worker, and update the UI only from the GUI thread so the window does not freeze. The example below uses Python 3, Tkinter, threading and a Queue; adapt the send_email and Excel-loading parts for your environment.

Key points to follow:

  • Read the Excel rows into a list before starting so you know the total.
  • Run the sending loop in a worker thread; do not call SMTP send routines on the GUI thread.
  • Use a thread-safe Queue to post status updates (success/failure) back to the GUI and poll it with root.after(...).
  • Log failures (and optionally retry with exponential backoff); do not stop the whole run for a single failure.
  • Beware of SMTP rate limits and attachment sizes — add small delays or batch pauses if needed.

Example minimal pattern (Tkinter + Queue + worker thread):

import tkinter as tk
from tkinter import ttk
import threading
import queue
import time
import smtplib
from email.message import EmailMessage

def send_email(recipient):
    # Build message, attach file(s) and send via SMTP.
    # Replace SMTP settings and attachment code with your implementation.
    msg = EmailMessage()
    msg['From'] = "you@example.com"
    msg['To'] = recipient['email']
    msg['Subject'] = "Notice"
    msg.set_content("See attached.")
    with smtplib.SMTP('smtp.example.com', 587) as s:
        s.starttls()
        s.login('user', 'pass')
        s.send_message(msg)

root = tk.Tk()
pbar = ttk.Progressbar(root, length=300, mode='determinate')
pbar.pack(padx=8, pady=6)
status = tk.Label(root, text="Idle")
status.pack()

q = queue.Queue()

def worker(recipients):
    for r in recipients:
        try:
            send_email(r)
            q.put(('ok', None))
        except Exception as e:
            q.put(('err', str(e)))
        time.sleep(0.1)
    q.put(('done', None))

def start(recipients):
    pbar['maximum'] = len(recipients)
    pbar['value'] = 0
    status['text'] = f"0/{len(recipients)} sent"
    threading.Thread(target=worker, args=(recipients,), daemon=True).start()
    root.after(100, poll)

def poll():
    try:
        while True:
            tag, data = q.get_nowait()
            if tag == 'ok':
                pbar['value'] += 1
                status['text'] = f"{int(pbar['value'])}/{int(pbar['maximum'])} sent"
            elif tag == 'err':
                # record error in a log; optionally collect failed recipients
                pass
            elif tag == 'done':
                status['text'] = "Finished"
                return
    except queue.Empty:
        pass
    root.after(100, poll)

# Load recipients from Excel into a list of dicts then call start(recipients)
root.mainloop()

Troubleshooting notes: if the progress bar does not move, the sending loop is still running on the main thread. If sends stop intermittently, check SMTP server responses, implement retries and log each failure. For Excel, use openpyxl or pandas to read rows into a list before calling start. This pattern keeps the UI responsive and gives a reliable X/Y progress display for each successful send.

Recommended Answers

All 4 Replies

If the email being sent is the same for each user why don't you just use cc or bcc to send the email once but to many recipients? Then a progress bar isn't really needed.
If you want to send the emails sequentially (because the emails are different), count how many addresses there are and max this the max value of the progress bar and then, after each individual email has been sent, increase the progress bar by one.

I want to send the emails sequentially because the emails are different and attachments for each user is different. Can you provide me sample code for do it?

As you said "count how many addresses there are and max this the max value of the progress bar and then, after each individual email has been sent, increase the progress bar by one" mean is increase the progress bar by one is counting of the implementation period of the corresponding with progress bar?
If so, how to count one time email with attachment file to an per email account? Every time I send email execution, respectively for approximately 50 email address!

I need a sample code to understand!

I'm assuming you already have the email code because you didn't ask for that.
As I understand it you have the emails stored in a file which allows you to count how many emails you are going to be sending (as each email is unique you send one email per address). The number of emails in the file then becomes the number of emails you are going to send in total.
You are going to run through the email sending code many times so after each iteration (i.e. after calling the send method of the Mail object) increment the current value of the progress bar by one (thereby moving it towards the max value).
This isn't the code you asked for but its late and I'm tired:) It explains the principle behind how to handle the problem though.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.