一,开发需求和思路
1.开发需求
你是不是有这么一种需求:在使用邮箱(qq邮箱或163邮箱)时,许多时候都需要我们重新登录(或者隔一段时间),那么如果忘记密码,重新设置将是一件很痛苦的事,加之,我们对邮箱使用很频繁,能不能有种产品能使我们不用登入账户,同时桌面应用程序那样而不用去登入网页版邮箱网站,从而满足我们的发送邮件的基本功能实现呢?答案是有的! 在开源IT时代,我们有很多方法和工具来实现我们的需求,作为极客,我们可以发现SMTP协议背后的一种特殊的发送邮件过程:基于邮箱服务商服务器(IMAP,SMTP,POS3等)来绑定对应程序,从而达到免登录,二次程序开发实现邮件发送功能(简单的理解下就可以了,可以自行百度)。 文末附上这个项目的GitHub地址链接!
2.开发思路
python是具有强大第三方库的一门超级语言,我们可以选择简单且易上手的第三方库!经过笔者比对发现python的yagmail库是个不错的选择,基本配置简单且不复杂! 另外,我们的需求开发出的是产品级,那么就不能再运行时再打开代码,我们要设计出有UI交互界面的程序,由于python自带tkinter库,我们可以用来GUI开发比较方便简单。我们还可以添加程序窗口图标,添加自己喜爱的图片作为背景! 为了使程序成品能给更多用户使用,同时保证各自邮箱的安全性,我们在配置个人邮箱隐私信息时,使用的是本地手动写入配置文件ini,这样使程序成品有可移植性,并且,可以随时修改自己的邮箱配置信息!
3.前期准备
知识储备 | 备注 |
---|
面向对象编程:类和对象 | 使用类,能使程序二次开发和维护更好,并且程序代码模块化和结构明了,利于阅读和开发 | GUI开发tkinter | python自带的tkinterGUI编写,虽然总体UI界面不比主流美观,但是开发简单,且外观逻辑上能满足我们的需求 | pyinstaller | python常见且流行的打包程序库,需要下载安装 | yagmail库 | 非常好用简单的第三方库,需要下载安装 | configparser 库 | 用来管理配置文件的库,需要下载安装 | PIL库 | 通用名为Pillow 库,需要下载安装 | datetime库 | 用来获取时间 ,需要下载安装 | calendar库 | 用来生成日历形式的库 | tkinter.filedialog 模块 | tk库里的文件选择框模块 | 其他媒体文件 | 用于背景和图标等,看自己选择,可自由决定 | 邮箱网站取得密钥和其他信息 | 如果没有这些配置,邮箱程序将无法运行,务必设置好先 |
邮箱网站配置方法如下: python-基于yagmail库开发自动邮件发送程序
二,编写代码
1.代码模块
(1)MAIL.py
该MAIL.py文件主要放置MAIL类,储存主要的账户配置!
import yagmail
import configparser
import os
class MAIL:
def __init__(self):
self.config = configparser.ConfigParser()
self.config.read('MailConfig.ini')
user = self.config['DEFAULT']['user']
password =self.config['DEFAULT']['password']
port = self.config['DEFAULT']['port']
host = self.config['DEFAULT']['host']
self.mail = yagmail.SMTP(user, password, host, port)
def creatconfig(self):
self.config['DEFAULT'] = {'user': 'user',
'password': 'password',
'port': 'port',
'host': 'hosts'
}
with open('MailConfig.ini', 'w+') as configfile:
self.config.write(configfile)
def openconfig(self):
os.startfile('MailConfig.ini')
(2)MAILGUI.py
该MAILGUI.py文件(是主程序)主要放置MAILGUI类,MAILGUI类主要是GUI编写的类和导入并使用前面的MAIL类的方法。
from tkinter import *
from PIL import Image,ImageTk
from MAIL import MAIL
import datetime
import calendar
import tkinter.filedialog
class MAILGUI(MAIL):
def __init__(self):
super().__init__()
self.root = Tk()
self.root.title('基于SMTP协议自动发送的邮箱程序')
self.root.geometry('800x600+300+100')
self.root.iconbitmap('mail.ico')
self.lists=['']
self.filename = ''
photo1=Image.open('background1.png')
self.background_image1 = ImageTk.PhotoImage(photo1.resize((500, 400)))
to_label = Label(self.root, text='收件人:', font=('黑体', 13)).place(x=10, y=20)
self.to_text = Text(self.root, width=26, height=1.55, font=('黑体', 13))
self.to_text.place(x=90, y=20)
title_label = Label(self.root, text='主题:', font=('黑体', 13)).place(x=10, y=80)
self.title_text = Text(self.root, width=26, height=1.55, font=('黑体', 13))
self.title_text.place(x=90, y=80)
contents_label = Label(self.root, text='内容:', font=('黑体', 13)).place(x=10, y=140)
self.content_text = Text(self.root, width=75, height=12, font=('黑体', 13))
self.content_text.place(x=90, y=140)
attachments_button = Button(self.root, text='附件地址', font=('黑体', 13), fg='white', bg='green', command=self.Attachments,width=10, height=2, relief=RAISED)
attachments_button.place(x=30, y=370)
self.attachments_label=Label(self.root, text='暂无选择文件', font=('黑体', 9),width=80, height=3, fg='white', bg='green')
self.attachments_label.place(x=180, y=370)
check_button = Button(self.root, text='确认发送', font=('黑体', 13), fg='white', bg='green', command=self.Sendto, width=10,height=2, relief=RAISED).place(x=30, y=450)
tip_label = Label(self.root, text='程序状态:', font=('黑体', 13)).place(x=10, y=530)
self.tipout_label = Label(self.root, text='暂无操作!', font=('黑体', 13), bg='green', fg='white')
self.tipout_label.place(x=120, y=530)
self.time_label = Label(self.root, text='', font=('黑体', 16), fg='green')
self.time_label.place(x=340, y=85)
self.menubar = Menu(self.root)
self.menuout = Menu(self.root, tearoff=0)
self.root['menu'] = self.menubar
self.menubar.add_command(label="初始化配置文件 ", command=self.creatconfig)
self.menubar.add_command(label=" 打开配置文件 ", command=self.openconfig)
self.menubar.add_command(label=" 草稿 ", command=self.textbook)
self.menubar.add_command(label=" 日历 ", command=self.show_datetime)
self.root.bind("<Button-3>", self.pops)
self.menuout.add_command(label='清空收件人窗口', command=self.Clear_to)
self.menuout.add_command(label='清空主题窗口', command=self.Clear_title)
self.menuout.add_command(label='清空内容窗口', command=self.Clear_content)
self.menuout.add_command(label='清空附件地址', command=self.Clear_attachments)
self.menuout.add_command(label='清空所有输入窗口', command=self.message)
self.root.mainloop()
def Attachments(self):
self.filename = tkinter.filedialog.askopenfilename()
if self.filename != '':
self.tipout_label['text'] = '您选择了附件文件!'
self.attachments_label['text'] = '您选择的文件是' + self.filename
else:
self.tipout_label['text'] = '您没有选择任何文件!'
self.attachments_label['text'] = '您还没选择任何文件!'
def Sendto(self):
to = self.to_text.get('1.0', 'end')
title = self.title_text.get('1.0', 'end')
content = self.content_text.get('1.0', 'end')
if self.filename == '':
try:
self.mail.send(to, title, content)
self.tipout_label['text'] = "发送成功!"
except:
self.message()
elif self.filename != '':
try:
self.mail.send(to, title, content, self.filename)
self.tipout_label['text'] = "发送成功!"
except:
self.message()
def show_datetime(self):
winnew = Toplevel(self.root)
winnew.title('日历窗口')
winnew.geometry('500x400+700+50')
winnew.iconbitmap('mail.ico')
self.tipout_label['text'] = '你点开了日历窗口!'
date_time = datetime.datetime.today()
year = date_time.year
month = date_time.month
calendar.setfirstweekday(firstweekday=6)
dates = calendar.month(year, month)
alldate = Label(winnew, text='', bg='green', fg='white', width=1000, height=600, font=('黑体', 20),
image=self.background_image1, compound=CENTER)
alldate.configure(text=dates)
alldate.pack()
def textbook(self):
text_win = Toplevel(self.root)
text_win.title('草稿窗口')
text_win.geometry('740x520+500+50')
text_win.iconbitmap('mail.ico')
self.tipout_label['text'] = '你点开了草稿窗口!'
self.draft_paper = Text(text_win, width=100, height=30)
self.draft_paper.insert('1.0', self.lists[0])
save_button = Button(text_win, text='保存', command=self.saves, relief=RAISED, fg='white', bg='green', font=('黑体', 14),
width=10, height=2).place(x=19, y=430)
clear_button = Button(text_win, text='清空所有内容', command=self.clears, relief=RAISED, fg='white', bg='green',
font=('黑体', 14), width=16, height=2).place(x=150, y=430)
self.draft_paper.place(x=19, y=18)
def saves(self):
self.lists[0] = self.draft_paper.get(1.0, 'end')
self.tipout_label['text'] = "你保存了草稿箱里的内容!"
def clears(self):
self.draft_paper.delete('1.0', 'end')
self.tipout_label['text'] = "你清空了草稿箱里的内容!"
def message(self):
self.tipout_label['text'] = "输入有误或已全清空!请重新输入所有内容!"
self.to_text.delete('1.0', 'end')
self.title_text.delete('1.0', 'end')
self.content_text.delete('1.0', 'end')
self.filename=''
self.tipout_label['text']='你清空了所有输入内容!包括收件人,主题,内容,附件地址的所有输入!'
self.attachments_label['text']='您还没选择任何文件!'
def pops(self,event):
self.menuout.post(event.x_root, event.y_root)
def Clear_to(self):
self.to_text.delete('1.0', 'end')
self.tipout_label['text'] = '你清空了收件人窗口!'
def Clear_title(self):
self.title_text.delete('1.0', 'end')
self.tipout_label['text'] = '你清空了主题窗口!'
def Clear_content(self):
self.content_text.delete('1.0', 'end')
self.tipout_label['text'] = '你清空了内容窗口!'
def Clear_attachments(self):
self.filename=''
self.tipout_label['text'] = '你清除了附件地址!'
self.attachments_label['text'] = '您还没选择任何文件!'
if __name__ == '__main__':
MAILGUI()
2.开发中遇到的问题
pyinstaller打包多个py文件和去除cmd黑框 报错:ModuleNotFoundError: No module named 'PIL’解决方法 python 获取当前年份和月份 Python中tkinter.filedialog Python-Tkinter图形化界面设计(详细教程 ) 用tkinter.pack设计复杂界面布局 python-基于yagmail库开发自动邮件发送程序
三,程序打包
1.打包过程
(1)找到自己代码文件的目录,复制下来 (2)打开cmd窗口,把复制的目录复制到cmd窗口,并在前加cd,如下例所示: (3)确认已经下载安装好pyinstaller,输入如下指令:
pyinstaller -F <程序主文件>.py
(4)在生成的文件中,只保留<主程序>.spec文件,其余都删除(当然我们原来的py代码文件也在该目录下,肯定不用删除,保留就行)!如下:
(5)打开后缀为.spec文件,在Analysis中的第一行的列表,再添加我们主程序依赖和要导入的模块MAIL.py文件的字符串形式,如下图:
(6)再重新打开cmd,进入文件目录,输入以下指令: 该程序不用携带小黑框,所以要在命令后加上–noconsole语句
pyinstaller -F <主程序名>.spec --noconsole
(7)提示打包成功后,我们可以删除生成的_pycache_和build文件,只保留dist文件夹,因为这里面放置了生成exe程序,另外程序窗体要用到mail.ico文件,默认打包是不会把它移到dist文件夹的,我们要复制到dist文件下! (8)修改配置文件,如下:
2.程序功能展示及描述
程序各界面如下:
控件 | 功能描述 | 注意事项 |
---|
初始化配置文件顶层菜单选项 | 初始化配置文件,相当恢复原厂设置,一般用于要修改配置 | | 打开配置文件顶层菜单选项 | 快速自动打开配置文件 | 如果打开修改配置文件的话,保存配置文件后,需重新打开程序 ,方可正常运行 | 草稿顶层菜单选项 | 打开草稿窗口 | | 日历顶层菜单选项 | 打开日历窗口 | | 收件人输入框 | 输入收件人的信息 | | 邮件主题输入框 | 输入邮件主题 | | 邮件内容输入框 | 输入邮件内容 | | 邮件附件按钮 | 选择邮件附件,若不点击,则默认无附件 | 点击附件选择窗口后,若无选择文件,则默认无附件 | 邮件发送确认按钮 | 输入所要要发送的信息,点击可发送 | 根据系统运行环境和网络环境会,发送时会有不同程度的卡顿,但会正常运行下去的,不必奇怪 | 其他显示标签 | 显示程序操作及相关提示等 | | 草稿保存按钮 | 保存草稿窗口所输入的内容 | 保存范围在不关闭主程序窗口内,都有记忆功能 | 草稿清空按钮 | 清空草稿内容 | | 配置文件 | | 若删除,可在程序运行状态下,点击初始化配置文件按钮,即可生成 |
四,程序成品下载
为了更好地学习和分享该部分的内容,以及提供成品程序给大家直接观摩,特意放资源链接在此,供各位读者下载! 邮件发送GUI程序下载 如果大家有条件的话,可以到我的Github去看我的项目文件及代码,下面附上GitHub项目地址: Python-tool-development-pip-instruction-GUI-program 最后,由于开发经验尚浅和程序其中的一些瑕疵,希望大家理解! 对于文中内容有任何问题,欢迎批评指正!!!
|