一. 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/xiaowuyi/archive/2012/03/17/2404015.html
二.创建Ui
sendmail.Ui
1 <?xml version="1.0" encoding="UTF-8"?> 2 <ui version="4.0"> 3 <class>SendMailer</class> 4 <widget class="QWidget" name="SendMailer"> 5 <property name="geometry"> 6 <rect> 7 <x>0</x> 8 <y>0</y> 9 <width>518</width> 10 <height>519</height> 11 </rect> 12 </property> 13 <property name="windowTitle"> 14 <string>Form</string> 15 </property> 16 <layout class="QVBoxLayout" name="verticalLayout"> 17 <item> 18 <widget class="QGroupBox" name="groupBox"> 19 <property name="minimumSize"> 20 <size> 21 <width>0</width> 22 <height>90</height> 23 </size> 24 </property> 25 <property name="maximumSize"> 26 <size> 27 <width>16777215</width> 28 <height>90</height> 29 </size> 30 </property> 31 <property name="title"> 32 <string>配置项</string> 33 </property> 34 <layout class="QVBoxLayout" name="verticalLayout_4"> 35 <item> 36 <layout class="QHBoxLayout" name="horizontalLayout_7"> 37 <item> 38 <widget class="QLabel" name="label"> 39 <property name="text"> 40 <string>服务器地址:</string> 41 </property> 42 </widget> 43 </item> 44 <item> 45 <widget class="QComboBox" name="comboBoxServer"> 46 <property name="minimumSize"> 47 <size> 48 <width>150</width> 49 <height>0</height> 50 </size> 51 </property> 52 </widget> 53 </item> 54 <item> 55 <widget class="QLineEdit" name="lineEditSMTP"> 56 <property name="text"> 57 <string>自定义</string> 58 </property> 59 </widget> 60 </item> 61 </layout> 62 </item> 63 <item> 64 <widget class="Line" name="line_4"> 65 <property name="orientation"> 66 <enum>Qt::Horizontal</enum> 67 </property> 68 </widget> 69 </item> 70 <item> 71 <layout class="QHBoxLayout" name="horizontalLayout_8"> 72 <item> 73 <widget class="QLabel" name="label_2"> 74 <property name="text"> 75 <string>用户名:</string> 76 </property> 77 </widget> 78 </item> 79 <item> 80 <widget class="QLineEdit" name="lineEditUser"> 81 <property name="inputMethodHints"> 82 <set>Qt::ImhNone</set> 83 </property> 84 </widget> 85 </item> 86 <item> 87 <widget class="Line" name="line_5"> 88 <property name="orientation"> 89 <enum>Qt::Vertical</enum> 90 </property> 91 </widget> 92 </item> 93 <item> 94 <widget class="QLabel" name="label_3"> 95 <property name="text"> 96 <string>密码:</string> 97 </property> 98 </widget> 99 </item> 100 <item> 101 <widget class="QLineEdit" name="lineEditPasswd"> 102 <property name="echoMode"> 103 <enum>QLineEdit::Password</enum> 104 </property> 105 </widget> 106 </item> 107 <item> 108 <widget class="QCheckBox" name="checkBoxRememberUP"> 109 <property name="text"> 110 <string>记住用户名密码</string> 111 </property> 112 </widget> 113 </item> 114 </layout> 115 </item> 116 </layout> 117 </widget> 118 </item> 119 <item> 120 <widget class="QGroupBox" name="groupBox_2"> 121 <property name="minimumSize"> 122 <size> 123 <width>500</width> 124 <height>0</height> 125 </size> 126 </property> 127 <property name="title"> 128 <string>内容项</string> 129 </property> 130 <layout class="QVBoxLayout" name="verticalLayout_2"> 131 <item> 132 <layout class="QHBoxLayout" name="horizontalLayout_2"> 133 <item> 134 <widget class="QLabel" name="label_5"> 135 <property name="maximumSize"> 136 <size> 137 <width>16777215</width> 138 <height>16777215</height> 139 </size> 140 </property> 141 <property name="text"> 142 <string>接收人: </string> 143 </property> 144 </widget> 145 </item> 146 <item> 147 <widget class="QLineEdit" name="lineEditReceiver"/> 148 </item> 149 <item> 150 <widget class="QLabel" name="label_6"> 151 <property name="text"> 152 <string>多个用, 分隔开</string> 153 </property> 154 </widget> 155 </item> 156 </layout> 157 </item> 158 <item> 159 <widget class="Line" name="line"> 160 <property name="orientation"> 161 <enum>Qt::Horizontal</enum> 162 </property> 163 </widget> 164 </item> 165 <item> 166 <layout class="QHBoxLayout" name="horizontalLayout_3"> 167 <item> 168 <widget class="QLabel" name="label_7"> 169 <property name="text"> 170 <string>邮件主题:</string> 171 </property> 172 </widget> 173 </item> 174 <item> 175 <widget class="QLineEdit" name="lineEditCheme"/> 176 </item> 177 </layout> 178 </item> 179 <item> 180 <widget class="Line" name="line_3"> 181 <property name="orientation"> 182 <enum>Qt::Horizontal</enum> 183 </property> 184 </widget> 185 </item> 186 <item> 187 <layout class="QVBoxLayout" name="verticalLayout_3"> 188 <item> 189 <widget class="QLabel" name="label_8"> 190 <property name="text"> 191 <string>邮件正文:</string> 192 </property> 193 </widget> 194 </item> 195 <item> 196 <widget class="QTextEdit" name="textEditBody"/> 197 </item> 198 <item> 199 <layout class="QHBoxLayout" name="horizontalLayout_4"> 200 <item> 201 <widget class="QLabel" name="label_4"> 202 <property name="text"> 203 <string>邮件附件:</string> 204 </property> 205 </widget> 206 </item> 207 <item> 208 <widget class="QPushButton" name="attachBtn"> 209 <property name="text"> 210 <string>选择附件</string> 211 </property> 212 </widget> 213 </item> 214 <item> 215 <widget class="QLineEdit" name="lineEditAttach"/> 216 </item> 217 </layout> 218 </item> 219 </layout> 220 </item> 221 </layout> 222 </widget> 223 </item> 224 <item> 225 <layout class="QHBoxLayout" name="horizontalLayout_6"> 226 <item> 227 <widget class="QProgressBar" name="progressBarSend"> 228 <property name="value"> 229 <number>24</number> 230 </property> 231 </widget> 232 </item> 233 <item> 234 <widget class="QLabel" name="labelSendMsg"> 235 <property name="minimumSize"> 236 <size> 237 <width>71</width> 238 <height>0</height> 239 </size> 240 </property> 241 <property name="text"> 242 <string> 发送消息</string> 243 </property> 244 </widget> 245 </item> 246 <item> 247 <spacer name="horizontalSpacer_2"> 248 <property name="orientation"> 249 <enum>Qt::Horizontal</enum> 250 </property> 251 <property name="sizeHint" stdset="0"> 252 <size> 253 <width>40</width> 254 <height>20</height> 255 </size> 256 </property> 257 </spacer> 258 </item> 259 <item> 260 <widget class="QPushButton" name="sendingBtn"> 261 <property name="text"> 262 <string>开始发送</string> 263 </property> 264 </widget> 265 </item> 266 </layout> 267 </item> 268 </layout> 269 </widget> 270 <resources/> 271 <connections/> 272 </ui>
转换为sendmail.py
1 # -*- coding: utf-8 -*- 2 3 # Form implementation generated from reading ui file 'sendmail.ui' 4 # 5 # Created: Thu Mar 05 17:49:53 2015 6 # by: PyQt4 UI code generator 4.10.3 7 # 8 # WARNING! All changes made in this file will be lost! 9 10 from PyQt4 import QtCore, QtGui 11 12 try: 13 _fromUtf8 = QtCore.QString.fromUtf8 14 except AttributeError: 15 def _fromUtf8(s): 16 return s 17 18 try: 19 _encoding = QtGui.QApplication.UnicodeUTF8 20 def _translate(context, text, disambig): 21 return QtGui.QApplication.translate(context, text, disambig, _encoding) 22 except AttributeError: 23 def _translate(context, text, disambig): 24 return QtGui.QApplication.translate(context, text, disambig) 25 26 class Ui_SendMailer(object): 27 def setupUi(self, SendMailer): 28 SendMailer.setObjectName(_fromUtf8("SendMailer")) 29 SendMailer.resize(518, 519) 30 self.verticalLayout = QtGui.QVBoxLayout(SendMailer) 31 self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) 32 self.groupBox = QtGui.QGroupBox(SendMailer) 33 self.groupBox.setMinimumSize(QtCore.QSize(0, 90)) 34 self.groupBox.setMaximumSize(QtCore.QSize(16777215, 90)) 35 self.groupBox.setObjectName(_fromUtf8("groupBox")) 36 self.verticalLayout_4 = QtGui.QVBoxLayout(self.groupBox) 37 self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4")) 38 self.horizontalLayout_7 = QtGui.QHBoxLayout() 39 self.horizontalLayout_7.setObjectName(_fromUtf8("horizontalLayout_7")) 40 self.label = QtGui.QLabel(self.groupBox) 41 self.label.setObjectName(_fromUtf8("label")) 42 self.horizontalLayout_7.addWidget(self.label) 43 self.comboBoxServer = QtGui.QComboBox(self.groupBox) 44 self.comboBoxServer.setMinimumSize(QtCore.QSize(150, 0)) 45 self.comboBoxServer.setObjectName(_fromUtf8("comboBoxServer")) 46 self.horizontalLayout_7.addWidget(self.comboBoxServer) 47 self.lineEditSMTP = QtGui.QLineEdit(self.groupBox) 48 self.lineEditSMTP.setObjectName(_fromUtf8("lineEditSMTP")) 49 self.horizontalLayout_7.addWidget(self.lineEditSMTP) 50 self.verticalLayout_4.addLayout(self.horizontalLayout_7) 51 self.line_4 = QtGui.QFrame(self.groupBox) 52 self.line_4.setFrameShape(QtGui.QFrame.HLine) 53 self.line_4.setFrameShadow(QtGui.QFrame.Sunken) 54 self.line_4.setObjectName(_fromUtf8("line_4")) 55 self.verticalLayout_4.addWidget(self.line_4) 56 self.horizontalLayout_8 = QtGui.QHBoxLayout() 57 self.horizontalLayout_8.setObjectName(_fromUtf8("horizontalLayout_8")) 58 self.label_2 = QtGui.QLabel(self.groupBox) 59 self.label_2.setObjectName(_fromUtf8("label_2")) 60 self.horizontalLayout_8.addWidget(self.label_2) 61 self.lineEditUser = QtGui.QLineEdit(self.groupBox) 62 self.lineEditUser.setInputMethodHints(QtCore.Qt.ImhNone) 63 self.lineEditUser.setObjectName(_fromUtf8("lineEditUser")) 64 self.horizontalLayout_8.addWidget(self.lineEditUser) 65 self.line_5 = QtGui.QFrame(self.groupBox) 66 self.line_5.setFrameShape(QtGui.QFrame.VLine) 67 self.line_5.setFrameShadow(QtGui.QFrame.Sunken) 68 self.line_5.setObjectName(_fromUtf8("line_5")) 69 self.horizontalLayout_8.addWidget(self.line_5) 70 self.label_3 = QtGui.QLabel(self.groupBox) 71 self.label_3.setObjectName(_fromUtf8("label_3")) 72 self.horizontalLayout_8.addWidget(self.label_3) 73 self.lineEditPasswd = QtGui.QLineEdit(self.groupBox) 74 self.lineEditPasswd.setEchoMode(QtGui.QLineEdit.Password) 75 self.lineEditPasswd.setObjectName(_fromUtf8("lineEditPasswd")) 76 self.horizontalLayout_8.addWidget(self.lineEditPasswd) 77 self.checkBoxRememberUP = QtGui.QCheckBox(self.groupBox) 78 self.checkBoxRememberUP.setObjectName(_fromUtf8("checkBoxRememberUP")) 79 self.horizontalLayout_8.addWidget(self.checkBoxRememberUP) 80 self.verticalLayout_4.addLayout(self.horizontalLayout_8) 81 self.verticalLayout.addWidget(self.groupBox) 82 self.groupBox_2 = QtGui.QGroupBox(SendMailer) 83 self.groupBox_2.setMinimumSize(QtCore.QSize(500, 0)) 84 self.groupBox_2.setObjectName(_fromUtf8("groupBox_2")) 85 self.verticalLayout_2 = QtGui.QVBoxLayout(self.groupBox_2) 86 self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) 87 self.horizontalLayout_2 = QtGui.QHBoxLayout() 88 self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) 89 self.label_5 = QtGui.QLabel(self.groupBox_2) 90 self.label_5.setMaximumSize(QtCore.QSize(16777215, 16777215)) 91 self.label_5.setObjectName(_fromUtf8("label_5")) 92 self.horizontalLayout_2.addWidget(self.label_5) 93 self.lineEditReceiver = QtGui.QLineEdit(self.groupBox_2) 94 self.lineEditReceiver.setObjectName(_fromUtf8("lineEditReceiver")) 95 self.horizontalLayout_2.addWidget(self.lineEditReceiver) 96 self.label_6 = QtGui.QLabel(self.groupBox_2) 97 self.label_6.setObjectName(_fromUtf8("label_6")) 98 self.horizontalLayout_2.addWidget(self.label_6) 99 self.verticalLayout_2.addLayout(self.horizontalLayout_2) 100 self.line = QtGui.QFrame(self.groupBox_2) 101 self.line.setFrameShape(QtGui.QFrame.HLine) 102 self.line.setFrameShadow(QtGui.QFrame.Sunken) 103 self.line.setObjectName(_fromUtf8("line")) 104 self.verticalLayout_2.addWidget(self.line) 105 self.horizontalLayout_3 = QtGui.QHBoxLayout() 106 self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3")) 107 self.label_7 = QtGui.QLabel(self.groupBox_2) 108 self.label_7.setObjectName(_fromUtf8("label_7")) 109 self.horizontalLayout_3.addWidget(self.label_7) 110 self.lineEditCheme = QtGui.QLineEdit(self.groupBox_2) 111 self.lineEditCheme.setObjectName(_fromUtf8("lineEditCheme")) 112 self.horizontalLayout_3.addWidget(self.lineEditCheme) 113 self.verticalLayout_2.addLayout(self.horizontalLayout_3) 114 self.line_3 = QtGui.QFrame(self.groupBox_2) 115 self.line_3.setFrameShape(QtGui.QFrame.HLine) 116 self.line_3.setFrameShadow(QtGui.QFrame.Sunken) 117 self.line_3.setObjectName(_fromUtf8("line_3")) 118 self.verticalLayout_2.addWidget(self.line_3) 119 self.verticalLayout_3 = QtGui.QVBoxLayout() 120 self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) 121 self.label_8 = QtGui.QLabel(self.groupBox_2) 122 self.label_8.setObjectName(_fromUtf8("label_8")) 123 self.verticalLayout_3.addWidget(self.label_8) 124 self.textEditBody = QtGui.QTextEdit(self.groupBox_2) 125 self.textEditBody.setObjectName(_fromUtf8("textEditBody")) 126 self.verticalLayout_3.addWidget(self.textEditBody) 127 self.horizontalLayout_4 = QtGui.QHBoxLayout() 128 self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4")) 129 self.label_4 = QtGui.QLabel(self.groupBox_2) 130 self.label_4.setObjectName(_fromUtf8("label_4")) 131 self.horizontalLayout_4.addWidget(self.label_4) 132 self.attachBtn = QtGui.QPushButton(self.groupBox_2) 133 self.attachBtn.setObjectName(_fromUtf8("attachBtn")) 134 self.horizontalLayout_4.addWidget(self.attachBtn) 135 self.lineEditAttach = QtGui.QLineEdit(self.groupBox_2) 136 self.lineEditAttach.setObjectName(_fromUtf8("lineEditAttach")) 137 self.horizontalLayout_4.addWidget(self.lineEditAttach) 138 self.verticalLayout_3.addLayout(self.horizontalLayout_4) 139 self.verticalLayout_2.addLayout(self.verticalLayout_3) 140 self.verticalLayout.addWidget(self.groupBox_2) 141 self.horizontalLayout_6 = QtGui.QHBoxLayout() 142 self.horizontalLayout_6.setObjectName(_fromUtf8("horizontalLayout_6")) 143 self.progressBarSend = QtGui.QProgressBar(SendMailer) 144 self.progressBarSend.setProperty("value", 24) 145 self.progressBarSend.setObjectName(_fromUtf8("progressBarSend")) 146 self.horizontalLayout_6.addWidget(self.progressBarSend) 147 self.labelSendMsg = QtGui.QLabel(SendMailer) 148 self.labelSendMsg.setMinimumSize(QtCore.QSize(71, 0)) 149 self.labelSendMsg.setObjectName(_fromUtf8("labelSendMsg")) 150 self.horizontalLayout_6.addWidget(self.labelSendMsg) 151 spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) 152 self.horizontalLayout_6.addItem(spacerItem) 153 self.sendingBtn = QtGui.QPushButton(SendMailer) 154 self.sendingBtn.setObjectName(_fromUtf8("sendingBtn")) 155 self.horizontalLayout_6.addWidget(self.sendingBtn) 156 self.verticalLayout.addLayout(self.horizontalLayout_6) 157 158 self.retranslateUi(SendMailer) 159 QtCore.QMetaObject.connectSlotsByName(SendMailer) 160 161 def retranslateUi(self, SendMailer): 162 SendMailer.setWindowTitle(_translate("SendMailer", "Form", None)) 163 self.groupBox.setTitle(_translate("SendMailer", "配置项", None)) 164 self.label.setText(_translate("SendMailer", "服务器地址:", None)) 165 self.lineEditSMTP.setText(_translate("SendMailer", "自定义", None)) 166 self.label_2.setText(_translate("SendMailer", "用户名:", None)) 167 self.label_3.setText(_translate("SendMailer", "密码:", None)) 168 self.checkBoxRememberUP.setText(_translate("SendMailer", "记住用户名密码", None)) 169 self.groupBox_2.setTitle(_translate("SendMailer", "内容项", None)) 170 self.label_5.setText(_translate("SendMailer", "接收人: ", None)) 171 self.label_6.setText(_translate("SendMailer", "多个用, 分隔开", None)) 172 self.label_7.setText(_translate("SendMailer", "邮件主题:", None)) 173 self.label_8.setText(_translate("SendMailer", "邮件正文:", None)) 174 self.label_4.setText(_translate("SendMailer", "邮件附件:", None)) 175 self.attachBtn.setText(_translate("SendMailer", "选择附件", None)) 176 self.labelSendMsg.setText(_translate("SendMailer", " 发送消息", None)) 177 self.sendingBtn.setText(_translate("SendMailer", "开始发送", None)) 178 179 180 if __name__ == "__main__": 181 import sys 182 app = QtGui.QApplication(sys.argv) 183 SendMailer = QtGui.QWidget() 184 ui = Ui_SendMailer() 185 ui.setupUi(SendMailer) 186 SendMailer.show() 187 sys.exit(app.exec_())
三. 逻辑的实现
MainSendMailer.py
1 # -*- coding: utf-8 -*- 2 3 4 from PyQt4 import QtGui, QtCore 5 from sendmail import Ui_SendMailer 6 import os 7 import icoqrc 8 9 10 class SendingMail(QtGui.QWidget): 11 def __init__(self, parent=None): 12 super(SendingMail, self).__init__(parent) 13 self.Ui= Ui_SendMailer() 14 self.Ui.setupUi(self) 15 self.setWindowTitle(u'Pyqt 邮件发送') 16 self.setWindowIcon(QtGui.QIcon(':myfavicon.ico')) 17 reload(sys) 18 sys.setdefaultencoding("utf-8") 19 #初始化UI项目 20 self.proparam() 21 # 获取配置项 22 self.GetConfig() 23 self.Ui.comboBoxServer.activated.connect(self.ServerSmtp) # stmp服务器 24 self.Ui.attachBtn.clicked.connect(self.SelAttach) # 选择附件 25 self.connect(self.Ui.sendingBtn,QtCore.SIGNAL("clicked()"), self.sending) 26 27 # 发送进度 28 self.timer = QtCore.QBasicTimer() 29 30 31 32 # def初始化UI项目 33 def proparam(self): 34 self.Ui.comboBoxServer.addItem(u'选择服务地址',QtCore.QVariant('')) 35 self.Ui.comboBoxServer.addItem(u'网易163',QtCore.QVariant('smtp.163.com')) 36 self.Ui.comboBoxServer.addItem(u'腾讯邮箱',QtCore.QVariant('smtp.qq.com')) 37 self.Ui.comboBoxServer.addItem(u'新浪邮箱',QtCore.QVariant('smtp.sina.com.cn')) 38 self.Ui.comboBoxServer.addItem(u'搜狐邮箱',QtCore.QVariant('smtp.sohu.com')) 39 self.Ui.comboBoxServer.addItem(u'Google邮箱',QtCore.QVariant('smtp.gmail.com')) 40 self.Ui.comboBoxServer.addItem(u'自定义',QtCore.QVariant('')) 41 # 隐藏发送进度和发送提示 42 self.Ui.progressBarSend.hide() 43 self.Ui.labelSendMsg.hide() 44 # 记住密码配置密钥 45 46 self.keyt=0xa1a2a3a8 47 48 # stmp 服务器 49 def ServerSmtp(self): 50 comboxserver= self.Ui.comboBoxServer.currentIndex() 51 comboxItemData= self.Ui.comboBoxServer.itemData(comboxserver) 52 self.Ui.lineEditSMTP.setText(comboxItemData.toPyObject()) 53 54 # 选择附件 后期判断文件大小,显示格式等 55 def SelAttach(self): 56 files = QtGui.QFileDialog.getOpenFileName(self, u'选择附件') 57 self.Ui.lineEditAttach.setText(files) 58 59 # 配置项 60 def GetConfig(self, sendingSucc=''): 61 isConfig = os.path.exists(r'SendMailerConfig.ini') 62 if isConfig and sendingSucc == '': # 存在记住用户名和密码 63 self.Ui.checkBoxRememberUP.setChecked(True) 64 file = QtCore.QFile("SendMailerConfig.ini") 65 file.open(QtCore.QIODevice.ReadOnly) 66 In = QtCore.QDataStream(file) 67 In.setVersion(QtCore.QDataStream.Qt_4_0) 68 magic = In.readUInt32() 69 if magic != self.keyt: 70 QtGui.QMessageBox.information(self,"exception",u"记住密码数据格式错误!") 71 return 72 comboBoxServer = In.readUInt32() 73 LoginUser = In.readString() 74 LoginPasswd = In.readString() 75 self.Ui.comboBoxServer.setCurrentIndex(comboBoxServer) 76 comboxItemData = self.Ui.comboBoxServer.itemData(comboBoxServer) 77 self.Ui.lineEditSMTP.setText(comboxItemData.toPyObject()) 78 self.Ui.lineEditUser.setText(str(LoginUser)) 79 self.Ui.lineEditPasswd.setText(str(LoginPasswd)) 80 # 发送成功判断记住密码 81 if sendingSucc: 82 isChecked = self.Ui.checkBoxRememberUP.isChecked() 83 if isChecked: 84 file = QtCore.QFile("SendMailerConfig.ini") 85 self.time = QtCore.QDateTime() 86 file.open(QtCore.QIODevice.WriteOnly) 87 out = QtCore.QDataStream(file) 88 out.setVersion(QtCore.QDataStream.Qt_4_0) 89 out.writeUInt32(self.keyt) # writeUInt32 参数为int类型 90 out.writeUInt32(self.Ui.comboBoxServer.currentIndex()) 91 out.writeString(self.Ui.lineEditUser.text()) # writeString 参数为string类型 92 out.writeString(self.Ui.lineEditPasswd.text()) 93 out << self.time.currentDateTime() 94 95 # 发送邮件 96 def sending(self): 97 exist = self.basicExist() 98 if exist: 99 success = self.CoreAction() 100 if success: 101 #判断是否记住密码 102 self.GetConfig('sendSuccess') 103 self.timer.start(10, self) 104 105 # 引入smtplib 发送邮件 106 def CoreAction(self): 107 import smtplib 108 from email.mime.text import MIMEText 109 from email.mime.multipart import MIMEMultipart 110 # 发送进度显示 111 self.Ui.labelSendMsg.show() 112 self.Ui.labelSendMsg.setText(u'正在发送……') 113 self.Ui.progressBarSend.show() 114 self.step = 0 115 self.timer.start(1000, self) 116 117 118 119 smtpConfig = {} # 配置 120 smtpConfig['Connect'] = str(self.Ui.lineEditSMTP.text()) 121 smtpConfig['LoginUser'] = str(self.Ui.lineEditUser.text()) 122 smtpConfig['LoginPasswd'] = str(self.Ui.lineEditPasswd.text()) 123 124 # 判断Longinuser 125 isExist=smtpConfig['LoginUser'].find('@') 126 if isExist==-1: 127 smtpConfig['LoginUser'] = smtpConfig['LoginUser']+smtpConfig['Connect'].replace('smtp.', '@', 1) 128 129 130 131 try: 132 smtp = smtplib.SMTP() 133 smtp.connect(smtpConfig['Connect']) 134 smtp.login(smtpConfig['LoginUser'], smtpConfig['LoginPasswd']) 135 msg = MIMEMultipart() 136 msg['Subject'] = str(self.Ui.lineEditCheme.text()) 137 # 内容 138 content = MIMEText(str(self.Ui.textEditBody.toPlainText()), 'html', 'utf-8') # 获取textedit数据 139 # 附件 140 isExistAttach = str(self.Ui.lineEditAttach.text()) 141 if isExistAttach: # 如果存在附件 142 filename = os.path.basename(isExistAttach) 143 attach = MIMEText(open(isExistAttach, 'rb').read(), 'base64', 'gb2312') 144 attach["Content-Type"] = 'application/octet-stream' 145 attach["Content-Disposition"] = 'attachment; filename="'+filename+'"' 146 msg.attach(attach) # 可能有附件没有内容 147 148 msg.attach(content) 149 Receiver=str(self.Ui.lineEditReceiver.text()) 150 ListReceiver= Receiver.split(',') 151 smtp.sendmail(smtpConfig['LoginUser'], ListReceiver, msg.as_string()) # 发送者 和 接收人 152 smtp.quit() 153 return True 154 155 except Exception, e: 156 QtGui.QMessageBox.warning(self, u'错误提示', str(e), QtGui.QMessageBox.Yes) 157 # 发送失败隐藏发送进度 158 self.Ui.labelSendMsg.setText(u'成功失败') 159 self.Ui.labelSendMsg.hide() 160 self.Ui.progressBarSend.hide() 161 return False 162 163 164 ''' 165 获取配置项目 166 ''' 167 def basicExist(self): 168 if self.Ui.lineEditSMTP.text() == '': 169 QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写SMTP服务地址'), QtGui.QMessageBox.Yes) 170 return False 171 if self.Ui.lineEditUser.text() == '': 172 QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写发送者用户名'), QtGui.QMessageBox.Yes) 173 return False 174 if self.Ui.lineEditPasswd.text() == '': 175 QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写发送者密码'), QtGui.QMessageBox.Yes) 176 return False 177 if self.Ui.lineEditReceiver.text() == '': 178 QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写接收者邮箱'), QtGui.QMessageBox.Yes) 179 return False 180 if self.Ui.lineEditCheme.text() == '': 181 QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写邮件标题'), QtGui.QMessageBox.Yes) 182 return False 183 return True 184 185 def keyPressEvent(self, event): 186 if event.key() ==QtCore.Qt.Key_Escape: 187 Ok = QtGui.QMessageBox.question(self,u'提示', u'确定要退出吗?',QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) 188 if Ok == QtGui.QMessageBox.Yes: 189 self.close() 190 # 重写timer 191 def timerEvent(self,event): 192 if self.step >= 100: 193 self.timer.stop() 194 self.Ui.labelSendMsg.show() 195 self.Ui.labelSendMsg.setText(u"发送完成!") 196 return 197 self.step = self.step+1 198 self.Ui.progressBarSend.setValue(self.step) 199 200 201 202 if __name__ == '__main__': 203 import sys 204 app = QtGui.QApplication(sys.argv) 205 appSendingMail = SendingMail() 206 appSendingMail.show() 207 sys.exit(app.exec_())
运行效果:
四. 问题
发送附件超过2M以上或 网速慢的时候主程序会等待相应直到邮件发送完成,解决办法:多线程实现!
多线程实现 by 2015-04-17
以上因为主进程进行通信导致Ui堵塞界面假死,想到的办法就是Qthread 多进程,
今天就实现多线程逻辑部分
1 # -*- coding: utf-8 -*- 2 3 4 from PyQt4 import QtGui, QtCore 5 from sendmail import Ui_SendMailer 6 import os 7 import icoqrc 8 9 10 class SendingMail(QtGui.QWidget): 11 def __init__(self, parent=None): 12 super(SendingMail, self).__init__(parent) 13 self.Ui = Ui_SendMailer() 14 self.Ui.setupUi(self) 15 self.setWindowTitle(u'Pyqt 邮件发送') 16 self.setWindowIcon(QtGui.QIcon(':myfavicon.ico')) 17 reload(sys) 18 sys.setdefaultencoding("utf-8") 19 #初始化UI项目 20 self.proparam() 21 # 获取配置项 22 self.GetConfig() 23 self.Ui.comboBoxServer.activated.connect(self.ServerSmtp) # stmp服务器 24 self.Ui.attachBtn.clicked.connect(self.SelAttach) # 选择附件 25 self.connect(self.Ui.sendingBtn, QtCore.SIGNAL("clicked()"), self.CoreAction) 26 27 # 发送进度 28 self.timer = QtCore.QBasicTimer() 29 30 31 32 33 34 35 36 37 # def初始化UI项目 38 def proparam(self): 39 self.Ui.comboBoxServer.addItem(u'选择服务地址',QtCore.QVariant('')) 40 self.Ui.comboBoxServer.addItem(u'网易163',QtCore.QVariant('smtp.163.com')) 41 self.Ui.comboBoxServer.addItem(u'腾讯邮箱',QtCore.QVariant('smtp.qq.com')) 42 self.Ui.comboBoxServer.addItem(u'新浪邮箱',QtCore.QVariant('smtp.sina.com.cn')) 43 self.Ui.comboBoxServer.addItem(u'搜狐邮箱',QtCore.QVariant('smtp.sohu.com')) 44 self.Ui.comboBoxServer.addItem(u'Google邮箱',QtCore.QVariant('smtp.gmail.com')) 45 self.Ui.comboBoxServer.addItem(u'自定义',QtCore.QVariant('')) 46 # 隐藏发送进度和发送提示 47 self.Ui.progressBarSend.hide() 48 self.Ui.labelSendMsg.hide() 49 # 记住密码配置密钥 50 51 self.keyt=0xa1a2a3a8 52 53 # stmp 服务器 54 def ServerSmtp(self): 55 comboxserver= self.Ui.comboBoxServer.currentIndex() 56 comboxItemData= self.Ui.comboBoxServer.itemData(comboxserver) 57 self.Ui.lineEditSMTP.setText(comboxItemData.toPyObject()) 58 59 # 选择附件 后期判断文件大小,显示格式等 60 def SelAttach(self): 61 files = QtGui.QFileDialog.getOpenFileName(self, u'选择附件') 62 self.Ui.lineEditAttach.setText(files) 63 64 # 配置项 65 def GetConfig(self, sendingSucc=''): 66 isConfig = os.path.exists(r'SendMailerConfig.ini') 67 if isConfig and sendingSucc == '': # 存在记住用户名和密码 68 self.Ui.checkBoxRememberUP.setChecked(True) 69 file = QtCore.QFile("SendMailerConfig.ini") 70 file.open(QtCore.QIODevice.ReadOnly) 71 In = QtCore.QDataStream(file) 72 In.setVersion(QtCore.QDataStream.Qt_4_0) 73 magic = In.readUInt32() 74 if magic != self.keyt: 75 QtGui.QMessageBox.information(self,"exception",u"记住密码数据格式错误!") 76 return 77 comboBoxServer = In.readUInt32() 78 LoginUser = In.readString() 79 LoginPasswd = In.readString() 80 self.Ui.comboBoxServer.setCurrentIndex(comboBoxServer) 81 comboxItemData = self.Ui.comboBoxServer.itemData(comboBoxServer) 82 self.Ui.lineEditSMTP.setText(comboxItemData.toPyObject()) 83 self.Ui.lineEditUser.setText(str(LoginUser)) 84 self.Ui.lineEditPasswd.setText(str(LoginPasswd)) 85 # 发送成功判断记住密码 86 if sendingSucc: 87 isChecked = self.Ui.checkBoxRememberUP.isChecked() 88 if isChecked: 89 file = QtCore.QFile("SendMailerConfig.ini") 90 self.time = QtCore.QDateTime() 91 file.open(QtCore.QIODevice.WriteOnly) 92 out = QtCore.QDataStream(file) 93 out.setVersion(QtCore.QDataStream.Qt_4_0) 94 out.writeUInt32(self.keyt) # writeUInt32 参数为int类型 95 out.writeUInt32(self.Ui.comboBoxServer.currentIndex()) 96 out.writeString(self.Ui.lineEditUser.text()) # writeString 参数为string类型 97 out.writeString(self.Ui.lineEditPasswd.text()) 98 out << self.time.currentDateTime() 99 100 # 发送邮件 101 def CoreAction(self): 102 validate = self.basicExist() 103 if validate: 104 # 发送进度显示 105 self.Ui.labelSendMsg.show() 106 self.Ui.labelSendMsg.setText(u'正在发送……') 107 self.Ui.progressBarSend.show() 108 self.Ui.progressBarSend.reset() # 重置进度条 109 self.step = 0 110 self.timer.start(1000, self) 111 DictData={} 112 smtpConfig = {} # 配置 113 smtpConfig['Connect'] = str(self.Ui.lineEditSMTP.text()) 114 smtpConfig['LoginUser'] = str(self.Ui.lineEditUser.text()) 115 smtpConfig['LoginPasswd'] = str(self.Ui.lineEditPasswd.text()) 116 # 判断Longinuser 117 isExist=smtpConfig['LoginUser'].find('@') 118 if isExist==-1: 119 smtpConfig['LoginUser'] = smtpConfig['LoginUser']+smtpConfig['Connect'].replace('smtp.', '@', 1) 120 121 DictData['smtpConfig'] = smtpConfig # 配置 122 DictData['Subject'] = str(self.Ui.lineEditCheme.text()) # 主题 123 DictData['content'] = str(self.Ui.textEditBody.toPlainText()) # 内容 124 DictData['attach'] = str(self.Ui.lineEditAttach.text()) # 附件 125 Receiver=str(self.Ui.lineEditReceiver.text()) 126 DictData['ListReceiver'] = Receiver.split(',') 127 self.Theading = Theading(DictData) 128 self.connect(self.Theading, QtCore.SIGNAL("updateresult"), self.updateResult) # 创建一个信号,在线程状态结果时发射触发 129 self.Theading.start() # 线程开始 130 self.disconnect(self.Ui.sendingBtn, QtCore.SIGNAL("clicked()"), self.CoreAction) # 取消connect事件 131 self.Ui.sendingBtn.setEnabled(False) 132 133 #发送邮件后,进程触发事件 134 def updateResult(self,status): 135 if status['status']==1: # 发送成功 136 #判断是否记住密码 137 self.GetConfig('sendSuccess') 138 self.timer.start(10, self) 139 else: # 发送失败 140 self.Ui.labelSendMsg.hide() 141 self.Ui.progressBarSend.hide() 142 QtGui.QMessageBox.warning(self, u'错误提示', status['msg'], QtGui.QMessageBox.Yes) 143 self.connect(self.Ui.sendingBtn, QtCore.SIGNAL("clicked()"), self.CoreAction) # connect事件 144 self.Ui.sendingBtn.setEnabled(True) 145 146 147 148 ''' 149 获取配置项目 150 ''' 151 def basicExist(self): 152 if self.Ui.lineEditSMTP.text() == '': 153 QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写SMTP服务地址'), QtGui.QMessageBox.Yes) 154 return False 155 if self.Ui.lineEditUser.text() == '': 156 QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写发送者用户名'), QtGui.QMessageBox.Yes) 157 return False 158 if self.Ui.lineEditPasswd.text() == '': 159 QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写发送者密码'), QtGui.QMessageBox.Yes) 160 return False 161 if self.Ui.lineEditReceiver.text() == '': 162 QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写接收者邮箱'), QtGui.QMessageBox.Yes) 163 return False 164 if self.Ui.lineEditCheme.text() == '': 165 QtGui.QMessageBox.warning(self, (u'提示'),(u'请填写邮件标题'), QtGui.QMessageBox.Yes) 166 return False 167 return True 168 # 重写keypress事件 169 def keyPressEvent(self, event): 170 if event.key() ==QtCore.Qt.Key_Escape: 171 Ok = QtGui.QMessageBox.question(self,u'提示', u'确定要退出吗?',QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) 172 if Ok == QtGui.QMessageBox.Yes: 173 self.close() 174 # 重写timer 175 def timerEvent(self,event): 176 if self.step >= 100: 177 self.timer.stop() 178 self.Ui.labelSendMsg.show() 179 self.Ui.labelSendMsg.setText(u"发送完成!") 180 return 181 self.step = self.step+1 182 self.Ui.progressBarSend.setValue(self.step) 183 184 185 186 class Theading(QtCore.QThread): 187 def __init__(self, dict, parent=None): 188 super(Theading, self).__init__(parent) 189 self.dict = dict 190 def run(self): 191 #引入smtplib 发送邮件 192 import smtplib 193 from email.mime.text import MIMEText 194 from email.mime.multipart import MIMEMultipart 195 result={} 196 result['status'] = 0 197 result['msg'] = '' 198 try: 199 smtp = smtplib.SMTP() 200 smtp.connect(self.dict['smtpConfig']['Connect']) 201 smtp.login(self.dict['smtpConfig']['LoginUser'], self.dict['smtpConfig']['LoginPasswd']) 202 msg = MIMEMultipart() 203 msg['Subject'] = self.dict['Subject'] 204 # 内容 205 content = MIMEText(self.dict['content'], 'html', 'utf-8') # 获取textedit数据 206 # 附件 207 isExistAttach =self.dict['attach'] 208 if isExistAttach: # 如果存在附件 209 filename = os.path.basename(isExistAttach) 210 attach = MIMEText(open(isExistAttach, 'rb').read(), 'base64', 'gb2312') 211 attach["Content-Type"] = 'application/octet-stream' 212 attach["Content-Disposition"] = 'attachment; filename="'+filename+'"' 213 msg.attach(attach) # 可能有附件没有内容 214 msg.attach(content) 215 smtp.sendmail(self.dict['smtpConfig']['LoginUser'], self.dict['ListReceiver'], msg.as_string()) # 发送者 和 接收人 216 smtp.quit() 217 result['status'] = 1 218 219 except Exception, e: 220 result['msg'] = str(e) 221 222 self.emit(QtCore.SIGNAL("updateresult"), result) 223 224 if __name__ == '__main__': 225 import sys 226 app = QtGui.QApplication(sys.argv) 227 appSendingMail = SendingMail() 228 appSendingMail.show() 229 sys.exit(app.exec_())