current position:Home>Python application tool development: mail sending GUI program

Python application tool development: mail sending GUI program

2022-05-15 05:56:43SteveDraw

One , Development needs and ideas

1. Development requirements

Do you have such a need : Using mailbox (qq Email or 163 mailbox ) when , Many times we need to log in again ( Or at intervals ), So if you forget your password , Resetting will be a painful thing , Combined with the , We use email very often , Can there be a product that allows us not to log in to our account , At the same time, like desktop applications, you don't have to log in to the web mailbox website , So as to meet our basic function of sending e-mail ? The answer is yes !
Open source IT Time , We have many methods and tools to achieve our needs , As a geek , We can find out SMTP A special email sending process behind the protocol : Based on mailbox service provider server (IMAP,SMTP,POS3 etc. ) To bind the corresponding program , So as to achieve login free , The secondary program development realizes the mail sending function ( Just a simple understanding , Baidu ).
At the end of the paper, the GitHub Address Links !
 Insert picture description here

2. The development train of thought

python Is a super language with a powerful third-party library , We can choose a simple and easy-to-use third-party library ! After comparison, the author found that python Of yagmail Library is a good choice , The basic configuration is simple and not complex !
in addition , What we need to develop is product level , Then you can't open the code at runtime , We need to design something with UI Interactive interface program , because python Bring their own tkinter library , We can use it to GUI Development is relatively convenient and simple . We can also add program window icons , Add your favorite picture as the background !
In order to make the finished program available to more users , At the same time, ensure the security of their respective mailboxes , When we configure personal email privacy information , The configuration file is written locally and manually ini, This makes the finished program portable , also , You can modify your mailbox configuration information at any time !

3. Preparation

Knowledge reserve remarks
object-oriented programming : Classes and objects Use class , It can make the secondary development and maintenance of the program better , And the program code is modular and the structure is clear , Conducive to reading and development
GUI Development tkinterpython Self contained tkinterGUI To write , Although overall UI The interface is not more beautiful than the mainstream , But development is simple , And the appearance logic can meet our needs
pyinstallerpython Common and popular packaging Libraries , Need to download and install
yagmail library Very easy to use simple third-party libraries , Need to download and install
configparser library Library used to manage configuration files , Need to download and install
PIL library Common name is Pillow library , Need to download and install
datetime library To get time , Need to download and install
calendar library Used to generate a library in the form of calendar
tkinter.filedialog modular tk The file selection box module in the library
Other media files For background and icons, etc , Look at your choice , Free to decide
Get the key and other information from the email website Without these configurations , The mailbox program will not run , Be sure to set it first

The configuration method of mailbox website is as follows :
python- be based on yagmail Library to develop automatic mail sending program

Two , Write code

1. Code module

(1)MAIL.py

The MAIL.py Files are mainly placed in MAIL class , Save the main account configuration !

import yagmail# Core library of mailbox sender 
import configparser# Library used to manage configuration files 
import os
class MAIL:# mailbox MAIL class , Save the main account configuration 
    def __init__(self):
        # yagmail Library basic parameter settings 
        self.config = configparser.ConfigParser()
        self.config.read('MailConfig.ini')# Read configuration file , Ensure that the file exists before opening the program , After the program, press the corresponding function to regenerate the initialization configuration file 
        user = self.config['DEFAULT']['user']  #  Corresponding to your own email account 
        password =self.config['DEFAULT']['password'] #  The service password corresponding to your email application , The blog has links to introduce the steps , Not the login password of your mailbox 
        port = self.config['DEFAULT']['port'] #  Mailbox server port 
        host = self.config['DEFAULT']['host'] #  The email address of the server corresponding to 
        self.mail = yagmail.SMTP(user, password, host, port)  # yagmail Library initialization instance 
        # In order to ensure the security and portability of program code , In the same directory as the program , Open profile ( Open manually or programmatically ), Fill in the configuration information 
    def creatconfig(self):# The method of restoring to the default configuration file 
        self.config['DEFAULT'] = {
    'user': 'user',
                             'password': 'password',
                             'port': 'port',
                             'host': 'hosts'
                             }
        with open('MailConfig.ini', 'w+') as configfile:# Write to the default configuration file , Quite restore factory settings !
            self.config.write(configfile)

    def openconfig(self):# Method of automatically opening configuration file on program 
        os.startfile('MailConfig.ini')

(2)MAILGUI.py

