一. 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了一下,也没找到答案。) 

二.创建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_())

运行效果:

java多线程发邮件 多线程发送邮件_c/c++

四. 问题 

发送附件超过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_())