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

基于Python的Gmail销售统计程序:数值递增1时播放声音的实现

Solution: Add Sound Alerts for Counter Changes

Hey there! Let's break down how to add those sound alerts when your submission or membership counts change by exactly +1 or -1. We'll cover two key parts: tracking the previous count values and playing the right sound at the right time.

1. How to Detect +1/-1 Changes

The trick here is to remember the last value of each counter every time we check the inbox. Then, when we get the new count, we calculate the difference between the new and old values:

  • If new_count - old_count == 1: That's an increment of 1—play your "positive" sound (like a cash register chime)
  • If new_count - old_count == -1: That's a decrement of 1—play your "negative" sound
  • Any other difference (like bulk updates from your end-of-day cleanup) won't trigger a sound, which is exactly what you want.

2. Playing Sounds in Python

For cross-platform support, I recommend using the playsound library (it works on Windows, Mac, and Linux). First, install it via pip:

pip install playsound

If you're on Windows and don't want extra dependencies, you can use the built-in winsound module instead—just swap out the play_sound function with that (I'll note how in the code comments).

3. Modified Full Code

Here's your updated code with all the logic added. I've commented the key changes so you can follow along:

#! /usr/bin/python3
import imaplib
import email
import tkinter as tk
from playsound import playsound  # Install first: pip install playsound
# For Windows-only, replace the line above with:
# import winsound

WIDTH = 1000
HEIGHT = 100

# Track the last known values for each counter (start at 0)
last_submission_count = 0
last_membership_count = 0

def play_sound(sound_file):
    """Helper function to play sound files"""
    try:
        playsound(sound_file)
        # For Windows-only with winsound, use this instead:
        # winsound.PlaySound(sound_file, winsound.SND_FILENAME)
    except Exception as e:
        print(f"Oops, couldn't play sound: {e}")

def update_submissions():
    global last_submission_count  # Tell Python we're using the global variable
    # Connect to Gmail (we could optimize this to connect once, but let's keep it simple first)
    mail = imaplib.IMAP4_SSL('imap.gmail.com', 993)
    mail.login('email@gmail.com', 'MyPassword')
    mail.select("Submissions")
    
    # Get unread messages
    typ, message_ids = mail.search(None, "UNSEEN")
    id_str = str(message_ids[0], encoding='utf8')
    
    # Calculate current count
    if id_str == '':
        current_count = 0
        info1['text'] = 'no submissions'
    else:
        current_count = len(id_str.split(" "))
        info1['text'] = f'{current_count} submission[s]'
    
    # Check for +1/-1 change and play sound
    count_diff = current_count - last_submission_count
    if count_diff == 1:
        play_sound("cash_register.wav")  # Replace with your increment sound path
    elif count_diff == -1:
        play_sound("error_alert.wav")    # Replace with your decrement sound path
    
    # Update the last count for next time
    last_submission_count = current_count
    # Schedule next update
    subs.after(1000, update_submissions)

def update_memberships():
    global last_membership_count
    mail = imaplib.IMAP4_SSL('imap.gmail.com', 993)
    mail.login('email@gmail.com', 'MyPassword')
    mail.select("Memberships")
    
    typ, message_ids = mail.search(None, "UNSEEN")
    id_str = str(message_ids[0], encoding='utf8')
    
    if id_str == '':
        current_count = 0
        info2['text'] = 'no memberships'
    else:
        current_count = len(id_str.split(" "))
        info2['text'] = f'{current_count} membership[s]'
    
    count_diff = current_count - last_membership_count
    if count_diff == 1:
        play_sound("cash_register.wav")
    elif count_diff == -1:
        play_sound("error_alert.wav")
    
    last_membership_count = current_count
    membs.after(1000, update_memberships)

# Setup Tkinter windows (note: using two Tk() instances can cause issues—better to use Toplevel for one window!)
membs = tk.Tk()
subs = tk.Tk()

membs.title('memberships counter')
membs.configure(background="black")
subs.title('submissions counter')
subs.configure(background="black")

# Position submissions window
x = (subs.winfo_screenwidth()//5) - (WIDTH//5)
y = (subs.winfo_screenheight()//5) - (HEIGHT//5)
subs.geometry(f'{WIDTH}x{HEIGHT}+{x}+{y}')
info1 = tk.Label(subs, text='nothing to display', bg="black", fg="green", font="Lucida_Console 40")
info1.pack()

# Position memberships window
x = (membs.winfo_screenwidth()//2) - (WIDTH//2)
y = (membs.winfo_screenheight()//2) - (HEIGHT//2)
membs.geometry(f'{WIDTH}x{HEIGHT}+{x}+{y}')
info2 = tk.Label(membs, text='nothing to display', bg="black", fg="red", font="Lucida_Console 40")
info2.pack()

# Start update loops
update_submissions()
update_memberships()

# Run the Tkinter main loops
membs.mainloop()
subs.mainloop()

Quick Optimizations to Consider

  • Reuse Gmail Connection: Right now, we log in to Gmail every second for each counter. That's unnecessary—you could create a single connection once and reuse it in both update functions to reduce overhead.
  • Single Tk() Instance: Tkinter isn't designed to handle multiple Tk() instances. Instead, make one window the main Tk() and the other a Toplevel() child window—this will avoid weird behavior like unresponsive windows.
  • Error Handling: Add try-except blocks around the Gmail login/select steps to handle network drops or login failures gracefully (so your program doesn't crash unexpectedly).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:24:26