The MAILGUI.py file ( Is the main program ) The main place MAILGUI class ,MAILGUI Class is mainly GUI Write classes and import and use the previous MAIL Class method .

from tkinter import * #tkinter Compiling GUI Program 
from PIL import Image,ImageTk # Because we set the window picture background , So introduce pil library , The corresponding common library name is Pillow  library 
from MAIL import MAIL # Import required MAIL class 
import datetime # To get time 
import calendar # Used to generate a library in the form of calendar 
import tkinter.filedialog #tk The file selection box module in the library 
class MAILGUI(MAIL):# Inherited from MAIL class 
    def __init__(self):
        super().__init__()
        #  Main window settings 
        self.root = Tk()  #  Program main form 
        self.root.title(' be based on SMTP Mailbox program automatically sent by protocol ')  #  Set the window title 
        self.root.geometry('800x600+300+100')  #  Set the window size and position under the system display 
        self.root.iconbitmap('mail.ico')  #  Set the form icon 
        self.lists=[''] # Because the first list element is displayed later , So the initial element is set to an empty string first 
        self.filename = '' # Initialize the attachment address variable 

        photo1=Image.open('background1.png')# The same as the picture file in the code file directory , For calendar background 
        self.background_image1 = ImageTk.PhotoImage(photo1.resize((500, 400)))

        # GUI Components 
        #  Recipient prompt label 
        to_label = Label(self.root, text=' The recipient :', font=(' In black ', 13)).place(x=10, y=20)
        #  Recipient input box 
        self.to_text = Text(self.root, width=26, height=1.55, font=(' In black ', 13))
        self.to_text.place(x=90, y=20)

        #  Email subject tag 
        title_label = Label(self.root, text=' The theme :', font=(' In black ', 13)).place(x=10, y=80)
        #  Mail subject input box 
        self.title_text = Text(self.root, width=26, height=1.55, font=(' In black ', 13))
        self.title_text.place(x=90, y=80)

        #  Email content prompt label 
        contents_label = Label(self.root, text=' Content :', font=(' In black ', 13)).place(x=10, y=140)
        #  Mail content input box 
        self.content_text = Text(self.root, width=75, height=12, font=(' In black ', 13))
        self.content_text.place(x=90, y=140)

        # Mail attachment button 
        attachments_button = Button(self.root, text=' Attachment address ', font=(' In black ', 13), fg='white', bg='green', command=self.Attachments,width=10, height=2, relief=RAISED)
        attachments_button.place(x=30, y=370)
        # Email attachment prompt label 
        self.attachments_label=Label(self.root, text=' No files selected yet ', font=(' In black ', 9),width=80, height=3, fg='white', bg='green')
        self.attachments_label.place(x=180, y=370)


        # Mail send confirmation button 
        check_button = Button(self.root, text=' Confirm sending ', font=(' In black ', 13), fg='white', bg='green', command=self.Sendto, width=10,height=2, relief=RAISED).place(x=30, y=450)

        # Program status label 
        tip_label = Label(self.root, text=' Program status :', font=(' In black ', 13)).place(x=10, y=530)

        #  The text content corresponds to the label of the operation prompt of the actual operation program 
        self.tipout_label = Label(self.root, text=' No operation yet !', font=(' In black ', 13), bg='green', fg='white')
        self.tipout_label.place(x=120, y=530)

        #  Used for time display labels 
        self.time_label = Label(self.root, text='', font=(' In black ', 16), fg='green')
        self.time_label.place(x=340, y=85)

        self.menubar = Menu(self.root)  #  The main menu 
        self.menuout = Menu(self.root, tearoff=0)  #  Pop up menu , Clear the collection of function realization 
        self.root['menu'] = self.menubar  #  Set up the main menu 
        #  Add menu items :
        self.menubar.add_command(label=" Initialize configuration file  ", command=self.creatconfig)# Initialize the menu option function of the configuration file 
        self.menubar.add_command(label="  Open profile  ", command=self.openconfig)# Open the menu option function of the configuration file 
        self.menubar.add_command(label="  draft  ", command=self.textbook)
        self.menubar.add_command(label="  The calendar  ", command=self.show_datetime)
        self.root.bind("<Button-3>", self.pops)  # <Button-3> For right-click Events , Used to trigger pop-up menus 
        self.menuout.add_command(label=' Empty the recipient window ', command=self.Clear_to)
        self.menuout.add_command(label=' Empty the theme window ', command=self.Clear_title)
        self.menuout.add_command(label=' Empty the content window ', command=self.Clear_content)
        self.menuout.add_command(label=' Empty attachment address ', command=self.Clear_attachments)
        self.menuout.add_command(label=' Clear all input windows ', command=self.message)
        self.root.mainloop()

    #  Attachment control function 
    def Attachments(self):
        self.filename = tkinter.filedialog.askopenfilename()  #  Select File... In the pop-up box , And get the string file address 
        if self.filename != '':  #  use filename Whether it is an empty string , If there is no choice , Just use the initial amount 
            self.tipout_label['text'] = ' You have selected the attachment file !'
            self.attachments_label['text'] = ' The file you selected is ' + self.filename
        else:
            self.tipout_label['text'] = ' You have not selected any files !'
            self.attachments_label['text'] = ' You haven't selected any files yet !'

    #  The main function : Process mail delivery 
    def Sendto(self):
        to = self.to_text.get('1.0', 'end')  #  Get relevant content 
        title = self.title_text.get('1.0', 'end')
        content = self.content_text.get('1.0', 'end')
        if self.filename == '':  #  according to filename Value to select whether to include attachments when sending 
            try:  #  It is important to check whether the mail is sent successfully ;
                self.mail.send(to, title, content)
                self.tipout_label['text'] = " Send successfully !"
            except:
                self.message()
        elif self.filename != '':
            try:
                self.mail.send(to, title, content, self.filename)
                self.tipout_label['text'] = " Send successfully !"
            except:
                self.message()

    def show_datetime(self):  #  utilize calendar The library displays the calendar window 
        winnew = Toplevel(self.root)  #  Top level form 
        winnew.title(' Calendar window ')
        winnew.geometry('500x400+700+50')
        winnew.iconbitmap('mail.ico')  #  Set window icons , Use the same 
        self.tipout_label['text'] = ' You opened the calendar window !'  #  Operation change prompt , Basically, every module contains 
        date_time = datetime.datetime.today()
        year = date_time.year  #  Get current year 
        month = date_time.month  #  Get current month 
        calendar.setfirstweekday(firstweekday=6)  #  Set the initial day of the calendar ( The first day )
        dates = calendar.month(year, month)  #  Get the string type of calendar 
        alldate = Label(winnew, text='', bg='green', fg='white', width=1000, height=600, font=(' In black ', 20),
                        image=self.background_image1, compound=CENTER)
        alldate.configure(text=dates)
        alldate.pack()

    def textbook(self):#  Draft operation window 
        text_win = Toplevel(self.root)
        text_win.title(' Draft window ')
        text_win.geometry('740x520+500+50')
        text_win.iconbitmap('mail.ico')
        self.tipout_label['text'] = ' You opened the draft window !'
        self.draft_paper = Text(text_win, width=100, height=30)  #  This example is the function of draft box input and text display box 
        self.draft_paper.insert('1.0', self.lists[0])  #  Insert saved content , Quite a memory , The logic of saving function is realized 
        save_button = Button(text_win, text=' preservation ', command=self.saves, relief=RAISED, fg='white', bg='green', font=(' In black ', 14),
                             width=10, height=2).place(x=19, y=430)
        clear_button = Button(text_win, text=' Empty all content ', command=self.clears, relief=RAISED, fg='white', bg='green',
                              font=(' In black ', 14), width=16, height=2).place(x=150, y=430)
        self.draft_paper.place(x=19, y=18)

    def saves(self):# How to save the contents of the draft box 
        self.lists[0] = self.draft_paper.get(1.0, 'end')  #  Click the save button , Trigger to get the content of the text box , Can be saved at any time during the writing process , Avoid losing 
        self.tipout_label['text'] = " You saved the contents of the draft box !"

    def clears(self):# How to empty the contents of the draft box 
        self.draft_paper.delete('1.0', 'end')
        self.tipout_label['text'] = " You emptied the contents of the draft box !"

    #  Used for error message prompt in other modules , Call when using 
    def message(self):
        self.tipout_label['text'] = " The input is incorrect or has been completely cleared ! Please re-enter everything !"
        self.to_text.delete('1.0', 'end')  #  The position of the first character in the text box control is  1.0, You can use numbers  1.0  Or a string "1.0" To express 
        self.title_text.delete('1.0', 'end')
        self.content_text.delete('1.0', 'end')
        self.filename=''
        self.tipout_label['text']=' You cleared all the entries ! Including the addressee , The theme , Content , All input of attachment address !'
        self.attachments_label['text']=' You haven't selected any files yet !'

    def pops(self,event):  #  Right click the response function , Pop up menu 
        self.menuout.post(event.x_root, event.y_root)  #  These two variables can pop up at any trigger part of the window 

    def Clear_to(self):  #  Empty recipient input box function 
        self.to_text.delete('1.0', 'end')
        self.tipout_label['text'] = ' You cleared the recipient window !'

    def Clear_title(self):  #  How to clear the email subject input box 
        self.title_text.delete('1.0', 'end')
        self.tipout_label['text'] = ' You empty the theme window !'

    def Clear_content(self):  #  How to empty the email content input box 
        self.content_text.delete('1.0', 'end')
        self.tipout_label['text'] = ' You empty the content window !'

    def Clear_attachments(self):
        self.filename=''
        self.tipout_label['text'] = ' You cleared the attachment address !'
        self.attachments_label['text'] = ' You haven't selected any files yet !'


