最近因为编程,需要大量地看一些说明文档,无奈说明文档都是英文的,可把我这个半桶水折腾死了,太多词汇不知道,一个个复制翻译太麻烦了。于是我根据自己的需要,用python写了一个划词翻译。
一:使用逻辑
由于我是看PDF文档,用的是一款轻量级的PDF阅读器(SumatraPDF),这款阅读器只有5M,但是阅读很舒服很流畅,渲染也很到位。但是没有其他阅读器有许多强大功能,比如说划词翻译。
我的想法是一旦发现我复制就可以在当前鼠标位置显示一个翻译结果框。基于这个想法,我一开始准备使用MFC编写,因为MFC能够轻易获得系统消息,钩子调用十分简单。可是我把检测复制,显示文本框都做好的时候,发现一个悲伤的事实,c++的http库实在是不怎么样,竟然无法访问http://地址,经过一晚的尝试——失败,这才打算使用python。啰啰嗦嗦一大堆,我现在把我的逻辑说下吧。
二:需要引用的库
因为要联网所以需要urllib,解析网页需要json,读取剪切板数据需要win32clipboard,获得当前鼠标信息用PyMouse,生成文本框Tkinter,定时器time。python为什么强大,就在于集成库的易用性和多样性,有什么需要就pip install 装就行,这点比c++强太多了。
import urllib #http连接需要用到
import json #解析网页数据用
import win32clipboard as wc #读取剪切板数据
from pymouse import PyMouse #获得当前鼠标信息
import Tkinter #自带的GUI库,生成文本框
import time #定时器,减少占用
三:代码实现
- 我这里先定义了三个函数,方便后面实现功能,下面有详细解释和代码
#PyMouse得到的是2维字符串,但是tkinter生成窗体时需要的是类似(100*100+x+y)的字符串,100*100是窗口大小,xy是坐标点。
def transMousePosition():m = PyMouse()return "100x100+"+str(m.position()[0])+"+"+str(m.position()[1])
#获得剪切板数据
def getCopyText():wc.OpenClipboard()copy_text = wc.GetClipboardData()wc.CloseClipboard()return copy_text
#返会是否有新的复制数据,cmp函数用于比较2个对象,如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1。
def newCopyData():return cmp(currentData,str(getCopyText()))
- 主程序
if __name__ == '__main__':req_url = 'http://fanyi.youdao.com/translate' # 创建连接接口,这里是有道词典的借口# 创建要提交的数据currentData=str(getCopyText())Form_Date = {}Form_Date['doctype'] = 'json'while 1:if newCopyData():currentData=str(getCopyText())#取得当前剪切板数据Form_Date['i'] = currentData # 传递数据data = urllib.urlencode(Form_Date).encode('utf-8') #数据转换response = urllib.urlopen(req_url, data) #提交数据并解析html = response.read().decode('utf-8') #服务器返回结果读取translate_results = json.loads(html) #以json格式载入translate_results = translate_results['translateResult'][0][0]['tgt'] # json格式调取position=transMousePosition()#取得当前鼠标位置top = Tkinter.Tk()#窗口初始化top.wm_attributes('-topmost',1)#置顶窗口top.geometry(position)#指定定位生成指定大小窗口e=Tkinter.Text()#生成文本框部件e.insert(1.0,translate_results)#插入数据e.pack()#将部件打包进窗口top.mainloop()# 进入消息循环currentData=str(getCopyText())time.sleep(1)
到此,我们划词翻译程序就已经完成了,虽然不太美观。而且美中不足的是我没有想到一个好的办法退出程序,相当于一个死循环在里面,只有强行退出,不知道谁有好办法能够解决这个问题,如果有,请和我联系ltyplay@gmail.com
总结
如果要实现什么功能,python该是最好的胶水了,c++的http库实在是太坑了,浪费我好多小时。下面源代码附上,给大家参考
# -*- coding: utf-8 -*-
"""
Created on Sat Aug 11 08:24:48 2018@author: ltengy
"""
import urllib #http连接需要用到
import json #解析网页数据用
import win32clipboard as wc #读取剪切板数据
from pymouse import PyMouse #获得当前鼠标信息
import Tkinter #自带的GUI库,生成文本框
import time #定时器,减少占用
currentData='' #PyMouse得到的是2维字符串,但是tkinter生成窗体时需要的是类似(100*100+x+y)的字符串,100*100是窗口大小,xy是坐标点。
def transMousePosition():m = PyMouse()return "100x100+"+str(m.position()[0])+"+"+str(m.position()[1])
#获得剪切板数据
def getCopyText():wc.OpenClipboard()copy_text = wc.GetClipboardData()wc.CloseClipboard()return copy_text
#返会是否有新的复制数据
def newCopyData():return cmp(currentData,str(getCopyText()))
if __name__ == '__main__':req_url = 'http://fanyi.youdao.com/translate' # 创建连接接口,这里是有道词典的借口# 创建要提交的数据currentData=str(getCopyText())Form_Date = {}Form_Date['doctype'] = 'json'while 1:if newCopyData():currentData=str(getCopyText())#取得当前剪切板数据Form_Date['i'] = currentData # 传递数据data = urllib.urlencode(Form_Date).encode('utf-8') #数据转换response = urllib.urlopen(req_url, data) #提交数据并解析html = response.read().decode('utf-8') #服务器返回结果读取translate_results = json.loads(html) #以json格式载入translate_results = translate_results['translateResult'][0][0]['tgt'] # json格式调取position=transMousePosition()#取得当前鼠标位置top = Tkinter.Tk()#窗口初始化top.wm_attributes('-topmost',1)#置顶窗口top.geometry(position)#指定定位生成指定大小窗口e=Tkinter.Text()#生成文本框部件e.insert(1.0,translate_results)#插入数据e.pack()#将部件打包进窗口top.mainloop()# 进入消息循环currentData=str(getCopyText())time.sleep(1)