以下方法绑定到应使用Python的SMTP库发送电子邮件的发送按钮。我想要的是我的屏幕上的标签在发送邮件之前显示“发送...”文本然后在发送邮件之后弹出窗口将显示邮件发送的文本。我面临的问题是按下按钮后没有任何反应(标签文本没有显示),片刻之后(正常发送邮件的时间)弹出节目和标签中的文字显示...它是对我来说很奇怪,所有输出都是同时显示而不是正常顺序:
在标签中显示文字>发送邮件>邮件发送后显示弹出窗口。
我的代码如下:
def send_email(self):
self.the_mail_feedback.text = "Sending..."#this is not showing at first but after execution!
gmail_user = str(self.txt_from_mail.text)
gmail_pwd = str(self.txt_password.text)
FROM = str(self.txt_from_mail.text)
TO = []
TO.append(str(self.txt_to_mail.text))
SUBJECT = "subject 1"
TEXT = "some text..."
message = """\From: %s\nTo: %s\nSubject:
%s\n\n%s""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
try:
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(gmail_user, gmail_pwd)
server.sendmail(FROM, TO, message)
server.close()
self.pop.open()#a popup that says that the mail is sent...
#self.the_mail_feedback.text="" #will uncomment when it works to reset feedback
except:
self.the_mail_feedback.text="Failed To Send Mail... Check Credentials
“
答案 0 :(得分:1)
问题是所有这些操作都发生在同一个线程中,即主程序循环。因此,例如你的第二行确实更改了标签文本,但是在你的函数完成并且将控制释放到正常的kivy eventloop之前,ui不会更新。然后,eventloop更新标签的图形表示。
所以实际上一切都是按顺序进行的,只是图形在函数完成之前不能自由更新,此时一切都会立即发生。出于同样的原因,您会发现在邮件发送时您无法进行任何触摸输入。
为避免这种情况,您需要使用eventloop并允许正常kivy控制流的位置继续。这是一个我认为应该有效的简单示例:
def begin_send_email(self):
self.the_mail_feedback.text = "Sending..."#this is not showing at first but after execution!
Clock.schedule_once(self.finish_send_email, 0)
def finish_send_email(self, *args):
gmail_user = str(self.txt_from_mail.text)
gmail_pwd = str(self.txt_password.text)
FROM = str(self.txt_from_mail.text)
TO = []
TO.append(str(self.txt_to_mail.text))
SUBJECT = "subject 1"
TEXT = "some text..."
message = """\From: %s\nTo: %s\nSubject:
%s\n\n%s""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
try:
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(gmail_user, gmail_pwd)
server.sendmail(FROM, TO, message)
server.close()
self.pop.open()#a popup that says that the mail is sent...
#self.the_mail_feedback.text="" #will uncomment when it works to reset feedback
except:
self.the_mail_feedback.text="Failed To Send Mail... Check Credentials
当然还有其他方法可以构建它,但一般的想法是,不是锁定事件循环,而是函数更新标签文本,然后在将控制权交还给eventloop之前安排更多任务。然后,eventloop执行其正常任务,包括在执行预定功能完成发送之前将图形标签设置为“正在发送...”。
您可能还发现从单独的线程发送电子邮件是必要或有用的,以避免锁定ui,尽管它可能足够快就可以了。你可以很容易地做到这一点,但你必须小心只在主线程中执行图形操作。