发送emai时阻止TTK进度条

2024-06-07 13:54:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用tkinter用python编写一个应用程序。在这个应用程序我试图发送一批电子邮件,我想显示一个进度条,而他们正在发送。我可以创建进度条并启动它,但当电子邮件被发送时,该条停止移动(如果它是在电子邮件发送之前启动的,我想在电子邮件发送之前启动该条,但它只是挂起,当我这样做时,它就挂起了,没有任何东西在栏上移动。在

startProgressBar()
sendEmails()
stopProgressBar()

我试过把发送邮件的方式分为一个单独的线程,但我似乎没有任何运气。我正在使用高级线程模块。有什么建议吗?也许我没有弄好穿线部分。我正在使用smtplib发送电子邮件。在


Tags: 模块进度条应用程序tkinter电子邮件方式邮件线程
3条回答

试着这样做:

progress = ttk.Progressbar(bottommenuframe, orient=HORIZONTAL, length=100, maximum=(NUMBEROFEMAILS), mode='determinate')
progress.pack(side=RIGHT)

def emailing():
    progress.start()   
    ##send 1 email
    progress.step(1)

    if all emails sent:
        progress.stop()

    root.after(0, emailing)

这对你应该有用。 希望有帮助:)

此后,我在应用程序的更新中重新讨论了这个问题。我已经将其转换为使用Swing for the UI的jython项目。在

同样,我认为使用观察者模式是解决问题的最简单方法。对于我的项目来说,拥有并发线程并不是一个必要条件,我只想给出一个大致的进度视图。观察者模式非常适合我的需要,观察者模式的Java实现特别有用。在

这是一个老问题,但我所指的代码配方帮助我实现了一个类似的概念,所以我认为应该与大家分享。在

这种类型的问题需要使用线程,这样我们就可以将更新GUI和执行实际任务(例如发送电子邮件)的任务分开。从Active State看一下这个code recipe,我相信它正是您所要寻找的线程化和线程间(通过队列)传递信息的示例。在

我试图强调代码配方中的重要部分。我不包括设置进度条本身,而是整个代码结构和获取/设置队列。在

import Tkinter
import threading
import Queue

class GuiPart:
    def __init__(self, master, queue, endCommand):
        self.queue = queue
        # Do GUI set up here (i.e. draw progress bar)

        # This guy handles the queue contents
        def  processIncoming(self):
            while self.queue.qsize():
                try:
                    # Get a value (email progress) from the queue 
                    progress = self.queue.get(0)
                    # Update the progress bar here.

                except Queue.Empty:
                    pass

class ThreadedClient:
    # Launches the Gui and does the sending email task
    def __init__(self, master):
        self.master = master
        self.queue = Queue.Queue()

        # Set up the Gui, refer to code recipe
        self.gui = GuiPart(master, self.queue, ...)

        # Set up asynch thread (set flag to tell us we're running)
        self.running = 1        
        self.email_thread = threading.Thread(target = self.send_emails)
        self.email_thread.start()

        # Start checking the queue
        self.periodicCall()

     def periodicCall(self):
         # Checks contents of queue
         self.gui.processIncoming()
         # Wait X milliseconds, call this again... (see code recipe)

     def send_emails(self): # AKA "worker thread"
         while (self.running):
             # Send an email
             # Calculate the %age of email progress

             # Put this value in the queue!
             self.queue.put(value)

     # Eventually run out of emails to send.
     def endApplication(self):
         self.running = 0


root = Tkinter.Tk()
client = ThreadedClient(root)
root.mainloop()

相关问题 更多 >

    热门问题