python - 使用 python gui 中的按钮从以前选择的外部应用程序复制文本
问题描述
我正在尝试构建一个轻量级的 Text-to-Speech GUI,我可以在其中选择 Word 或 Chrome 中的文本,然后在我的 GUI 中按下一个按钮并让它读取它。
我已经弄清楚了创建 GUI 并让 TTS 工作的所有部分,但我无法正确设置外形尺寸。我试图模仿 Dragon Naturally speak 的文本到语音的形式因素,因为它很简单,而且我已经习惯了。
以下是我无法开始工作的用户故事中缺少的步骤,按顺序:
1) 用户使用鼠标突出显示应用程序中的文本(word、chrome、记事本等)并按下 gui 按钮
2) 来自外部应用程序的数据以 UTF-8 格式提取并存储在名为“text”的变量中
我知道有几个窗口可以选择文本存在问题。我的解决方案是从最近选择的窗口中提取选定的文本。
现在,笨拙的解决方法是 Ctrl-C 任何我想阅读的文本,然后按下按钮,因为我可以从剪贴板中提取数据,但这也是一种非常糟糕的用户体验和混乱。我尝试使用 pyperclip 获取将文本放入剪贴板的按钮,但它似乎不起作用,所以我不确定剪贴板的想法是否是死胡同。
def select_text(self):
#copy
pyperclip.copy() # doesn't work
#get text
win32clipboard.OpenClipboard()
text = win32clipboard.GetClipboardData()
win32clipboard.CloseClipboard()
#say it!
self.say_text(text)
我似乎在任何地方都找不到这样的东西,我不知道从哪里开始。任何帮助,将不胜感激。
解决方案
我想我想通了。这很丑陋,但它有效;我是编码的初学者,这对我来说只是一种爱好。老实说,我很高兴让它工作。
我已将命令绑定到 Alt_L+Q;稍后我可能会添加 Alt_R+Q,但我永远不会使用它们。出于某种原因,在没有 L 或 R 的情况下单独使用 Alt 是行不通的。
此外,如果没有第一个 sleep 语句,它根本不起作用。第二个睡眠声明是预防性的。
# set clipboard data
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText('No text is currently selected.')
win32clipboard.CloseClipboard()
text = None #this is what will be read
chg_rate = 0 #reading speed +/- 0.0 to 1.0
chg_vol = 0 #volume +/- 0.0 to 1.0
def get_text():
#current_window = win32gui.GetForegroundWindow()
import pythoncom
pythoncom.CoInitialize()
cw = win32com.client.Dispatch('WScript.Shell')
time.sleep(.7)
cw.SendKeys('^c') #copies text
time.sleep(.2)
#get text
win32clipboard.OpenClipboard()
text = win32clipboard.GetClipboardData()
win32clipboard.CloseClipboard()
return text
#define the hot key
def create_hotkey():
# The key combination to check
COMBINATIONS = [
{keyboard.Key.alt_l, keyboard.KeyCode(char='Q')},
{keyboard.Key.alt_l, keyboard.KeyCode(char='q')}
]
# The currently active modifiers
current = set()
def execute():
text = get_text()
if not isinstance(text, str):
text = "Selected input is not UTF-8 text."
say_text(text)
def on_press(key):
if any([key in COMBO for COMBO in COMBINATIONS]):
current.add(key)
if any(all(k in current for k in COMBO) for COMBO in COMBINATIONS):
execute()
def on_release(key):
if any([key in COMBO for COMBO in COMBINATIONS]):
current.remove(key)
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
#run hotkey
create_hotkey()
推荐阅读
- php - 使用 file_get_contents 发布 json
- javascript - Webpack4|Redux|React 问题 - 您可能需要适当的加载程序来处理此文件类型
- reactjs - 使用 react-moment 添加小时
- php - 在 yii 上不在对象上下文中时使用 $this
- laravel - 本地化属性不起作用
- c# - 我想从 webclient 实例获取源 IP 地址。
- python - 如何在 Django 中检查两个模型是否相等?
- database - 在基表中填充新 id 后插入
- ruby-on-rails - Ruby:QOS=1 的 paho-mqtt 会自动为我重新发送(重新发布)未确认的消息吗?
- deep-learning - 字符串的分类(修改)