From 961290ec19fd3283eff34c12cdafe9f267363932 Mon Sep 17 00:00:00 2001 From: Elliott Zheng Date: Wed, 28 Nov 2018 13:38:33 +0800 Subject: [PATCH] v0.0.7 release --- copyTranslator/CopyTranslator.py | 4 +- copyTranslator/color_ctrl.py | 7 ++- copyTranslator/config.py | 52 ++++++++++++-------- copyTranslator/constant.py | 3 +- copyTranslator/{setting.py => controller.py} | 32 +++++++----- copyTranslator/mainframe.py | 20 ++++++-- copyTranslator/mypanel.py | 8 +-- copyTranslator/shortcut.bat | 4 +- copyTranslator/taskbar.py | 8 ++- copyTranslator/update_checker.py | 3 +- copyTranslator/update_log.txt | 16 ++++-- copyTranslator/version.json | 4 +- requirements.txt | 2 + 13 files changed, 105 insertions(+), 58 deletions(-) rename copyTranslator/{setting.py => controller.py} (94%) create mode 100644 requirements.txt diff --git a/copyTranslator/CopyTranslator.py b/copyTranslator/CopyTranslator.py index 9d657dfc..998fc47f 100644 --- a/copyTranslator/CopyTranslator.py +++ b/copyTranslator/CopyTranslator.py @@ -1,6 +1,6 @@ import wx -from copyTranslator.setting import Setting +from copyTranslator.controller import Controller # import subprocess @@ -8,7 +8,7 @@ def main(): # subprocess.Popen('shortcut.bat',stdin = subprocess.PIPE, stdout = subprocess.PIPE) app = wx.App() - setting = Setting() + controller = Controller() app.MainLoop() diff --git a/copyTranslator/color_ctrl.py b/copyTranslator/color_ctrl.py index 4be08334..57a383bd 100644 --- a/copyTranslator/color_ctrl.py +++ b/copyTranslator/color_ctrl.py @@ -51,7 +51,7 @@ def __init__(self, parent=None, id=None, style=0, setting=None): self.setting = setting self.lang = self.setting.lang if style == 0: - style = wx.TE_RICH2 | wx.TE_MULTILINE | wx.TE_PROCESS_ENTER + style = wx.TE_RICH2 | wx.TE_MULTILINE | wx.TE_PROCESS_ENTER | wx.TE_NOHIDESEL super(ColoredCtrl, self).__init__(parent=parent, id=id, style=style) self.Bind(wx.EVT_RIGHT_DOWN, self.OnShowPopup) @@ -117,8 +117,6 @@ def CreateContextMenu(self): # menu.Append(self.ID_Mode2, self.lang(self.setting.config.Mode2)) - - copy = menu.AppendCheckItem(self.ID_Copy, self.lang('Auto Copy'), 'Auto copy result to clipboard.') copy.Check(self.setting.is_copy) @@ -181,7 +179,8 @@ def show_word(self, result): # Color.black) self.ColoredAppend('\nBasic Explains:\n', Color.blue) - self.ColoredAppend('\t' + '\n\t'.join(result['basic']['explains']) + '\n', Color.black) + filtered = filter(lambda x: x is not None, result['basic']['explains']) + self.ColoredAppend('\t' + '\n\t'.join(filtered) + '\n', Color.black) if 'translation' in result: self.ColoredAppend('Google Translation:\n', Color.blue) diff --git a/copyTranslator/config.py b/copyTranslator/config.py index dbe263fb..05fb93e8 100644 --- a/copyTranslator/config.py +++ b/copyTranslator/config.py @@ -7,11 +7,13 @@ import json import os +import threading +import webbrowser import wx from pynput import mouse -from constant import version +from constant import * from copyTranslator.youdao import YoudaoSpider from focusframe import FocusFrame from googletranslator import GoogleTranslator @@ -27,10 +29,10 @@ def __init__(self, setting): self.mouseListener = mouse.Listener(on_click=self.setting.onLongClick) self._default_value = {'author': 'Elliott Zheng', 'version': version, - 'is_listen': False, + 'is_listen': True, 'is_copy': False, 'is_dete': False, - 'stay_top': True, + 'stay_top': False, 'continus': False, 'smart_dict': True, 'frame_mode': FrameMode.main, @@ -38,13 +40,13 @@ def __init__(self, setting): 'font_size': 15, 'focus_x': 100, 'focus_y': 100, - 'focus_height': 150, - 'focus_width': 300, + 'focus_height': 300, + 'focus_width': 500, 'source': 'English', 'target': 'Chinese (Simplified)', 'last_ask': 0, 'language': 'Chinese (Simplified)', - 'autohide': True, + 'autohide': False, 'autoshow': False } self.value = self._default_value @@ -71,6 +73,8 @@ def activate(self): self.is_copy = self.is_copy self.frame_mode = self.frame_mode self.is_dict = self.is_dict + self.autoshow = self.autoshow + self.autohide = self.autohide self.switch_translator() def detect(self, string): @@ -95,17 +99,18 @@ def target(self): def target(self, value): self['target'] = value - def load(self): + def load(self): # 只有版本相同才会被保留,因为配置文件在不同版本间变化很大。 if not os.path.exists(self.filepath): + FirstThread().start() self.save(self.filepath) return self myfile = open(self.filepath, 'r') value = json.load(myfile) myfile.close() - if value['version'] < 'v0.0.7.0': - self.inherent(value) - elif value['version'] >= 'v0.0.7.0': + if value['version'] == version: self.value = value + else: + FirstThread().start() self.save(self.filepath) return self @@ -116,16 +121,6 @@ def save(self, filepath=None): json.dump(self.value, myfile, indent=4) myfile.close() - def inherent(self, old_value): - self.continus = old_value['continus'] - self.stay_top = old_value['stay_top'] - self.is_listen = old_value['is_listen'] - self.is_dete = old_value['is_dete'] - self.is_copy = old_value['is_copy'] - self.frame_mode = FrameMode.main if old_value['is_main'] else FrameMode.focus # TODO - self.font_size = old_value['pixel_size'] - self.is_dict = old_value['smart_dict'] - def switch_translator(self, type=TranslatorType.GOOGLE): if type == TranslatorType.GOOGLE: self.translator = GoogleTranslator() @@ -293,6 +288,7 @@ def autohide(self): @autohide.setter def autohide(self, value): self.value['autohide'] = value + self.setting.mainFrame.hideCheck.SetValue(value) @property def autoshow(self): @@ -301,3 +297,19 @@ def autoshow(self): @autoshow.setter def autoshow(self, value): self.value['autoshow'] = value + self.setting.mainFrame.showCheck.SetValue(value) + + +class FirstThread(threading.Thread): + def __init__(self): + threading.Thread.__init__(self) + + def run(self): + box = wx.MessageDialog(None, + 'If you found it useful, please give me a star on GitHub or introduce to your friend.\n\n如果您感觉本软件对您有所帮助,请在项目Github上给个star或是介绍给您的朋友,谢谢。\n\n本软件免费开源,如果您是以付费的方式获得本软件,那么你应该是被骗了。[○・`Д´・ ○]\n\n这是您首次使用,本软件功能非常丰富,需要查看使用指南才能完全发挥功能,前往软件官网查看?', + project_name + ' ' + version + ' by Elliott Zheng', + wx.YES_NO | wx.STAY_ON_TOP | wx.ICON_QUESTION) + answer = box.ShowModal() + if answer == wx.ID_YES: + webbrowser.open(usage_url) + box.Destroy() diff --git a/copyTranslator/constant.py b/copyTranslator/constant.py index 3de6ce8f..971b9bef 100644 --- a/copyTranslator/constant.py +++ b/copyTranslator/constant.py @@ -5,12 +5,13 @@ # @Software: PyCharm logopath = 'logo.ico' -version = 'v0.0.7.0-Kirin-Alpha' +version = 'v0.0.7-Kylin-RC0' project_name = 'CopyTranslator' update_json_url = 'https://hypercube.top/copytranslator/version.json' install_url = 'https://github.com/elliottzheng/CopyTranslator/wiki/Downloads-%E4%B8%8B%E8%BD%BD%E4%B8%8E%E5%AE%89%E8%A3%85' log_path = 'update_log.txt' project_url = 'https://hypercube.top/copytranslator/' +usage_url = 'https://github.com/elliottzheng/CopyTranslator/wiki/Usage-%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97' level = 3 levels_log = { diff --git a/copyTranslator/setting.py b/copyTranslator/controller.py similarity index 94% rename from copyTranslator/setting.py rename to copyTranslator/controller.py index 63b8ef6b..016b02c3 100644 --- a/copyTranslator/setting.py +++ b/copyTranslator/controller.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # @Time : 2018/9/25 0025 17:49 # @Author : Elliott Zheng -# @FileName: setting.py +# @FileName: contraller.py # @Software: PyCharm import threading @@ -9,7 +9,8 @@ import pyperclip as smart_clipboard import regex as re -from pynput.keyboard import Key, Controller +from pynput.keyboard import Controller as KeyboardController +from pynput.keyboard import Key from config import Config from copyTranslator.focusframe import FocusFrame @@ -56,10 +57,10 @@ def check_contain_chinese(check_str): return False -class Setting(): +class Controller(): def __init__(self): # Collect events until released - self.keyboard = Controller() + self.keyboard = KeyboardController() self.ori_x = 0 self.ori_y = 0 self.t1 = time.time() @@ -132,6 +133,8 @@ def ToWriting(self, event): def save_config(self): self.config['focus_x'], self.config['focus_y'] = self.subFrame.GetPosition() + if self.config['focus_y'] < 0: + self.config['focus_y'] = 0 self.config['focus_width'], self.config['focus_height'] = self.subFrame.GetSize() self.config.source, self.config.target = self.get_src_target() self.config.save() @@ -277,13 +280,15 @@ def AutoHide(self, event=False): else: # 收起 x, y_now = frame.GetPosition() # 不贴边不自动收起 - if (y_now > 0 or not self.config.autohide) and event is not None: + if (y_now > 0 or not self.config.autohide) and event is not False: return _, height = frame.GetSize() target = -height + 10 while (y_now >= target): frame.SetPosition((x, y_now)) y_now -= 2 + if event == False: + self.mainFrame.SetFocus() except: pass @@ -296,14 +301,14 @@ def OnTaskBarLeftDClick(self, event): frame.Raise() def BossKey(self, evt): - value = self.config.frame_mode - if value == FrameMode.main: - frame = self.mainFrame - elif value == FrameMode.focus: - frame = self.subFrame - else: - frame = self.writingFrame - + # value = self.config.frame_mode + # if value == FrameMode.main: + # frame = self.mainFrame + # elif value == FrameMode.focus: + # frame = self.subFrame + # else: + # frame = self.writingFrame + frame = self.get_current_frame() frame.Iconize(not frame.IsIconized()) if not frame.IsIconized(): @@ -399,3 +404,4 @@ def switch_hide(self, event): def switch_show(self, event): self.config.autoshow = not self.config.autoshow + diff --git a/copyTranslator/mainframe.py b/copyTranslator/mainframe.py index 95a1ec68..f4409896 100644 --- a/copyTranslator/mainframe.py +++ b/copyTranslator/mainframe.py @@ -20,6 +20,7 @@ def __init__(self, setting): self.SetIcon(wx.Icon(logopath, wx.BITMAP_TYPE_ICO)) self.SetWindowStyle(MainFrame.mainStyle) + # self.SetMinSize((465, 385)) self.setting = setting self.lang = self.setting.lang TextPanel = wx.Panel(self, -1) @@ -45,6 +46,14 @@ def __init__(self, setting): self.continusCheck = wx.CheckBox(buttonPanel, -1, self.lang('Incremental Copy')) self.Bind(wx.EVT_CHECKBOX, self.setting.ReverseContinus, self.continusCheck) + # 贴边隐藏 + self.hideCheck = wx.CheckBox(buttonPanel, -1, self.lang('Auto Hide')) + self.Bind(wx.EVT_CHECKBOX, self.setting.switch_hide, self.hideCheck) + + # 自动显示 + self.showCheck = wx.CheckBox(buttonPanel, -1, self.lang('Auto Show')) + self.Bind(wx.EVT_CHECKBOX, self.setting.switch_show, self.showCheck) + # 连续复制模式 self.dictCheck = wx.CheckBox(buttonPanel, -1, self.lang('Smart Dict')) self.Bind(wx.EVT_CHECKBOX, self.setting.ReverseDict, self.dictCheck) @@ -91,9 +100,10 @@ def __init__(self, setting): TextPanel.SetSizer(panel1sizer) - panel2sizer = wx.FlexGridSizer(13, 1, 6, 0) + panel2sizer = wx.FlexGridSizer(15, 1, 6, 0) panel2sizer.AddMany( [self.topCheck, self.listenCheck, self.copyCheck, self.dictCheck, self.continusCheck, self.detectCheck, + self.hideCheck, self.showCheck, self.fromlabel, self.fromchoice, tolabel, self.tochoice, self.switchBtn, self.transBtn, self.copyBtn]) @@ -103,13 +113,15 @@ def __init__(self, setting): panel2sizer.AddGrowableRow(3, 0) panel2sizer.AddGrowableRow(4, 0) panel2sizer.AddGrowableRow(5, 0) - # panel2sizer.AddGrowableRow(6, 0) + panel2sizer.AddGrowableRow(6, 0) panel2sizer.AddGrowableRow(7, 0) - # panel2sizer.AddGrowableRow(8, 0) + #panel2sizer.AddGrowableRow(8, 0) panel2sizer.AddGrowableRow(9, 0) - panel2sizer.AddGrowableRow(10, 0) + #panel2sizer.AddGrowableRow(10, 0) panel2sizer.AddGrowableRow(11, 0) panel2sizer.AddGrowableRow(12, 0) + panel2sizer.AddGrowableRow(13, 0) + panel2sizer.AddGrowableRow(14, 0) buttonPanel.SetSizer(panel2sizer) diff --git a/copyTranslator/mypanel.py b/copyTranslator/mypanel.py index fcfe9060..75524970 100644 --- a/copyTranslator/mypanel.py +++ b/copyTranslator/mypanel.py @@ -31,10 +31,10 @@ def __init__(self, parent, setting=None): def OnLeftDClick(self, evt): # self.parentFrame.setting.ChangeMode(evt) - if self.setting.config.autohide: - self.setting.AutoHide(False) - else: - self.setting.get_current_frame().OnIconfiy(evt) + # if self.setting.config.autohide: + self.setting.AutoHide(False) + # else: + # self.setting.get_current_frame().OnIconfiy(evt) def OnLeftDown(self, evt): self.CaptureMouse() diff --git a/copyTranslator/shortcut.bat b/copyTranslator/shortcut.bat index 090ae59d..d0ade52d 100644 --- a/copyTranslator/shortcut.bat +++ b/copyTranslator/shortcut.bat @@ -8,7 +8,7 @@ set Program=%~dp0CopyTranslator.exe ::ÿݷʽƣѡ -set LnkName=Copy Translator +set LnkName=CopyTranslator @@ -20,7 +20,7 @@ set WorkDir=%~dp0 ::ÿݷʽʾ˵ѡ -set Desc=Copy, translate and paste with Google translate API. +set Desc=Foreign language assisted reading and translation solution diff --git a/copyTranslator/taskbar.py b/copyTranslator/taskbar.py index 8891bf69..14e30f40 100644 --- a/copyTranslator/taskbar.py +++ b/copyTranslator/taskbar.py @@ -34,6 +34,7 @@ class TaskBarIcon(wx.adv.TaskBarIcon): ID_ENGLISH = wx.NewId() ID_Hide = wx.NewId() ID_Format = wx.NewId() + ID_AutoShow = wx.NewId() def __init__(self, setting): self.setting = setting @@ -60,6 +61,7 @@ def __init__(self, setting): self.Bind(wx.EVT_MENU, self.OnLanguage, id=self.ID_ENGLISH) self.Bind(wx.EVT_MENU, self.OnLanguage, id=self.ID_CHINESE) self.Bind(wx.EVT_MENU, self.setting.switch_hide, id=self.ID_Hide) + self.Bind(wx.EVT_MENU, self.setting.switch_show, id=self.ID_AutoShow) def OnLanguage(self, event): if event.Id == self.ID_ENGLISH: @@ -73,13 +75,14 @@ def OnExchange(self, event): def OnAbout(self, event): UpdateThread(self.setting).start() box = wx.MessageDialog(self.setting.get_current_frame(), - 'If you found it useful, please give me a star on GitHub or introduce to your friend.\n\n如果您感觉本软件对您有所帮助,请在项目Github上给个star或是介绍给您的朋友,谢谢。\n\n 本软件免费开源,如果您是以付费的方式获得本软件,那么你应该是被骗了。[○・`Д´・ ○]', + 'If you found it useful, please give me a star on GitHub or introduce to your friend.\n\n如果您感觉本软件对您有所帮助,请在项目Github上给个star或是介绍给您的朋友,谢谢。\n\n本软件免费开源,如果您是以付费的方式获得本软件,那么你应该是被骗了。[○・`Д´・ ○]\n\n前往软件官网?', project_name + ' ' + version + ' by Elliott Zheng', wx.YES_NO | wx.ICON_QUESTION) answer = box.ShowModal() if answer == wx.ID_YES: webbrowser.open(project_url) box.Destroy() + # 右键菜单 def CreatePopupMenu(self): menu = wx.Menu() @@ -106,6 +109,9 @@ def CreatePopupMenu(self): hide = menu.AppendCheckItem(self.ID_Hide, self.lang('Auto Hide'), 'Auto Hide') hide.Check(self.setting.config.autohide) + autoShow = menu.AppendCheckItem(self.ID_AutoShow, self.lang('Auto Show'), 'Auto Show') + autoShow.Check(self.setting.config.autoshow) + # hide = menu.AppendCheckItem(self.ID_Format, self.lang('Auto Formation'), 'Auto Hide') # hide.Check(self.setting.config.autohide) diff --git a/copyTranslator/update_checker.py b/copyTranslator/update_checker.py index 5aef2c5b..2352885f 100644 --- a/copyTranslator/update_checker.py +++ b/copyTranslator/update_checker.py @@ -16,7 +16,7 @@ def load_log(filepath): - myfile = open(filepath, 'r') + myfile = open(filepath, 'r', encoding='UTF-8') lines = myfile.readlines() log = '' for line in lines: @@ -41,7 +41,6 @@ def check(setting): new_version = version_value['version'] if new_version <= version: return - update_log = version_value['update_log'] box = wx.MessageDialog(setting.get_current_frame(), levels_log[version_value[ diff --git a/copyTranslator/update_log.txt b/copyTranslator/update_log.txt index e72c56a9..4d8000c9 100644 --- a/copyTranslator/update_log.txt +++ b/copyTranslator/update_log.txt @@ -1,4 +1,14 @@ -v0.0.6.1 Colorful Statusbar -1. fix the translation bug of v0.0.6.0 -2. colorful statusbar of focus mode +v0.0.7-Kylin-RC0 +1. 在任务栏图标右键菜单中可以选择界面语言(English/简体中文),重启CopyTranslator生效 +2. 当光标位于专注模式结果框中时Ctrl+Enter实现翻译(监听剪贴板时会复制框内文本,当不监听剪贴板时不复制拖拽的文本),Ctrl+B实现百度搜索框内内容,Ctrl+G实现Google搜索框内内容。 +3. 专注模式贴上边(Y坐标小于0)失去焦点后会自动隐藏,可设置,另外可设置翻译后自动显示。 +4. 自动显示:勾选此选项后,当专注模式处于收起状态,且监听到剪贴板变化,专注模式将自动展开。展开后想要收起结果框,请先点击一下结果框,后点击其他地方,如果贴边隐藏处于打开状态则结果框会收起。 +5. 双击闪区会收起窗口到顶部,不论窗口在哪里,不管是否开启贴边隐藏。 +6. 右击闪区可以快速开启和关闭监听剪贴板功能。 +7. 拖拽文本到专注模式框,可以直接得到翻译结果(监听剪贴板时会复制拖拽的文本,当不监听剪贴板时不复制拖拽的文本)。注意,如果你是从编辑器拖拽文本过来,编辑器里的文本是会消失的,相当于剪切,CopyTranslator不背这锅。 +8. 主模式改名为对照模式,并且可以调节大小了。 +9. 配置文件版本间变动很大,又因为如果配置文件不兼容软件将直接无法使用,影响用户体验,但处理兼容性会占用较长的时间,因此决定不向前兼容也不向后兼容,每次更新您的旧版本/新版本配置会消失。 +10. 版本号风格变更,取消第四位版本号,后续将以RCX标识小版本。 +11. 仅提供32位版本。(64位系统是可以使用32位版本的,后续就不再区分了) +12. 记忆专注模式的窗口大小,位置。 diff --git a/copyTranslator/version.json b/copyTranslator/version.json index b6e7b770..fa08d011 100644 --- a/copyTranslator/version.json +++ b/copyTranslator/version.json @@ -1,6 +1,6 @@ version={ - "version": "v0.0.6.0", + "version": "v0.0.7-Kylin-RC0", "install_url": "https://github.com/elliottzheng/CopyTranslator/wiki/Downloads-%E4%B8%8B%E8%BD%BD%E4%B8%8E%E5%AE%89%E8%A3%85", - "update_log": "v0.0.6.1 Colorful Statusbar\n1. fix the translation bug of v0.0.6.0\n2. colorful statusbar of focus mode\n\n", + "update_log": "v0.0.7-Kylin-RC0\n1. \u5728\u4efb\u52a1\u680f\u56fe\u6807\u53f3\u952e\u83dc\u5355\u4e2d\u53ef\u4ee5\u9009\u62e9\u754c\u9762\u8bed\u8a00\uff08English/\u7b80\u4f53\u4e2d\u6587\uff09\uff0c\u91cd\u542fCopyTranslator\u751f\u6548\n2. \u5f53\u5149\u6807\u4f4d\u4e8e\u4e13\u6ce8\u6a21\u5f0f\u7ed3\u679c\u6846\u4e2d\u65f6Ctrl+Enter\u5b9e\u73b0\u7ffb\u8bd1\uff08\u76d1\u542c\u526a\u8d34\u677f\u65f6\u4f1a\u590d\u5236\u6846\u5185\u6587\u672c\uff0c\u5f53\u4e0d\u76d1\u542c\u526a\u8d34\u677f\u65f6\u4e0d\u590d\u5236\u62d6\u62fd\u7684\u6587\u672c\uff09\uff0cCtrl+B\u5b9e\u73b0\u767e\u5ea6\u641c\u7d22\u6846\u5185\u5185\u5bb9\uff0cCtrl+G\u5b9e\u73b0Google\u641c\u7d22\u6846\u5185\u5185\u5bb9\u3002\n3. \u4e13\u6ce8\u6a21\u5f0f\u8d34\u4e0a\u8fb9\uff08Y\u5750\u6807\u5c0f\u4e8e0\uff09\u5931\u53bb\u7126\u70b9\u540e\u4f1a\u81ea\u52a8\u9690\u85cf\uff0c\u53ef\u8bbe\u7f6e\uff0c\u53e6\u5916\u53ef\u8bbe\u7f6e\u7ffb\u8bd1\u540e\u81ea\u52a8\u663e\u793a\u3002\n4. \u81ea\u52a8\u663e\u793a\uff1a\u52fe\u9009\u6b64\u9009\u9879\u540e\uff0c\u5f53\u4e13\u6ce8\u6a21\u5f0f\u5904\u4e8e\u6536\u8d77\u72b6\u6001\uff0c\u4e14\u76d1\u542c\u5230\u526a\u8d34\u677f\u53d8\u5316\uff0c\u4e13\u6ce8\u6a21\u5f0f\u5c06\u81ea\u52a8\u5c55\u5f00\u3002\u5c55\u5f00\u540e\u60f3\u8981\u6536\u8d77\u7ed3\u679c\u6846\uff0c\u8bf7\u5148\u70b9\u51fb\u4e00\u4e0b\u7ed3\u679c\u6846\uff0c\u540e\u70b9\u51fb\u5176\u4ed6\u5730\u65b9\uff0c\u5982\u679c\u8d34\u8fb9\u9690\u85cf\u5904\u4e8e\u6253\u5f00\u72b6\u6001\u5219\u7ed3\u679c\u6846\u4f1a\u6536\u8d77\u3002\n5. \u53cc\u51fb\u95ea\u533a\u4f1a\u6536\u8d77\u7a97\u53e3\u5230\u9876\u90e8\uff0c\u4e0d\u8bba\u7a97\u53e3\u5728\u54ea\u91cc\uff0c\u4e0d\u7ba1\u662f\u5426\u5f00\u542f\u8d34\u8fb9\u9690\u85cf\u3002\n6. \u53f3\u51fb\u95ea\u533a\u53ef\u4ee5\u5feb\u901f\u5f00\u542f\u548c\u5173\u95ed\u76d1\u542c\u526a\u8d34\u677f\u529f\u80fd\u3002\n7. \u62d6\u62fd\u6587\u672c\u5230\u4e13\u6ce8\u6a21\u5f0f\u6846\uff0c\u53ef\u4ee5\u76f4\u63a5\u5f97\u5230\u7ffb\u8bd1\u7ed3\u679c(\u76d1\u542c\u526a\u8d34\u677f\u65f6\u4f1a\u590d\u5236\u62d6\u62fd\u7684\u6587\u672c\uff0c\u5f53\u4e0d\u76d1\u542c\u526a\u8d34\u677f\u65f6\u4e0d\u590d\u5236\u62d6\u62fd\u7684\u6587\u672c)\u3002\u6ce8\u610f\uff0c\u5982\u679c\u4f60\u662f\u4ece\u7f16\u8f91\u5668\u62d6\u62fd\u6587\u672c\u8fc7\u6765\uff0c\u7f16\u8f91\u5668\u91cc\u7684\u6587\u672c\u662f\u4f1a\u6d88\u5931\u7684\uff0c\u76f8\u5f53\u4e8e\u526a\u5207\uff0cCopyTranslator\u4e0d\u80cc\u8fd9\u9505\u3002\n8. \u4e3b\u6a21\u5f0f\u6539\u540d\u4e3a\u5bf9\u7167\u6a21\u5f0f\uff0c\u5e76\u4e14\u53ef\u4ee5\u8c03\u8282\u5927\u5c0f\u4e86\u3002\n9. \u914d\u7f6e\u6587\u4ef6\u7248\u672c\u95f4\u53d8\u52a8\u5f88\u5927\uff0c\u53c8\u56e0\u4e3a\u5982\u679c\u914d\u7f6e\u6587\u4ef6\u4e0d\u517c\u5bb9\u8f6f\u4ef6\u5c06\u76f4\u63a5\u65e0\u6cd5\u4f7f\u7528\uff0c\u5f71\u54cd\u7528\u6237\u4f53\u9a8c\uff0c\u4f46\u5904\u7406\u517c\u5bb9\u6027\u4f1a\u5360\u7528\u8f83\u957f\u7684\u65f6\u95f4\uff0c\u56e0\u6b64\u51b3\u5b9a\u4e0d\u5411\u524d\u517c\u5bb9\u4e5f\u4e0d\u5411\u540e\u517c\u5bb9\uff0c\u6bcf\u6b21\u66f4\u65b0\u60a8\u7684\u65e7\u7248\u672c/\u65b0\u7248\u672c\u914d\u7f6e\u4f1a\u6d88\u5931\u3002\n10. \u7248\u672c\u53f7\u98ce\u683c\u53d8\u66f4\uff0c\u53d6\u6d88\u7b2c\u56db\u4f4d\u7248\u672c\u53f7\uff0c\u540e\u7eed\u5c06\u4ee5RCX\u6807\u8bc6\u5c0f\u7248\u672c\u3002\n11. \u4ec5\u63d0\u4f9b32\u4f4d\u7248\u672c\u3002\uff0864\u4f4d\u7cfb\u7edf\u662f\u53ef\u4ee5\u4f7f\u752832\u4f4d\u7248\u672c\u7684\uff0c\u540e\u7eed\u5c31\u4e0d\u518d\u533a\u5206\u4e86\uff09\n12. \u8bb0\u5fc6\u4e13\u6ce8\u6a21\u5f0f\u7684\u7a97\u53e3\u5927\u5c0f\uff0c\u4f4d\u7f6e\u3002\n\n", "level": 3 } \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..4f46e642 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pyperclip +pynput \ No newline at end of file