如何使用 python 宏监控 Libreoffice 文档中的键盘输入?
How to monitor keyboard input in a Libreoffice document using a python macro?
请注意,这是一个自答题,仅供参考。
尽管进行了确定的搜索,但我还没有找到 python 的文档。
我不想为对话框中的特定元素创建侦听器,而是想“侦听”文本文档的键盘输入。如果看到某些键或组合,该对象将执行操作。
使用 Uno com.sun.star.awt XKeyListener
创建了以下代码后,我预计至少会看到它正在运行的一些指示。
import unohelper
from com.sun.star.awt import XKeyListener
def fs_listen(*args):
doc = XSCRIPTCONTEXT.getDocument()
desktop = XSCRIPTCONTEXT.getDesktop()
model = desktop.getCurrentComponent()
contr = model.getCurrentController()
url_current = doc.getLocation()
oEventListener = KeyListen(doc)
contr.addEventListener(oEventListener)
class KeyListen(unohelper.Base, XKeyListener):
def __init__(self, parent):
self.parent = parent
print("listener added")
def keyPressed( self, event ):
""" is invoked when a key has been pressed."""
print("event",event)
def keyReleased( self, event ):
""" is invoked when a key has been released."""
print("release",event)
代码将激活并且 运行 但在“添加侦听器”之后不会为键盘输入产生任何输出。
我哪里错了?
与直觉相反,向 CurrentController 添加 KeyListener 似乎并没有
做一个人会想的。它似乎准备文档接收输入,你会
想想,反正都会做。
将对键盘输入产生响应的函数是 XKeyHandler
.
虽然它没有作为 EventListener 添加,但它作为 KeyHandler 添加。
这个函数有它自己的怪癖,因为要取消它,你需要删除处理程序
oEventListener
的实例与用于启动它的实例完全相同。 oobasic 不是问题,
其中实例可以存储为“全局”,我假设,因为它是不可或缺的,所以它以某种方式维护或存储。
python 的问题是它不能以这种方式存储,除非有人读到这个,知道
的一种方式。它不会“泡菜”,关于如何储存它,我最后泡菜了。我可能错过了一些明显的东西。
我最终使用的解决方案是根据键盘使功能自动取消
输入。
警告:仅在 Linux
上进行了测试
可以通过从命令行启动 LibreOffice lowriter
然后 运行 来测试以下内容
与任何其他宏一样,以 Shift+Alt+Ctrl+k
终止
#!/usr/bin/python
import unohelper
from com.sun.star.awt import XKeyHandler
from com.sun.star.awt import Key
from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK
from com.sun.star.awt.MessageBoxType import INFOBOX
fs_fkeys={} # dictionary of keys to identify each key
for key in dir(Key):
fs_fkeys[getattr(Key, key)] = key
#Idiosyncrasies
# Shift_L, Ctrl_L, Alt_L are not reported as separate keys but are reported as modifiers
# 1,2 and 4 respectively. Shift_R and Ctrl_R are identical to their Left twins
# Alt_R (AltGr) is not reported and not a modifier.
# Super_R (Right Windows) is not reported but is a modifier, even though it doesn't modify any keys.
# It reports as modifier 8
# Super_L (Left Windows) is not reported and not a modifier.
# Caps_Lock and Num_Lock report as unidentified keys but not as modifiers.
# track key input with option of consuming the input (return True)
def fs_Tracker(*args):
doc = XSCRIPTCONTEXT.getDocument()
desktop = XSCRIPTCONTEXT.getDesktop()
global contr, oEventHandler
contr = desktop.getCurrentComponent().getCurrentController()
oEventHandler = KeyHandler(doc)
contr.addKeyHandler(oEventHandler)
mess = "Key tracker active\nTo deactivate close document or Shift+Alt+Ctrl K"
heading = "Key Tracker"
MessageBox(None, mess, heading, INFOBOX, BUTTONS_OK)
class KeyHandler( unohelper.Base, XKeyHandler ):
def __init__(self, parent):
self.parent = parent
return None
def Terminate ( self, event ):
mess = "Key tracker deactivated!"
heading = "Key Tracker"
MessageBox(None, mess, heading, INFOBOX, BUTTONS_OK)
contr.removeKeyHandler(oEventHandler)
def keyPressed( self, event ):
k = event.KeyCode
c = event.KeyChar.value
mods = event.Modifiers
# mods are additive
# 0 - None
# 1 - Shift
# 2 - Ctrl
# 4 - Alt
# 8 - Super_R
if c == "K" and mods == 7: #Shift+Ctrl+Alt+k
self.Terminate(None)
return True # Returning True consumes the key
# Thus assigning this macro to the same keyboard shortcut means that
# the macro is toggled On/Off by Shift+Alt+Ctrl+k
if k in fs_fkeys:
name = fs_fkeys[k]
else:
name = "Undefined"
print(name, k, c, mods)
return False
def keyReleased( self, event ):
return False
def MessageBox(ParentWindow, MsgText, MsgTitle, MsgType, MsgButtons):
ctx = XSCRIPTCONTEXT.getComponentContext()
sm = ctx.ServiceManager
si = sm.createInstanceWithContext("com.sun.star.awt.Toolkit", ctx)
mBox = si.createMessageBox(ParentWindow, MsgType, MsgButtons, MsgTitle, MsgText)
mBox.execute()
#List components that are accessible
g_exportedScripts = fs_Tracker,
请注意,这是一个自答题,仅供参考。 尽管进行了确定的搜索,但我还没有找到 python 的文档。
我不想为对话框中的特定元素创建侦听器,而是想“侦听”文本文档的键盘输入。如果看到某些键或组合,该对象将执行操作。
使用 Uno com.sun.star.awt XKeyListener
创建了以下代码后,我预计至少会看到它正在运行的一些指示。
import unohelper
from com.sun.star.awt import XKeyListener
def fs_listen(*args):
doc = XSCRIPTCONTEXT.getDocument()
desktop = XSCRIPTCONTEXT.getDesktop()
model = desktop.getCurrentComponent()
contr = model.getCurrentController()
url_current = doc.getLocation()
oEventListener = KeyListen(doc)
contr.addEventListener(oEventListener)
class KeyListen(unohelper.Base, XKeyListener):
def __init__(self, parent):
self.parent = parent
print("listener added")
def keyPressed( self, event ):
""" is invoked when a key has been pressed."""
print("event",event)
def keyReleased( self, event ):
""" is invoked when a key has been released."""
print("release",event)
代码将激活并且 运行 但在“添加侦听器”之后不会为键盘输入产生任何输出。
我哪里错了?
与直觉相反,向 CurrentController 添加 KeyListener 似乎并没有
做一个人会想的。它似乎准备文档接收输入,你会
想想,反正都会做。
将对键盘输入产生响应的函数是 XKeyHandler
.
虽然它没有作为 EventListener 添加,但它作为 KeyHandler 添加。
这个函数有它自己的怪癖,因为要取消它,你需要删除处理程序
oEventListener
的实例与用于启动它的实例完全相同。 oobasic 不是问题,
其中实例可以存储为“全局”,我假设,因为它是不可或缺的,所以它以某种方式维护或存储。
python 的问题是它不能以这种方式存储,除非有人读到这个,知道 的一种方式。它不会“泡菜”,关于如何储存它,我最后泡菜了。我可能错过了一些明显的东西。
我最终使用的解决方案是根据键盘使功能自动取消 输入。
警告:仅在 Linux
上进行了测试可以通过从命令行启动 LibreOffice lowriter
然后 运行 来测试以下内容
与任何其他宏一样,以 Shift+Alt+Ctrl+k
#!/usr/bin/python
import unohelper
from com.sun.star.awt import XKeyHandler
from com.sun.star.awt import Key
from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK
from com.sun.star.awt.MessageBoxType import INFOBOX
fs_fkeys={} # dictionary of keys to identify each key
for key in dir(Key):
fs_fkeys[getattr(Key, key)] = key
#Idiosyncrasies
# Shift_L, Ctrl_L, Alt_L are not reported as separate keys but are reported as modifiers
# 1,2 and 4 respectively. Shift_R and Ctrl_R are identical to their Left twins
# Alt_R (AltGr) is not reported and not a modifier.
# Super_R (Right Windows) is not reported but is a modifier, even though it doesn't modify any keys.
# It reports as modifier 8
# Super_L (Left Windows) is not reported and not a modifier.
# Caps_Lock and Num_Lock report as unidentified keys but not as modifiers.
# track key input with option of consuming the input (return True)
def fs_Tracker(*args):
doc = XSCRIPTCONTEXT.getDocument()
desktop = XSCRIPTCONTEXT.getDesktop()
global contr, oEventHandler
contr = desktop.getCurrentComponent().getCurrentController()
oEventHandler = KeyHandler(doc)
contr.addKeyHandler(oEventHandler)
mess = "Key tracker active\nTo deactivate close document or Shift+Alt+Ctrl K"
heading = "Key Tracker"
MessageBox(None, mess, heading, INFOBOX, BUTTONS_OK)
class KeyHandler( unohelper.Base, XKeyHandler ):
def __init__(self, parent):
self.parent = parent
return None
def Terminate ( self, event ):
mess = "Key tracker deactivated!"
heading = "Key Tracker"
MessageBox(None, mess, heading, INFOBOX, BUTTONS_OK)
contr.removeKeyHandler(oEventHandler)
def keyPressed( self, event ):
k = event.KeyCode
c = event.KeyChar.value
mods = event.Modifiers
# mods are additive
# 0 - None
# 1 - Shift
# 2 - Ctrl
# 4 - Alt
# 8 - Super_R
if c == "K" and mods == 7: #Shift+Ctrl+Alt+k
self.Terminate(None)
return True # Returning True consumes the key
# Thus assigning this macro to the same keyboard shortcut means that
# the macro is toggled On/Off by Shift+Alt+Ctrl+k
if k in fs_fkeys:
name = fs_fkeys[k]
else:
name = "Undefined"
print(name, k, c, mods)
return False
def keyReleased( self, event ):
return False
def MessageBox(ParentWindow, MsgText, MsgTitle, MsgType, MsgButtons):
ctx = XSCRIPTCONTEXT.getComponentContext()
sm = ctx.ServiceManager
si = sm.createInstanceWithContext("com.sun.star.awt.Toolkit", ctx)
mBox = si.createMessageBox(ParentWindow, MsgType, MsgButtons, MsgTitle, MsgText)
mBox.execute()
#List components that are accessible
g_exportedScripts = fs_Tracker,