前言
功能
存单词(简单的feapder爬虫)
查单词 (pandas)
听写 (需要第三方库pyttsx3)
展示(分页)
没有可以pip一下
主页面
main.py
运行如图

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from 英语.save_word import word
from 英语.find import Find
from init import picturepath
#picturepath 图片路径
class Word(QWidget):
def __init__(self):
super().__init__()
self.find_w = None
self.show_word = None
self.listen_write = None
self.find_word = None
self.label = None
self.loser = None
self.save_word = None
self.initui()
def initui(self):
self.resize(617, 610)
self.setWindowOpacity(0.8)
#设置了透明度
self.setWindowTitle("主页面")
# 5个按钮,多个按钮对应一个点击事件,按钮的名字不一样
# 按钮的名字会起到关键性作用
self.save_word = QPushButton(self)
self.save_word.setText("存单词")
self.save_word.clicked.connect(self.save)
self.save_word.setShortcut('s')
self.save_word.setGeometry(140, 140, 93, 28)
self.loser = QPushButton(self)
self.loser.setText("退出")
self.loser.setGeometry(140, 300, 93, 28)
self.loser.clicked.connect(self.lose)
self.loser.setShortcut('l')
self.find_word = QPushButton(self)
self.find_word.setText("查单词")
self.find_word.setShortcut('f')
self.find_word.clicked.connect(self.find_)
self.find_word.setGeometry(310, 140, 93, 28)
self.label = QLabel(self)
self.label.setText("<html><head/><body><p align=\"center\"><span style=\" font-size:16pt; font-weight:600; color:#2a17ff;\">单词学习</span></p></body></html>")
self.label.setGeometry(170, 40, 221, 41)
self.listen_write = QPushButton(self)
self.listen_write.setText("听写")
self.listen_write.clicked.connect(self.find_)
self.listen_write.setShortcut('w,l')
self.listen_write.setGeometry(140, 220, 93, 28)
self.show_word = QPushButton(self)
self.show_word.clicked.connect(self.find_)
self.show_word.setGeometry(320, 220, 93, 28)
self.show_word.setText("展示")
# 存单词对应的事件
def save(self):
w = word()
w.setStyle(QStyleFactory.create('Fusion'))
w.setWindowModality(Qt.ApplicationModal)
w.show()
w.exec_()
# 除去退出按钮和存单词按钮对应的事件
def find_(self):
title = self.sender().text()
self.find_w = Find(title)
self.find_w.setWindowModality(Qt.ApplicationModal)
self.find_w.show()
# 退出事件
def lose(self):
self.close()
# 给图片添加背景
def paintEvent(self, QPaintEvent):
painter = QPainter(self)
pixmap = QPixmap(picturepath + '/29.jpg')
painter.drawPixmap(self.rect(), pixmap)
def main():
app = QApplication(sys.argv)
app.setStyle(QStyleFactory.create('Fusion'))
a = Word()
a.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
存单词
word.py
主页面点击存单词,就会弹出如下