if __name__ == '__main__':
    MAILGUI()

2. Problems encountered in development

pyinstaller Package multiple py Document and removal cmd Black box
Report errors :ModuleNotFoundError: No module named 'PIL’ resolvent
python Get current year and month
Python in tkinter.filedialog
Python-Tkinter Graphical interface design ( Detailed tutorial )
use tkinter.pack Design complex interface layout
python- be based on yagmail Library to develop automatic mail sending program

3、 ... and , Program packaging

1. Packaging process

(1) Find the directory of your code files , Copy down
 Insert picture description here
(2) open cmd window , Copy the copied directory to cmd window , And add cd, As shown in the following example :
 Insert picture description here
(3) Make sure you have downloaded and installed pyinstaller, Enter the following command :

pyinstaller -F < Program master file >.py

 Insert picture description here
(4) In the generated file , Only keep < The main program >.spec file , Delete the rest ( Of course, our original py The code files are also in this directory , Definitely don't delete , Just keep it )! as follows :
 Insert picture description here

(5) Open suffix is .spec file , stay Analysis A list of the first line in , Then add the dependencies of our main program and the modules to be imported MAIL.py The string form of the file , Here's the picture :
 Insert picture description here

(6) Open it again cmd, Enter file directory , Enter the following command :
The program does not carry a small black box , So add... After the command –noconsole sentence

pyinstaller -F  < Main program name >.spec --noconsole

 Insert picture description here
(7) Prompt after successful packaging , We can delete the generated _pycache_ and build file , Only keep dist Folder , Because there is a generator exe Program , In addition, the program form needs to use mail.ico file , By default, packaging will not move it to dist The folder , We want to copy to dist Under the document !
 Insert picture description here
(8) Modify the configuration file , as follows :
 Insert picture description here

2. Program function display and description

The interfaces of the program are as follows :
 Insert picture description here

 Insert picture description here
 Insert picture description here

Control Function description matters needing attention
Initialize the top-level menu options of the configuration file Initialize configuration file , Quite restore the original factory settings , Generally used to modify the configuration
Open the configuration file top-level menu option Quickly and automatically open the configuration file If you open and modify the configuration file , After saving the configuration file , You need to reopen the program , Before normal operation
Draft top-level menu options Open the draft window
Calendar top-level menu options Open the calendar window
Recipient input box Enter the recipient's information
Mail subject input box Enter the subject of the message
Mail content input box Enter the message content
Mail attachment button Select email attachment , If you don't click , No attachments by default Click the attachment selection window , If no file is selected , No attachments by default
Mail send confirmation button Enter the information you want to send , Click to send The system will run according to the network environment , There will be different degrees of jamming when sending , But it will work normally , Don't be surprised
Other display labels Display program operation and relevant prompts, etc
Draft save button Save what you entered in the draft window Save the scope in the window without closing the main program , All have memory function
Draft clear button Empty draft content
The configuration file If delete , It can be in the running state of the program , Click the initialize profile button , It can generate

Four , Finished program download

In order to better learn and share the content of this part , And provide the finished product program for everyone to directly observe , Specially put the resource link here , For all readers to download !
Mail delivery GUI Program download
If you have conditions , You can come to my Github Look at my project file and code , Attached below GitHub Project address :
Python-tool-development-pip-instruction-GUI-program
Last , Due to the lack of development experience and some defects in the program , I hope you understand !
Any questions about the content of the text , Welcome criticism and correction !!!

copyright notice
author[SteveDraw],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2022/131/202205110610218304.html

Random recommended