成品差不多是下面这样,使用的方式是,Ctrl+c复制需要翻译的内容,按Alt+D进行翻译,窗口会全程置顶。如果你希望运行之后,没有黑漆漆的CMD窗口的话,将py后缀改为pyw就好。
以Python3.9的文档界面一段话作为演示,可以看到,去掉了换行看起来还行。对文本主要进行了多余空格的替换,以及去掉换行,连接因为一行放不下而在文献中常常出现的“-”连接符。
起因
是这样的,因为知云崩溃到直接无法打开,加上不知道是不是开了太多VPN(公司的,别多想),导致翻译的速度实在拉跨。没办法,想起来大四的选修课用过百度API-OCR接口,翻译图片上的文字。心想,自己申请一个百度的文本翻译API,自用岂不是很爽。
想到Python也可以建立GUI界面,而且还算是比较容易上手的,就直接开干。
翻译部分
API申请的话,可以看看Bob这个软件文档提供的申请步骤,我就是参考这个申请的翻译API。说到这个,就是因为换了Windows,Bob用不了,它只有macOS端。如果是用macOS的同学,我血书推荐Bob。
扯远了,直接看百度官方提供的调用代码,稍微改改之后就是下面这样了。
def translate(text='Test successed!', fromLang='auto', toLang='zh', appID='', secretKey=''):
# 创建专有的API链接
httpClient = None
myUrl = '/api/trans/vip/translate'
salt = random.randint(32768, 65536)
sign = appID + text + str(salt) + secretKey
md5 = hashlib.md5()
md5.update(sign.encode("utf-8"))
sign = md5.hexdigest()
myUrl = myUrl+'?appid=' + appID + '&q=' + parse.quote(text) + '&from=' + fromLang + '&to=' + toLang+'&salt=' + str(salt) + '&sign=' + sign
try:
# 客户端连接
httpClient = http.client.HTTPConnection('api.fanyi.baidu.com')
httpClient.request('GET', myUrl)
response = httpClient.getresponse()
#转码
html = response.read().decode('utf-8')
html = json.loads(html)
dst = html["trans_result"][0]["dst"]
# 打印输出翻译的内容
print("Results: " + dst)
return dst
except Exception as e:
# 打印错误信息
print(e)
return None
finally:
# 关闭API连接
if httpClient:
httpClient.close()
因为我是将它封装到类里面了,所以这里定义了一个函数。各位用的时候,只要填入自己的appID和secretKey就可以了。
界面部分
界面因为没什么需求,加上对界面这部分也确实不了解。唯二写过的带界面的桌面软件,也就是课设的VisualBasic,跟毕业设计用的Matlab了。
所以界面就用了4个QLabel空间,设置了一下位置跟文字大小之后,差不多就是你们之前看到的样式了。
class shawnWindow(QDialog):
sig_keyhot = pyqtSignal(str)
def __init__(self):
super(shawnWindow, self).__init__()
# 初始化状态
self.windowOnTop = True
self.setWindowFlags(Qt.WindowStaysOnTopHint)
# 设置标题
self.setWindowTitle('Shawn')
font = QFont()
font.setFamily("")
font.setPointSize(12)
# 创建 4 个 Label
nameLb1 = QLabel('原文:', self)
self.nameLb2 = QLabel(None, self)
nameLb3 = QLabel('译文:', self)
self.nameLb4 = QLabel(None, self)
self.nameLb2.setFont(font)
self.nameLb4.setFont(font)
# 主要布局
mainLayout = QGridLayout(self)
mainLayout.addWidget(nameLb1, 0, 0)
mainLayout.addWidget(self.nameLb2, 1, 0)
mainLayout.addWidget(nameLb3, 2, 0)
mainLayout.addWidget(self.nameLb4, 3, 0)
mainLayout.setColumnMinimumWidth(0, 500)
mainLayout.setRowMinimumHeight(0, 50)
mainLayout.setRowMinimumHeight(1, 200)
mainLayout.setRowMinimumHeight(2, 50)
mainLayout.setRowMinimumHeight(3, 200)
self.nameLb2.setWordWrap(True)
self.nameLb4.setWordWrap(True)
self.setWindowIcon(QIcon("logo.ico"))
键盘监听部分
因为不想加一个按钮,纯键盘操作是最好的,所以直接监听键盘了,我设置的快捷键是 Alt + D 操作,理论上直接设置为 Ctrl + C 为快捷键是最好的,因为这样的话,可以复制完立马翻译。
说到这个,是因为不会获取鼠标选中的内容,所以曲线救国,先复制,再读取剪切板。这样的话,如果将翻译的监听快捷键设置为 Ctrl + C 的话,会使得先执行翻译,后执行复制,每次翻译的内容都是前面剪贴板的内容。因此,就暂时这么设置为 Alt + D 了。
# 设置自定义热键响应函数
self.sig_keyhot.connect(self.hotKeyPressEvent)
# 初始化热键
self.hk_start = SystemHotkey()
# 绑定快捷键和对应的信号发送函数
self.hk_start.register(('alt','d'), callback = lambda x: self.send_key_event("start"))
# 热键处理函数
def hotKeyPressEvent(self, event) -> None:
copyFromClipBoard = pyperclip.paste()
copyFromClipBoard = copyFromClipBoard.replace('-\\n', ' ').replace('-\\r', ' ').replace('\\n', ' ').replace('\\r', ' ')
copyFromClipBoard = re.sub(' +', ' ', copyFromClipBoard)
translateFormAPI = self.translate(text = copyFromClipBoard)
self.setLable(copyFromClipBoard, translateFormAPI)
# 热键信号发送函数(将外部信号,转化成qt信号)
def send_key_event(self,i_str):
self.sig_keyhot.emit(i_str)
# 设置翻译
def setLable(self, copyFromClipBoard, translateFormAPI):
self.nameLb2.setText(copyFromClipBoard)
self.nameLb4.setText(translateFormAPI)
什么BUG?
暂时用着挺好的,没什么问题。就是太简陋了,以及API其实反应也没有我想的那么快,只不过专属的API接口确实不错就是了。
希望后面会有时间折腾一下,OCR,也就是截图翻译识别文本。
还有就是,没有用到多线程,这个在后面折腾一个压缩图片的工具时学了下,可惜这里没用到。