输入英文,点击确定,就会调用爬虫,获取中文,存入到数据库
(我选择放到一个csv中,不想用数据库之类的,麻烦)
😛😛😛😛😛😛
import sys
import time
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
save_csv = r'C:\Users\520\PycharmProjects\pythonProject4\英语\英语库.csv'
import feapder
from feapder.setting import DEFAULT_USERAGENT
zh=None
zh 全局变量
# 爬虫的类,简单点,爬百度翻译的,爬有道还要逆向一下
class baidu_tran(feapder.AirSpider):
def __init__(self, kw):
super().__init__()
self.kw = kw
# 关键字(需要保存的单词)
def start_requests(self):
yield feapder.Request(url='https://fanyi.baidu.com/sug', download_midware=self.download_mid_ware)
# 中间件
def download_mid_ware(self, request):
request.headers = {
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'user-agent': DEFAULT_USERAGENT
}
request.data = {
'kw': self.kw
}
return request
def parse(self, request, response):
global zh
data=response.json
zh=data['data'][0]['v']
# 存单词
class word(QDialog):
def __init__(self):
super().__init__()
self.loser = None
self.ok = None
self.ch_qe = None
self.label = None
self.label_2 = None
self.en_qe = None
self.initui()
def initui(self):
self.resize(528, 312)
self.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
self.en_qe = QLineEdit(self)
self.en_qe.setGeometry(160, 90, 151, 21)
self.label = QLabel(self)
self.label.setGeometry(90, 90, 72, 15)
self.ok = QPushButton(self)
self.ok.setShortcut('O,K')
self.ok.clicked.connect(self.click_ok)
self.ok.setGeometry(160, 180, 93, 28)
self.loser = QPushButton(self)
self.loser.setShortcut('l')
self.loser.clicked.connect(self.lose)
self.loser.setGeometry(290, 180, 93, 28)
self.setWindowTitle('存单词')
self.label.setText("英文")
self.ok.setText("确定")
self.loser.setText("取消")
def click_ok(self):
global zh
data = []
en = self.en_qe.text()
if en:
# 有英文
spider = baidu_tran(en)
spider.start()
spider.join()
# 等待爬虫结束,才会往下继续
data.append([en, zh])
data = ','.join(data[0])
with open(save_csv, 'a') as f:
f.write(data)
f.write('\n')
qmes = QMessageBox()
QMessageBox.information(self, '消息', f'{en}的意思是:\n{zh}\n存入成功', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
def lose(self):
self.close()
其他功能
find.py
点击其他按钮
都会触发这个事件
比如点击查单词,就会弹出这个窗体

如果点击听写,还是会弹出这个窗体,但是内容不同,而且听写的输入框是不可用
点击其他按钮,依然如此,窗体一样,但内容不同。

如下
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import pandas as pd
import pyttsx3
import time
import numpy as np
save_csv=r'C:\Users\520\PycharmProjects\pythonProject4\英语\英语库.csv'
class Find(QWidget):
def __init__(self,title):
# 传入一个参数,决定某些控件的有无,控件的事件也不一样
# 一个确定按钮有多个事件。
super().__init__()
self.input_ok = None
self.input = None
self.data = None
self.now_page = 0
self.before_btn = None
self.next_btn = None
self.title=title
self.label = None
self.qe = None
self.table = None
self.loser = None
self.ok = None
self.now_info=None
self.initui()
def initui(self):
self.resize(788, 732)
self.setWindowTitle("查单词")
self.next_btn=QPushButton(self)
self.next_btn.setText('下一页')
self.next_btn.setVisible(False)
self.next_btn.setGeometry(10,20,80,30)
self.next_btn.clicked.connect(self.next_page)
self.before_btn=QPushButton(self)
self.before_btn.setText('上一页')
self.before_btn.setVisible(False)
self.before_btn.clicked.connect(self.before_page)
self.before_btn.setGeometry(100,20,80,30)
# 展示时存在的控件,分页
if self.title=='展示':
self.input=QLineEdit(self)
self.input.setGeometry(180,20,100,30)
va = QIntValidator(self)
# 校验器
va.setRange(0,9)
self.input.setValidator(va)
self.input.setPlaceholderText('输入页数:')
self.input_ok = QPushButton(self)
self.input_ok.setText('确定')
self.input_ok.setVisible(False)
self.input_ok.setGeometry(300,20,60,30)
self.input_ok.clicked.connect(self.choice)
else:
pass
self.now_info = QLabel(self)
self.now_info.setStyleSheet("color:blue;")
font=QFont()
font.setPointSize(12)
self.now_info.setFont(font)
self.now_info.setGeometry(80, 130, 220, 91)
# 参数不同,按钮的名字,按钮的事件会不同
self.ok = QPushButton(self)
if self.title=='听写':
self.ok.setText('开始')
else:
self.ok.setText("确定")
if self.title=='展示':
self.ok.clicked.connect(self.init_table)
elif self.title=='查单词':
self.ok.clicked.connect(self.init_tb)
elif self.title=='听写':
self.ok.clicked.connect(self.listen)
self.ok.setShortcut("O, K")
self.ok.setGeometry(50, 120, 93, 28)
self.label = QLabel(self)
self.label.setText(f"<html><head/><body><p align=\"center\"><span style=\" font-size:16pt; color:#54551a;\">{self.title}</span></p></body></html>")
self.label.setGeometry(210, 40, 161, 91)
# 输入框能否用
self.qe = QLineEdit(self)
if self.title=='查单词':
self.qe.setEnabled(True)
else:
self.qe.setEnabled(False)
self.qe.setGeometry(170, 120, 271, 21)
self.table= QTableWidget(self)
self.table.setGeometry(50, 190, 711, 521)
self.loser = QPushButton(self)
self.loser.setText('取消')
self.loser.setShortcut('l')
self.loser.clicked.connect(self.close)
self.loser.setGeometry(660, 110, 93, 28)
def lose(self):
self.close()
def choice(self):
text=self.input.text()
if text:
a=int(text)
if 1<=a<=len(self.data):
self.now_page=a-1
else:
QMessageBox.information(self, '消息', '超出页数范围', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
self.insert_tb()
def init_table(self):
self.table.setColumnCount(2)
table_header = [
{'text': '英文', 'width': 200},
{'text': '中文', 'width': 400},
]
for i, t in enumerate(table_header):
t_item1 = QTableWidgetItem()
t_item1.setText(t['text'])
self.table.setHorizontalHeaderItem(i, t_item1)
self.table.setColumnWidth(i, t['width'])
if self.title=='展示':
self.insert_data()
else:
pass
def insert_data(self):
self.next_btn.setVisible(True)
self.before_btn.setVisible(True)
self.input_ok.setVisible(True)
self.ok.setVisible(False)
self.data=self.from_csv()
self.insert_tb()
def insert_tb(self):
self.put_data()
def put_data(self):
self.now_info.setText(f"当前页数为{int(self.now_page)+1},一共有{len(self.data)}页")
self.table.setRowCount(0)
row_count = self.table.rowCount()
for i in self.data[self.now_page]:
self.table.insertRow(row_count)
for ids, t in enumerate(i):
cell = QTableWidgetItem(str(t))
self.table.setItem(row_count, ids, cell)
row_count += 1
def next_page(self):
if self.now_page==len(self.data)-1:
QMessageBox.information(self, '消息', '没有下一页了', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
else:
self.now_page += 1
self.insert_tb()
print(self.now_page)
def before_page(self):
if self.now_page==0:
QMessageBox.information(self, '消息', '没有上一页了', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
else:
self.now_page -= 1
self.insert_tb()
print(self.now_page)
# 为了分页展示
def from_csv(self):
df = pd.read_csv(save_csv, chunksize=10)
# pandas 分批次提取
info = []
for i in df:
data = np.array(i)
info.append(data)
return info
# 查单词的事件
def init_tb(self):
en=self.qe.text()
if en:
df = pd.read_csv(save_csv, index_col='英文')
try:
zh = df.loc[f'{en}']['中文']
self.init_table()
self.table.setRowCount(0)
row_count = self.table.rowCount()
self.table.insertRow(row_count)
i = [en, zh]
for ids, t in enumerate(i):
print(t)
cell = QTableWidgetItem(str(t))
self.table.setItem(row_count, ids, cell)
except Exception as e:
QMessageBox.information(self, '消息', f'单词{e}不存在', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
else:
QMessageBox.information(self, '消息', '请输入!!', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
def listen(self):
df = pd.read_csv(save_csv)
df=df.sample(10)
# pandas 取随机数,听写,有等待时间
data=[]
for i in range(10):
time.sleep(3)
en = df.iloc[i][0]
zh = df.iloc[i][1]
data.append([en,zh])
speak = pyttsx3.init()
speak.say(f'{en}')
speak.runAndWait()
reply=QMessageBox.information(self, '消息', '是否展示', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
if reply == QMessageBox.Yes:
self.init_table()
self.table.setRowCount(0)
row_count = self.table.rowCount()
for i in data:
self.table.insertRow(row_count)
for ids, t in enumerate(i):
cell = QTableWidgetItem(str(t))
self.table.setItem(row_count, ids, cell)
row_count += 1
else:
pass
总结
听写感觉没有完善,应该再写个文本框,判断听写的内容,有没有写对,顺便还可以打打分。
😁😁😁