一. smtplib 的介绍
smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])
SMTP类构造函数,表示与SMTP服务器之间的连接,通过这个连接可以向smtp服务器发送指令,执行相关操作(如:登陆、发送邮件)。所有参数都是可选的。
host:smtp服务器主机名
port:smtp服务的端口,默认是25;如果在创建SMTP对象的时候提供了这两个参数,在初始化的时候会自动调用connect方法去连接服务器。
smtplib模块还提供了SMTP_SSL类和LMTP类,对它们的操作与SMTP基本一致。
smtplib.SMTP提供的方法:
SMTP.set_debuglevel(level):设置是否为调试模式。默认为False,即非调试模式,表示不输出任何调试信息。
SMTP.connect([host[, port]]):连接到指定的smtp服务器。参数分别表示smpt主机和端口。注意: 也可以在host参数中指定端口号(如:smpt.yeah.net:25),这样就没必要给出port参数。
SMTP.docmd(cmd[, argstring]):向smtp服务器发送指令。可选参数argstring表示指令的参数。
SMTP.helo([hostname]) :使用"helo"指令向服务器确认身份。相当于告诉smtp服务器“我是谁”。
SMTP.has_extn(name):判断指定名称在服务器邮件列表中是否存在。出于安全考虑,smtp服务器往往屏蔽了该指令。
SMTP.verify(address) :判断指定邮件地址是否在服务器中存在。出于安全考虑,smtp服务器往往屏蔽了该指令。
SMTP.login(user, password) :登陆到smtp服务器。现在几乎所有的smtp服务器,都必须在验证用户信息合法之后才允许发送邮件。
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]) :发送邮件。这里要注意一下第三个参数,msg是字符串,表示邮件。我们知道邮件一般由标题,发信人,收件人,邮件内容,附件等构成,发送邮件的时候,要注意msg的格式。这个格式就是smtp协议中定义的格式。
SMTP.quit() :断开与smtp服务器的连接,相当于发送"quit"指令。(很多程序中都用到了smtp.close(),具体与quit的区别google了一下,也没找到答案。)
参考:http://www.cnblogs.com/xiao*/archive/2012/03/17/2404015.html
二.创建Ui
sendmail.Ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SendMailer</class>
<widget class="QWidget" name="SendMailer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>518</width>
<height>519</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="minimumSize">
<size>
<width>0</width>
<height>90</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>90</height>
</size>
</property>
<property name="title">
<string>配置项</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>服务器地址:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBoxServer">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditSMTP">
<property name="text">
<string>自定义</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>用户名:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditUser">
<property name="inputMethodHints">
<set>Qt::ImhNone</set>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>密码:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditPasswd">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBoxRememberUP">
<property name="text">
<string>记住用户名密码</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="minimumSize">
<size>
<width>500</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>内容项</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_5">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>接收人: </string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditReceiver"/>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>多个用, 分隔开</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>邮件主题:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditCheme"/>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>邮件正文:</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="textEditBody"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>邮件附件:</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="attachBtn">
<property name="text">
<string>选择附件</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditAttach"/>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QProgressBar" name="progressBarSend">
<property name="value">
<number>24</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelSendMsg">
<property name="minimumSize">
<size>
<width>71</width>
<height>0</height>
</size>
</property>
<property name="text">
<string> 发送消息</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="sendingBtn">
<property name="text">
<string>开始发送</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
转换为sendmail.py
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'sendmail.ui'
#
# Created: Thu Mar 05 17:49:53 2015
# by: PyQt4 UI code generator 4.10.3
#
# WARNING! All changes made in this file will be lost! from PyQt4 import QtCore, QtGui try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig) class Ui_SendMailer(object):
def setupUi(self, SendMailer):
SendMailer.setObjectName(_fromUtf8("SendMailer"))
SendMailer.resize(518, 519)
self.verticalLayout = QtGui.QVBoxLayout(SendMailer)
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.groupBox = QtGui.QGroupBox(SendMailer)
self.groupBox.setMinimumSize(QtCore.QSize(0, 90))
self.groupBox.setMaximumSize(QtCore.QSize(16777215, 90))
self.groupBox.setObjectName(_fromUtf8("groupBox"))
self.verticalLayout_4 = QtGui.QVBoxLayout(self.groupBox)
self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4"))
self.horizontalLayout_7 = QtGui.QHBoxLayout()
self.horizontalLayout_7.setObjectName(_fromUtf8("horizontalLayout_7"))
self.label = QtGui.QLabel(self.groupBox)
self.label.setObjectName(_fromUtf8("label"))
self.horizontalLayout_7.addWidget(self.label)
self.comboBoxServer = QtGui.QComboBox(self.groupBox)
self.comboBoxServer.setMinimumSize(QtCore.QSize(150, 0))
self.comboBoxServer.setObjectName(_fromUtf8("comboBoxServer"))
self.horizontalLayout_7.addWidget(self.comboBoxServer)
self.lineEditSMTP = QtGui.QLineEdit(self.groupBox)
self.lineEditSMTP.setObjectName(_fromUtf8("lineEditSMTP"))
self.horizontalLayout_7.addWidget(self.lineEditSMTP)
self.verticalLayout_4.addLayout(self.horizontalLayout_7)
self.line_4 = QtGui.QFrame(self.groupBox)
self.line_4.setFrameShape(QtGui.QFrame.HLine)
self.line_4.setFrameShadow(QtGui.QFrame.Sunken)
self.line_4.setObjectName(_fromUtf8("line_4"))
self.verticalLayout_4.addWidget(self.line_4)
self.horizontalLayout_8 = QtGui.QHBoxLayout()
self.horizontalLayout_8.setObjectName(_fromUtf8("horizontalLayout_8"))
self.label_2 = QtGui.QLabel(self.groupBox)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.horizontalLayout_8.addWidget(self.label_2)
self.lineEditUser = QtGui.QLineEdit(self.groupBox)
self.lineEditUser.setInputMethodHints(QtCore.Qt.ImhNone)
self.lineEditUser.setObjectName(_fromUtf8("lineEditUser"))
self.horizontalLayout_8.addWidget(self.lineEditUser)
self.line_5 = QtGui.QFrame(self.groupBox)
self.line_5.setFrameShape(QtGui.QFrame.VLine)
self.line_5.setFrameShadow(QtGui.QFrame.Sunken)
self.line_5.setObjectName(_fromUtf8("line_5"))
self.horizontalLayout_8.addWidget(self.line_5)
self.label_3 = QtGui.QLabel(self.groupBox)
self.label_3.setObjectName(_fromUtf8("label_3"))
self.horizontalLayout_8.addWidget(self.label_3)
self.lineEditPasswd = QtGui.QLineEdit(self.groupBox)
self.lineEditPasswd.setEchoMode(QtGui.QLineEdit.Password)
self.lineEditPasswd.setObjectName(_fromUtf8("lineEditPasswd"))
self.horizontalLayout_8.addWidget(self.lineEditPasswd)
self.checkBoxRememberUP = QtGui.QCheckBox(self.groupBox)
self.checkBoxRememberUP.setObjectName(_fromUtf8("checkBoxRememberUP"))
self.horizontalLayout_8.addWidget(self.checkBoxRememberUP)
self.verticalLayout_4.addLayout(self.horizontalLayout_8)
self.verticalLayout.addWidget(self.groupBox)
self.groupBox_2 = QtGui.QGroupBox(SendMailer)
self.groupBox_2.setMinimumSize(QtCore.QSize(500, 0))
self.groupBox_2.setObjectName(_fromUtf8("groupBox_2"))
self.verticalLayout_2 = QtGui.QVBoxLayout(self.groupBox_2)
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
self.label_5 = QtGui.QLabel(self.groupBox_2)
self.label_5.setMaximumSize(QtCore.QSize(16777215, 16777215))
self.label_5.setObjectName(_fromUtf8("label_5"))
self.horizontalLayout_2.addWidget(self.label_5)
self.lineEditReceiver = QtGui.QLineEdit(self.groupBox_2)
self.lineEditReceiver.setObjectName(_fromUtf8("lineEditReceiver"))
self.horizontalLayout_2.addWidget(self.lineEditReceiver)
self.label_6 = QtGui.QLabel(self.groupBox_2)
self.label_6.setObjectName(_fromUtf8("label_6"))
self.horizontalLayout_2.addWidget(self.label_6)
self.verticalLayout_2.addLayout(self.horizontalLayout_2)
self.line = QtGui.QFrame(self.groupBox_2)
self.line.setFrameShape(QtGui.QFrame.HLine)
self.line.setFrameShadow(QtGui.QFrame.Sunken)
self.line.setObjectName(_fromUtf8("line"))
self.verticalLayout_2.addWidget(self.line)
self.horizontalLayout_3 = QtGui.QHBoxLayout()
self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))
self.label_7 = QtGui.QLabel(self.groupBox_2)
self.label_7.setObjectName(_fromUtf8("label_7"))
self.horizontalLayout_3.addWidget(self.label_7)
self.lineEditCheme = QtGui.QLineEdit(self.groupBox_2)
self.lineEditCheme.setObjectName(_fromUtf8("lineEditCheme"))
self.horizontalLayout_3.addWidget(self.lineEditCheme)
self.verticalLayout_2.addLayout(self.horizontalLayout_3)
self.line_3 = QtGui.QFrame(self.groupBox_2)
self.line_3.setFrameShape(QtGui.QFrame.HLine)
self.line_3.setFrameShadow(QtGui.QFrame.Sunken)
self.line_3.setObjectName(_fromUtf8("line_3"))
self.verticalLayout_2.addWidget(self.line_3)
self.verticalLayout_3 = QtGui.QVBoxLayout()
self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
self.label_8 = QtGui.QLabel(self.groupBox_2)
self.label_8.setObjectName(_fromUtf8("label_8"))
self.verticalLayout_3.addWidget(self.label_8)
self.textEditBody = QtGui.QTextEdit(self.groupBox_2)
self.textEditBody.setObjectName(_fromUtf8("textEditBody"))
self.verticalLayout_3.addWidget(self.textEditBody)
self.horizontalLayout_4 = QtGui.QHBoxLayout()
self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4"))
self.label_4 = QtGui.QLabel(self.groupBox_2)
self.label_4.setObjectName(_fromUtf8("label_4"))
self.horizontalLayout_4.addWidget(self.label_4)
self.attachBtn = QtGui.QPushButton(self.groupBox_2)
self.attachBtn.setObjectName(_fromUtf8("attachBtn"))
self.horizontalLayout_4.addWidget(self.attachBtn)
self.lineEditAttach = QtGui.QLineEdit(self.groupBox_2)
self.lineEditAttach.setObjectName(_fromUtf8("lineEditAttach"))
self.horizontalLayout_4.addWidget(self.lineEditAttach)
self.verticalLayout_3.addLayout(self.horizontalLayout_4)
self.verticalLayout_2.addLayout(self.verticalLayout_3)
self.verticalLayout.addWidget(self.groupBox_2)
self.horizontalLayout_6 = QtGui.QHBoxLayout()
self.horizontalLayout_6.setObjectName(_fromUtf8("horizontalLayout_6"))
self.progressBarSend = QtGui.QProgressBar(SendMailer)
self.progressBarSend.setProperty("value", 24)
self.progressBarSend.setObjectName(_fromUtf8("progressBarSend"))
self.horizontalLayout_6.addWidget(self.progressBarSend)
self.labelSendMsg = QtGui.QLabel(SendMailer)
self.labelSendMsg.setMinimumSize(QtCore.QSize(71, 0))
self.labelSendMsg.setObjectName(_fromUtf8("labelSendMsg"))
self.horizontalLayout_6.addWidget(self.labelSendMsg)
spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.horizontalLayout_6.addItem(spacerItem)
self.sendingBtn = QtGui.QPushButton(SendMailer)
self.sendingBtn.setObjectName(_fromUtf8("sendingBtn"))
self.horizontalLayout_6.addWidget(self.sendingBtn)
self.verticalLayout.addLayout(self.horizontalLayout_6) self.retranslateUi(SendMailer)
QtCore.QMetaObject.connectSlotsByName(SendMailer) def retranslateUi(self, SendMailer):
SendMailer.setWindowTitle(_translate("SendMailer", "Form", None))
self.groupBox.setTitle(_translate("SendMailer", "配置项", None))
self.label.setText(_translate("SendMailer", "服务器地址:", None))
self.lineEditSMTP.setText(_translate("SendMailer", "自定义", None))
self.label_2.setText(_translate("SendMailer", "用户名:", None))
self.label_3.setText(_translate("SendMailer", "密码:", None))
self.checkBoxRememberUP.setText(_translate("SendMailer", "记住用户名密码", None))
self.groupBox_2.setTitle(_translate("SendMailer", "内容项", None))
self.label_5.setText(_translate("SendMailer", "接收人: ", None))
self.label_6.setText(_translate("SendMailer", "多个用, 分隔开", None))
self.label_7.setText(_translate("SendMailer", "邮件主题:", None))
self.label_8.setText(_translate("SendMailer", "邮件正文:", None))
self.label_4.setText(_translate("SendMailer", "邮件附件:", None))
self.attachBtn.setText(_translate("SendMailer", "选择附件", None))
self.labelSendMsg.setText(_translate("SendMailer", " 发送消息", None))
self.sendingBtn.setText(_translate("SendMailer", "开始发送", None)) if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
SendMailer = QtGui.QWidget()
ui = Ui_SendMailer()
ui.setupUi(SendMailer)
SendMailer.show()
sys.exit(app.exec_())
三. 逻辑的实现
MainSendMailer.py
# -*- coding: utf-8 -*- from PyQt4 import QtGui, QtCore
from sendmail import Ui_SendMailer
import os
import icoqrc class SendingMail(QtGui.QWidget):
def __init__(self, parent=None):
super(SendingMail, self).__init__(parent)
self.Ui= Ui_SendMailer()
self.Ui.setupUi(self)
self.setWindowTitle(u'Pyqt 邮件发送')
self.setWindowIcon(QtGui.QIcon(':myfavicon.ico'))
reload(sys)
sys.setdefaultencoding("utf-8")
#初始化UI项目
self.proparam()
# 获取配置项
self.GetConfig()
self.Ui.comboBoxServer.activated.connect(self.ServerSmtp) # stmp服务器
self.Ui.attachBtn.clicked.connect(self.SelAttach) # 选择附件
self.connect(self.Ui.sendingBtn,QtCore.SIGNAL("clicked()"), self.sending) # 发送进度
self.timer = QtCore.QBasicTimer() # def初始化UI项目
def proparam(self):
self.Ui.comboBoxServer.addItem(u'选择服务地址',QtCore.QVariant(''))
self.Ui.comboBoxServer.addItem(u'网易163',QtCore.QVariant('smtp.163.com'))
self.Ui.comboBoxServer.addItem(u'腾讯邮箱',QtCore.QVariant('smtp.qq.com'))
self.Ui.comboBoxServer.addItem(u'新浪邮箱',QtCore.QVariant('smtp.sina.com.cn'))
self.Ui.comboBoxServer.addItem(u'搜狐邮箱',QtCore.QVariant('smtp.sohu.com'))
self.Ui.comboBoxServer.addItem(u'Google邮箱',QtCore.QVariant('smtp.gmail.com'))
self.Ui.comboBoxServer.addItem(u'自定义',QtCore.QVariant(''))
# 隐藏发送进度和发送提示
self.Ui.progressBarSend.hide()
self.Ui.labelSendMsg.hide()
# 记住密码配置密钥 self.keyt=0xa1a2a3a8 # stmp 服务器
def ServerSmtp(self):
comboxserver= self.Ui.comboBoxServer.currentIndex()
comboxItemData= self.Ui.comboBoxServer.itemData(comboxserver)
self.Ui.lineEditSMTP.setText(comboxItemData.toPyObject()) # 选择附件 后期判断文件大小,显示格式等
def SelAttach(self):
files = QtGui.QFileDialog.getOpenFileName(self, u'选择附件')
self.Ui.lineEditAttach.setText(files) # 配置项
def GetConfig(self, sendingSucc=''):
isConfig = os.path.exists(r'SendMailerConfig.ini')
if isConfig and sendingSucc == '': # 存在记住用户名和密码
self.Ui.checkBoxRememberUP.setChecked(True)
file = QtCore.QFile("SendMailerConfig.ini")
file.open(QtCore.QIODevice.ReadOnly)
In = QtCore.QDataStream(file)
In.setVersion(QtCore.QDataStream.Qt_4_0)
magic = In.readUInt32()
if magic != self.keyt:
QtGui.QMessageBox.information(self,"exception",u"记住密码数据格式错误!")
return
comboBoxServer = In.readUInt32()
LoginUser = In.readString()
LoginPasswd = In.readString()
self.Ui.comboBoxServer.setCurrentIndex(comboBoxServer)
comboxItemData = self.Ui.comboBoxServer.itemData(comboBoxServer)
self.Ui.lineEditSMTP.setText(comboxItemData.toPyObject())
self.Ui.lineEditUser.setText(str(LoginUser))
self.Ui.lineEditPasswd.setText(str(LoginPasswd))
# 发送成功判断记住密码
if sendingSucc:
isChecked = self.Ui.checkBoxRememberUP.isChecked()
if isChecked:
file = QtCore.QFile("SendMailerConfig.ini")
self.time = QtCore.QDateTime()
file.open(QtCore.QIODevice.WriteOnly)
out = QtCore.QDataStream(file)
out.setVersion(QtCore.QDataStream.Qt_4_0)
out.writeUInt32(self.keyt) # writeUInt32 参数为int类型
out.writeUInt32(self.Ui.comboBoxServer.currentIndex())
out.writeString(self.Ui.lineEditUser.text()) # writeString 参数为string类型
out.writeString(self.Ui.lineEditPasswd.text())
out << self.time.currentDateTime() # 发送邮件
def sending(self):
exist = self.basicExist()
if exist:
success = self.CoreAction()
if success:
#判断是否记住密码
self.GetConfig('sendSuccess')
self.timer.start(10, self) # 引入smtplib 发送邮件
def CoreAction(self):
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 发送进度显示
self.Ui.labelSendMsg.show()
self.Ui.labelSendMsg.setText(u'正在发送……')
self.Ui.progressBarSend.show()
self.step = 0
self.timer.start(1000, self) smtpConfig = {} # 配置
smtpConfig['Connect'] = str(self.Ui.lineEditSMTP.text())
smtpConfig['LoginUser'] = str(self.Ui.lineEditUser.text())
smtpConfig['LoginPasswd'] = str(self.Ui.lineEditPasswd.text()) # 判断Longinuser
isExist=smtpConfig['LoginUser'].find('@')
if isExist==-1:
smtpConfig['LoginUser'] = smtpConfig['LoginUser']+smtpConfig['Connect'].replace('smtp.', '@', 1) try:
smtp = smtplib.SMTP()
smtp.connect(smtpConfig['Connect'])
smtp.login(smtpConfig['LoginUser'], smtpConfig['LoginPasswd'])
msg = MIMEMultipart()
msg['Subject'] = str(self.Ui.lineEditCheme.text())
# 内容
content = MIMEText(str(self.Ui.textEditBody.toPlainText()), 'html', 'utf-8') # 获取textedit数据
# 附件
isExistAttach = str(self.Ui.lineEditAttach.text())
if isExistAttach: # 如果存在附件
filename = os.path.basename(isExistAttach)
attach = MIMEText(open(isExistAttach, 'rb').read(), 'base64', 'gb2312')
attach["Content-Type"] = 'application/octet-stream'
attach["Content-Disposition"] = 'attachment; filename="'+filename+'"'
msg.attach(attach) # 可能有附件没有内容 msg.attach(content)
Receiver=str(self.Ui.lineEditReceiver.text())
ListReceiver= Receiver.split(',')
smtp.sendmail(smtpConfig['LoginUser'], ListReceiver, msg.as_string()) # 发送者 和 接收人
smtp.quit()
return True except Exception, e:
QtGui.QMessageBox.warning(self, u'错误提示', str(e), QtGui.QMessageBox.Yes)
# 发送失败隐藏发送进度
self.Ui.labelSendMsg.setText(u'成功失败')
self.Ui.labelSendMsg.hide()
self.Ui.progressBarSend.hide()
return False '''
获取配置项目
'''
def basicExist(self):
if self.Ui.lineEditSMTP.text() == '':
QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写SMTP服务地址'), QtGui.QMessageBox.Yes)
return False
if self.Ui.lineEditUser.text() == '':
QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写发送者用户名'), QtGui.QMessageBox.Yes)
return False
if self.Ui.lineEditPasswd.text() == '':
QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写发送者密码'), QtGui.QMessageBox.Yes)
return False
if self.Ui.lineEditReceiver.text() == '':
QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写接收者邮箱'), QtGui.QMessageBox.Yes)
return False
if self.Ui.lineEditCheme.text() == '':
QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写邮件标题'), QtGui.QMessageBox.Yes)
return False
return True def keyPressEvent(self, event):
if event.key() ==QtCore.Qt.Key_Escape:
Ok = QtGui.QMessageBox.question(self,u'提示', u'确定要退出吗?',QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
if Ok == QtGui.QMessageBox.Yes:
self.close()
# 重写timer
def timerEvent(self,event):
if self.step >= 100:
self.timer.stop()
self.Ui.labelSendMsg.show()
self.Ui.labelSendMsg.setText(u"发送完成!")
return
self.step = self.step+1
self.Ui.progressBarSend.setValue(self.step) if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
appSendingMail = SendingMail()
appSendingMail.show()
sys.exit(app.exec_())
运行效果:
四. 问题
发送附件超过2M以上或 网速慢的时候主程序会等待相应直到邮件发送完成,解决办法:多线程实现!
多线程实现 by 2015-04-17
以上因为主进程进行通信导致Ui堵塞界面假死,想到的办法就是Qthread 多进程,
今天就实现多线程逻辑部分
# -*- coding: utf-8 -*- from PyQt4 import QtGui, QtCore
from sendmail import Ui_SendMailer
import os
import icoqrc class SendingMail(QtGui.QWidget):
def __init__(self, parent=None):
super(SendingMail, self).__init__(parent)
self.Ui = Ui_SendMailer()
self.Ui.setupUi(self)
self.setWindowTitle(u'Pyqt 邮件发送')
self.setWindowIcon(QtGui.QIcon(':myfavicon.ico'))
reload(sys)
sys.setdefaultencoding("utf-8")
#初始化UI项目
self.proparam()
# 获取配置项
self.GetConfig()
self.Ui.comboBoxServer.activated.connect(self.ServerSmtp) # stmp服务器
self.Ui.attachBtn.clicked.connect(self.SelAttach) # 选择附件
self.connect(self.Ui.sendingBtn, QtCore.SIGNAL("clicked()"), self.CoreAction) # 发送进度
self.timer = QtCore.QBasicTimer() # def初始化UI项目
def proparam(self):
self.Ui.comboBoxServer.addItem(u'选择服务地址',QtCore.QVariant(''))
self.Ui.comboBoxServer.addItem(u'网易163',QtCore.QVariant('smtp.163.com'))
self.Ui.comboBoxServer.addItem(u'腾讯邮箱',QtCore.QVariant('smtp.qq.com'))
self.Ui.comboBoxServer.addItem(u'新浪邮箱',QtCore.QVariant('smtp.sina.com.cn'))
self.Ui.comboBoxServer.addItem(u'搜狐邮箱',QtCore.QVariant('smtp.sohu.com'))
self.Ui.comboBoxServer.addItem(u'Google邮箱',QtCore.QVariant('smtp.gmail.com'))
self.Ui.comboBoxServer.addItem(u'自定义',QtCore.QVariant(''))
# 隐藏发送进度和发送提示
self.Ui.progressBarSend.hide()
self.Ui.labelSendMsg.hide()
# 记住密码配置密钥 self.keyt=0xa1a2a3a8 # stmp 服务器
def ServerSmtp(self):
comboxserver= self.Ui.comboBoxServer.currentIndex()
comboxItemData= self.Ui.comboBoxServer.itemData(comboxserver)
self.Ui.lineEditSMTP.setText(comboxItemData.toPyObject()) # 选择附件 后期判断文件大小,显示格式等
def SelAttach(self):
files = QtGui.QFileDialog.getOpenFileName(self, u'选择附件')
self.Ui.lineEditAttach.setText(files) # 配置项
def GetConfig(self, sendingSucc=''):
isConfig = os.path.exists(r'SendMailerConfig.ini')
if isConfig and sendingSucc == '': # 存在记住用户名和密码
self.Ui.checkBoxRememberUP.setChecked(True)
file = QtCore.QFile("SendMailerConfig.ini")
file.open(QtCore.QIODevice.ReadOnly)
In = QtCore.QDataStream(file)
In.setVersion(QtCore.QDataStream.Qt_4_0)
magic = In.readUInt32()
if magic != self.keyt:
QtGui.QMessageBox.information(self,"exception",u"记住密码数据格式错误!")
return
comboBoxServer = In.readUInt32()
LoginUser = In.readString()
LoginPasswd = In.readString()
self.Ui.comboBoxServer.setCurrentIndex(comboBoxServer)
comboxItemData = self.Ui.comboBoxServer.itemData(comboBoxServer)
self.Ui.lineEditSMTP.setText(comboxItemData.toPyObject())
self.Ui.lineEditUser.setText(str(LoginUser))
self.Ui.lineEditPasswd.setText(str(LoginPasswd))
# 发送成功判断记住密码
if sendingSucc:
isChecked = self.Ui.checkBoxRememberUP.isChecked()
if isChecked:
file = QtCore.QFile("SendMailerConfig.ini")
self.time = QtCore.QDateTime()
file.open(QtCore.QIODevice.WriteOnly)
out = QtCore.QDataStream(file)
out.setVersion(QtCore.QDataStream.Qt_4_0)
out.writeUInt32(self.keyt) # writeUInt32 参数为int类型
out.writeUInt32(self.Ui.comboBoxServer.currentIndex())
out.writeString(self.Ui.lineEditUser.text()) # writeString 参数为string类型
out.writeString(self.Ui.lineEditPasswd.text())
out << self.time.currentDateTime() # 发送邮件
def CoreAction(self):
validate = self.basicExist()
if validate:
# 发送进度显示
self.Ui.labelSendMsg.show()
self.Ui.labelSendMsg.setText(u'正在发送……')
self.Ui.progressBarSend.show()
self.Ui.progressBarSend.reset() # 重置进度条
self.step = 0
self.timer.start(1000, self)
DictData={}
smtpConfig = {} # 配置
smtpConfig['Connect'] = str(self.Ui.lineEditSMTP.text())
smtpConfig['LoginUser'] = str(self.Ui.lineEditUser.text())
smtpConfig['LoginPasswd'] = str(self.Ui.lineEditPasswd.text())
# 判断Longinuser
isExist=smtpConfig['LoginUser'].find('@')
if isExist==-1:
smtpConfig['LoginUser'] = smtpConfig['LoginUser']+smtpConfig['Connect'].replace('smtp.', '@', 1) DictData['smtpConfig'] = smtpConfig # 配置
DictData['Subject'] = str(self.Ui.lineEditCheme.text()) # 主题
DictData['content'] = str(self.Ui.textEditBody.toPlainText()) # 内容
DictData['attach'] = str(self.Ui.lineEditAttach.text()) # 附件
Receiver=str(self.Ui.lineEditReceiver.text())
DictData['ListReceiver'] = Receiver.split(',')
self.Theading = Theading(DictData)
self.connect(self.Theading, QtCore.SIGNAL("updateresult"), self.updateResult) # 创建一个信号,在线程状态结果时发射触发
self.Theading.start() # 线程开始
self.disconnect(self.Ui.sendingBtn, QtCore.SIGNAL("clicked()"), self.CoreAction) # 取消connect事件
self.Ui.sendingBtn.setEnabled(False) #发送邮件后,进程触发事件
def updateResult(self,status):
if status['status']==1: # 发送成功
#判断是否记住密码
self.GetConfig('sendSuccess')
self.timer.start(10, self)
else: # 发送失败
self.Ui.labelSendMsg.hide()
self.Ui.progressBarSend.hide()
QtGui.QMessageBox.warning(self, u'错误提示', status['msg'], QtGui.QMessageBox.Yes)
self.connect(self.Ui.sendingBtn, QtCore.SIGNAL("clicked()"), self.CoreAction) # connect事件
self.Ui.sendingBtn.setEnabled(True) '''
获取配置项目
'''
def basicExist(self):
if self.Ui.lineEditSMTP.text() == '':
QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写SMTP服务地址'), QtGui.QMessageBox.Yes)
return False
if self.Ui.lineEditUser.text() == '':
QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写发送者用户名'), QtGui.QMessageBox.Yes)
return False
if self.Ui.lineEditPasswd.text() == '':
QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写发送者密码'), QtGui.QMessageBox.Yes)
return False
if self.Ui.lineEditReceiver.text() == '':
QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写接收者邮箱'), QtGui.QMessageBox.Yes)
return False
if self.Ui.lineEditCheme.text() == '':
QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写邮件标题'), QtGui.QMessageBox.Yes)
return False
return True
# 重写keypress事件
def keyPressEvent(self, event):
if event.key() ==QtCore.Qt.Key_Escape:
Ok = QtGui.QMessageBox.question(self,u'提示', u'确定要退出吗?',QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
if Ok == QtGui.QMessageBox.Yes:
self.close()
# 重写timer
def timerEvent(self,event):
if self.step >= 100:
self.timer.stop()
self.Ui.labelSendMsg.show()
self.Ui.labelSendMsg.setText(u"发送完成!")
return
self.step = self.step+1
self.Ui.progressBarSend.setValue(self.step) class Theading(QtCore.QThread):
def __init__(self, dict, parent=None):
super(Theading, self).__init__(parent)
self.dict = dict
def run(self):
#引入smtplib 发送邮件
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
result={}
result['status'] = 0
result['msg'] = ''
try:
smtp = smtplib.SMTP()
smtp.connect(self.dict['smtpConfig']['Connect'])
smtp.login(self.dict['smtpConfig']['LoginUser'], self.dict['smtpConfig']['LoginPasswd'])
msg = MIMEMultipart()
msg['Subject'] = self.dict['Subject']
# 内容
content = MIMEText(self.dict['content'], 'html', 'utf-8') # 获取textedit数据
# 附件
isExistAttach =self.dict['attach']
if isExistAttach: # 如果存在附件
filename = os.path.basename(isExistAttach)
attach = MIMEText(open(isExistAttach, 'rb').read(), 'base64', 'gb2312')
attach["Content-Type"] = 'application/octet-stream'
attach["Content-Disposition"] = 'attachment; filename="'+filename+'"'
msg.attach(attach) # 可能有附件没有内容
msg.attach(content)
smtp.sendmail(self.dict['smtpConfig']['LoginUser'], self.dict['ListReceiver'], msg.as_string()) # 发送者 和 接收人
smtp.quit()
result['status'] = 1 except Exception, e:
result['msg'] = str(e) self.emit(QtCore.SIGNAL("updateresult"), result) if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
appSendingMail = SendingMail()
appSendingMail.show()
sys.exit(app.exec_())