一. 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_())
运行效果:
四. 问题
发送附件超过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_())