1.界面設計
1.1 環境配置
在外部工具位置進行配置
?1.2 UI界面設計
1.2.1 進入QT的UI設計界面
在pycharm中按順序點擊,進入UI編輯界面:
?
?點擊第三步后進入QT的UI設計界面,通過點擊按鈕進行界面設計,設計后進行保存到當前Pycharm項目的文件路徑之下。
?1.2.2? .ui文件轉換為.py文件
?1.2.3 運行主程序
通過以下代碼對ui轉換的py文件進行調用:
# -*- coding: utf-8 -*-
import smtplib
import ssl
from email.mime.text import MIMEText
from email.header import Header
from email.utils import formataddrimport sys
from PyQt5.QtWidgets import QApplication,QMainWindow
from EmailSenderUI import Ui_Form # 加載布局# 定義主窗口類,繼承自QMainWindow和自動生成的UI類Ui_Form
class Mywindow(QMainWindow, Ui_Form):def __init__(self): # 調用父類QMainWindow的初始化方法super().__init__() # 初始化UI界面(由Qt Designer生成的setupUi方法)self.setupUi(self) # 可在此處添加額外的初始化代碼(如信號槽連接等)if __name__ == '__main__':# 當直接運行本腳本時執行以下代碼(而非被其他模塊導入時)app = QApplication(sys.argv) # 創建Qt應用程序實例,sys.argv用于傳遞命令行參數ui = Mywindow() # 實例化主窗口對象ui.show() # 顯示主窗口sys.exit(app.exec_()) # 進入Qt主事件循環,等待用戶操作。sys.exit()確保程序能正確退出并返回狀態碼
?運行結果如下圖所示:
?注:通過上面的步驟就可以得到一個設計的初始化界面,其具體功能還未實現。
1.3 功能實現——槽函數
UI界面設計的各個控件的名稱通過槽函數與相應的功能函數進行連接
2. 完整代碼
程序共包含4個文件:main.py,open_show_file.py,發送郵件函數.py,EmailSenderUI.py
2.1 open_show_file.py
import sys
import pandas as pd
from PyQt5.QtWidgets import QApplication,QMainWindowfrom PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QLabel, QFileDialog, QTextEdit,QTableWidget, QTableWidgetItem, QWidget,QStackedWidget
from sklearn.ensemble import RandomForestRegressor
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import Qtfrom sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error
from sklearn.metrics import *
import numpy as npimport torch
import torch.nn as nn
import torch.optim as optim
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, mean_absolute_errorimport matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
## 設置字符集,防止中文亂碼
import matplotlib as mpl #畫圖工具
mpl.rcParams['font.sans-serif']=[u'simHei']
mpl.rcParams['axes.unicode_minus']=False############################################################################## page1_1_1 ####################################################################################
# 打開文件,選擇路徑并顯示
def open_select_file_def(parent,page1_1_1_via_show):options = QFileDialog.Options() # 創建一個文件對話框選項對象。options |= QFileDialog.ReadOnly # 將選項設置為只讀模式,這表示用戶只能選擇已經存在的文件而不能創建新文件。file_path, _ = QFileDialog.getOpenFileName(parent, "Select File", "", "Excel Files (*.xlsx *.xls)", options=options)# 調用文件對話框的getOpenFileName方法,該方法會打開文件選擇對話框 ;參數:# self:表示當前窗口或部件。# "Select File":對話框標題。# "":默認路徑,此處為空字符串表示打開對話框時不指定默認路徑。# "Excel Files (*.xlsx)":文件類型過濾器,限制用戶只能選擇Excel文件。# options = options:傳遞前面創建的選項對象。if file_path: # 檢查用戶是否選擇了文件路徑,如果選擇了文件,則進入下面的代碼塊。selected_file_path = file_path # 將選擇的文件路徑保存到對象的 selected_file_path 屬性中,以便后續使用。page1_1_1_via_show.setText(f"文件路徑: {file_path}") # 將界面上的文件標簽的文本設置為顯示所選文件的路徑。page1_1_1_data = pd.read_excel(file_path) # 使用 pandas 讀取 Excel 文件數據return page1_1_1_dataelse:pass# 將 Excel 數據填充到表格中。
def show_file_data_def(table_widget, data):table_widget.setColumnCount(data.shape[1]) # 將表格小部件的列數設置為data DataFrame的列數,以便為每個數據行創建一個對應的表格列table_widget.setRowCount(data.shape[0]) # 將表格小部件的行數設置為data DataFrame的行數,以便為每個數據行創建一個對應的表格行table_widget.setHorizontalHeaderLabels(data.columns) # 將DataFrame的列名設置為表格小部件的水平表頭標簽for row_idx in range(data.shape[0]):for col_idx in range(data.shape[1]):item = QTableWidgetItem(str(data.iat[row_idx, col_idx])) # 從DataFrame中獲取特定行和列索引位置處的單元格數據,并使用str()函數將其轉換為字符串。然后,通過QTableWidgetItem()將該字符串添加到表格小部件的特定單元格中。table_widget.setItem(row_idx, col_idx, item) # 將 QTableWidgetItem 對象放置到表格小部件的特定單元格中,從而將數據顯示在表格中
############################################################################## page1_1_1 ####################################################################################
2.2 發送郵件函數.py:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import osimport pandas as pddef send_email(from_addr,password,to_addrs,subject,body,attachments=None,smtp_server="smtp.qq.com",smtp_port=587
):msg = MIMEMultipart()msg["From"] = from_addrmsg["To"] = ",".join(to_addrs)msg["Subject"] = subjectmsg.attach(MIMEText(body, "plain", "utf-8"))# 添加附件if attachments:for file_path in attachments:part = MIMEBase("application", "octet-stream")with open(file_path, "rb") as f:part.set_payload(f.read())encoders.encode_base64(part)part.add_header("Content-Disposition",f"attachment; filename={os.path.basename(file_path)}",)msg.attach(part)server = smtplib.SMTP(smtp_server, smtp_port)server.starttls()try:server.login(from_addr, password)except Exception as e:return "登錄失敗","請輸入正確的郵箱賬號和授權碼"try:server.sendmail(from_addr,to_addrs,msg.as_string())# print(f"郵件 {to_addrs} 發送成功!")return f"{to_addrs} ","成功"except Exception as e:# print(f"發送失敗:{str(e)}")# print(f"郵件 {to_addrs} 發送失敗!")return f"{to_addrs} ","失敗"finally:server.quit()
2.3 main.py:
# -*- coding: utf-8 -*-
import smtplib
import ssl
from email.mime.text import MIMEText
from email.header import Header
from email.utils import formataddr
import pandas as pd
import sys
from PyQt5.QtWidgets import QApplication,QMainWindow
from EmailSenderUI import Ui_Form # 加載布局
from 軟件功能函數.open_show_file import open_select_file_def,show_file_data_def
from 軟件功能函數.發送郵件函數 import send_emailfrom PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QLabel, QFileDialog, QTextEdit, \QTableWidget, QTableWidgetItem, QWidget,QStackedWidget
from sklearn.ensemble import RandomForestRegressor
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import Qtfrom sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error
from sklearn.metrics import *
import numpy as npimport torch
import torch.nn as nn
import torch.optim as optim
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, mean_absolute_errorimport matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
## 設置字符集,防止中文亂碼
import matplotlib as mpl #畫圖工具import rempl.rcParams['font.sans-serif']=[u'simHei']
mpl.rcParams['axes.unicode_minus']=False# 定義主窗口類,繼承自QMainWindow和自動生成的UI類Ui_Form
class Mywindow(QMainWindow, Ui_Form):def __init__(self): # 調用父類QMainWindow的初始化方法super().__init__() # 初始化UI界面(由Qt Designer生成的setupUi方法)self.setupUi(self) # 可在此處添加額外的初始化代碼(如信號槽連接等)# 通過槽函數 將控件名稱與功能實現函數連接self.pushButton_open.clicked.connect(self.button_open_file) # 連接 pushButton_open 鈕到 button_open_file 函數方法self.pushButton_confirm.clicked.connect(self.email_information)self.pushButton_send.clicked.connect(self.send_information)# 函數功能實現# 打開文件夾,獲取接收方賬號等信息def button_open_file(self):self.data_frame = open_select_file_def(self, self.lineEdit_via_show)show_file_data_def(self.email_show, self.data_frame)# 確實郵件發送方信息def email_information(self):try:self.EmailAccount_text = self.sender_email.text().strip() # 獲取文本內容,并去除首位空格self.EmailCode_text = self.sender_email_code.text().strip() # 獲取文本內容if not self.EmailAccount_text or not self.EmailCode_text:self.label_information.setText("請確認發送方賬號和驗證碼的輸入信息")return# 郵箱格式驗證(正則表達式)if not re.match(r'^[\w\.-]+@[\w\.-]+\.\w+$', self.EmailAccount_text):self.label_information.setText("發送方的郵箱格式不正確")returnelse:self.label_information.setText("發送方賬號和驗證碼輸入成功")# 此處可添加后續邏輯(如調用發送郵件函數)except Exception as e:print(f"信息讀取錯誤: {str(e)}") # 明確打印錯誤類型# 發送郵件def send_information(self):sender_account = self.EmailAccount_textsender_password = self.EmailCode_textresults = []for index, row in self.data_frame.iterrows():# 提取當前行數據to_email = row.iloc[0]subject = row.iloc[1]body = row.iloc[2]result = send_email(from_addr=sender_account, password=sender_password, to_addrs=to_email, subject=subject,body=body)results.append(result)# 設置表格的行數和列數self.email_send_information.setRowCount(len(results))self.email_send_information.setColumnCount(2) # 假設有三個字段:Name, Age, City# 設置表頭self.email_send_information.setHorizontalHeaderLabels(["郵箱賬號","郵件發送狀態"])# 填充數據for row, row_data in enumerate(results):self.email_send_information.setItem(row, 0, QTableWidgetItem(str(row_data[0])))self.email_send_information.setItem(row, 1, QTableWidgetItem(str(row_data[1])))if __name__ == '__main__':# 當直接運行本腳本時執行以下代碼(而非被其他模塊導入時)app = QApplication(sys.argv) # 創建Qt應用程序實例,sys.argv用于傳遞命令行參數ui = Mywindow() # 實例化主窗口對象ui.show() # 顯示主窗口sys.exit(app.exec_()) # 進入Qt主事件循環,等待用戶操作。sys.exit()確保程序能正確退出并返回狀態碼
2.4?EmailSenderUI.py
# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'EmailSenderUI.ui'
#
# Created by: PyQt5 UI code generator 5.12
#
# WARNING! All changes made in this file will be lost!from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(778, 827)self.pushButton_open = QtWidgets.QPushButton(Form)self.pushButton_open.setGeometry(QtCore.QRect(60, 30, 101, 41))self.pushButton_open.setObjectName("pushButton_open")self.lineEdit_via_show = QtWidgets.QLineEdit(Form)self.lineEdit_via_show.setGeometry(QtCore.QRect(190, 30, 471, 41))self.lineEdit_via_show.setObjectName("lineEdit_via_show")self.sender_email = QtWidgets.QLineEdit(Form)self.sender_email.setGeometry(QtCore.QRect(70, 310, 461, 41))self.sender_email.setText("")self.sender_email.setObjectName("sender_email")self.pushButton_confirm = QtWidgets.QPushButton(Form)self.pushButton_confirm.setGeometry(QtCore.QRect(560, 320, 91, 91))self.pushButton_confirm.setObjectName("pushButton_confirm")self.sender_email_code = QtWidgets.QLineEdit(Form)self.sender_email_code.setGeometry(QtCore.QRect(70, 390, 461, 41))self.sender_email_code.setText("")self.sender_email_code.setObjectName("sender_email_code")self.label = QtWidgets.QLabel(Form)self.label.setGeometry(QtCore.QRect(80, 280, 131, 31))self.label.setObjectName("label")self.label_2 = QtWidgets.QLabel(Form)self.label_2.setGeometry(QtCore.QRect(80, 360, 191, 31))self.label_2.setObjectName("label_2")self.email_show = QtWidgets.QTableWidget(Form)self.email_show.setGeometry(QtCore.QRect(60, 80, 601, 192))self.email_show.setObjectName("email_show")self.email_show.setColumnCount(0)self.email_show.setRowCount(0)self.email_send_information = QtWidgets.QTableWidget(Form)self.email_send_information.setGeometry(QtCore.QRect(60, 570, 591, 171))self.email_send_information.setObjectName("email_send_information")self.email_send_information.setColumnCount(0)self.email_send_information.setRowCount(0)self.pushButton_send = QtWidgets.QPushButton(Form)self.pushButton_send.setGeometry(QtCore.QRect(60, 520, 591, 41))self.pushButton_send.setObjectName("pushButton_send")self.label_information = QtWidgets.QLabel(Form)self.label_information.setGeometry(QtCore.QRect(80, 460, 571, 41))self.label_information.setObjectName("label_information")self.retranslateUi(Form)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "Form"))self.pushButton_open.setText(_translate("Form", "打開"))self.pushButton_confirm.setText(_translate("Form", "確認"))self.label.setText(_translate("Form", "發送方的郵箱賬號:"))self.label_2.setText(_translate("Form", "發送方的郵箱賬號的授權碼:"))self.pushButton_send.setText(_translate("Form", "發送"))self.label_information.setText(_translate("Form", "信息:"))
2.5 文件目錄結構
?
2.6?程序運行界面
獲取郵箱授權碼_qq郵箱授權碼如何獲取-CSDN博客文章瀏覽閱讀1.6k次。登錄QQ郵箱:依次點擊:設置--賬號。_qq郵箱授權碼如何獲取https://blog.csdn.net/javin4715/article/details/140911566?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522b863bb97086e7c2892e63c5833317f87%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=b863bb97086e7c2892e63c5833317f87&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-1-140911566-null-null.142^v102^pc_search_result_base7&utm_term=qq%E9%82%AE%E7%AE%B1%E6%8E%88%E6%9D%83%E7%A0%81&spm=1018.2226.3001.4187
?3. 代碼打包成APP
?使用下面代碼在終端進行打包:
pyinstaller -F -w app.py -n xxx # 其中app.py為你的.py代碼名字; xxx 為打包時設置的軟件名字
pyinstaller -F -w main.py -n EmailQQ
其中:打包時會自動去添加需要的代碼,因此app.py為主函數代碼。如下圖所示:
?當生成完成后,將會在項目的文件路徑下看到多了3個文件build、?dist?、app.spec,其中在dist目錄下看到有一個 EmailQQ.exe?文件,這就是使用 PyInstaller 工具生成的 EXE 程序。?
打包方法介紹https://blog.csdn.net/qq_68639191/article/details/136215464?spm=1011.2415.3001.5331