我打算写一个程序,理想状态下可以进行全局快捷键控制。我看到windows下有的小伙伴写游戏挂或者全局热键的时候用到这个功能,但是苦苦在linux系统下没得相关的python的api。来看看一些资料
- Qt注册全局热键
- 用Python制作游戏外挂(下)
- Python 全局热键功能(多个) - 这个是windows下的。
然后实在在python自定的api上没得办法,就想到用bash来替代python的api。看到一个叫gsettings的linux命令,十分有趣,下面是引用脚本之家上的一句话
gsettings提供了对GSetings的命令行操作。GSetings实际上是一套高级API,用来操作dconf。今天小编将为大家带来的是gsettings简介及常用操作介绍!希望对大家会有帮助!有需要的朋友一起去看看吧
我们就先来看看这个有趣的命令吧[引]
gsettings list-schemas 显示系统已安装的不可重定位的schema
gsettings list-relocatable-schemas 显示已安装的可重定位的schema
gsettings list-children SCHEMA 显示指定schema的children,其中SCHEMA指xml文件中schema的id属性值,例如实例中的"org.lili.test.app.testgsettings"
gsettings list-keys SCHEMA 显示指定schema的所有项(key)
gsettings range SCHEMA KEY 查询指定schema的指定项KEY的有效取值范围
gsettings get SCHEMA KEY 显示指定schema的指定项KEY的值
gsettings set SCHEMA KEY VALUE 设置指定schema的指定项KEY的值为VALUE
gsettings reset SCHEMA KEY 恢复指定schema的指定项KEY的值为默认值
gsettings reset-recursively SCHEMA 恢复指定schema的所有key的值为默认值
gsettings list-recursively [SCHEMA]如果有SCHEMA参数,则递归显示指定schema的所有项(key)和值(value),如果没有SCHEMA参数,则递归显示所有schema的所有项(key)和值(value)
哈哈,大概就解决了,来看看我们全局快捷键的设置。
#使用get命令来获取自定义全局快捷键的重定位
$ gsettings get org.gnome.settings-daemon.plugins.media-keys custom-keybindings
#输出如下
[’/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/’, ‘/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/’, ‘/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom2/’]
#我们来看看自定义快捷键的属性
$ gsettings list-keys org.gnome.settings-daemon.plugins.media-keys.custom-keybinding
#输出如下
binding
command
name
#我们来查看一下我们设置的一个快捷键的值
$ gsettings get 'org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ binding '
#输出如下 其中< Primary>应该是标示的ctrl键
’ < Primary><Shift>v’
#来看看设置快捷键的命令
$ gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ binding '<Primary><Shift>z'
命令梳理清楚了,接下啦无非就是用python来拼接字符串罢了。
对了这里还要提一下subprocess的用法,之前一直是用的subprocess.call函数,其实他还有一个更加强大的命令行调用函数subprocess.Popen,下面是一个简单的例子。
import shlex
import subprocess
shell_cmd = '/bin/bash -c "gsettings get org.gnome.settings-daemon.plugins.media-keys custom-keybindings"'
cmd = shlex.split(shell_cmd) #shelx中的split和字符串自带的split不一样,在这里会将本例中的双引号部分作为一个字段
p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while p.poll() is None:
line = p.stdout.readline()
if line: # if have output
outs = json.loads(line.strip().decode().replace('\'','"'))
print('Subprogram output: [{}]'.format(outs))
for item in outs:
print('out:', item)
输出如下:
Subprogram output: [[’/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/’, ‘/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/’, ‘/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom2/’]]
out: /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/
out: /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/
out: /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom2/
好了,恭喜了得到我搞了一天的的代码,这个代码是做全局快捷键的配置,快来学习下
#!/usr/bin/env python3
import subprocess
import sys,os
name = sys.argv[1]
cmd = sys.argv[2]
binding = sys.argv[3]
# 配置参数初始化
firstname = "my_custom"
key = "org.gnome.settings-daemon.plugins.media-keys custom-keybindings"
get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
custom_key = key.replace(" ", ".")[:-1]+":"
relocal_path = "/"+key.replace(" ", "/").replace(".", "/")+"/"+firstname+'/'
array_str = get("gsettings get "+key)
shell_cmds = []
subkey_exists = False
command_result = array_str.lstrip("@as")
current = eval(command_result)
# print(current)
for item in current: #org.gnome.settings-daemon.plugins.media-keys.custom-keybinding
if os.path.basename(os.path.abspath(item)) == firstname:
# 修改命令
shell_cmds = []
subkey_exists = True
shell_cmds.append('gsettings set {0}{1} command {2}'.format(custom_key,item,cmd))
shell_cmds.append('gsettings set {0}{1} binding "{2}"'.format(custom_key,item,binding))
current.append(relocal_path)
if not subkey_exists:
shell_cmds = []
shell_cmds.append('gsettings set '+key+' "'+str(current)+'"'.format(key,))
shell_cmds.append('gsettings set {0}{1} name "{2}"'.format(custom_key,relocal_path,firstname))
shell_cmds.append('gsettings set {0}{1} command "{2}"'.format(custom_key,relocal_path,cmd))
shell_cmds.append('gsettings set {0}{1} binding "{2}"'.format(custom_key,relocal_path,binding))
for shell_cmd in shell_cmds:
# print(shell_cmd)
subprocess.call(["/bin/bash", "-c", shell_cmd])
exit(0)
以上代码我保存为set_custom_shortkey.py
运行一下
$ python set_custom_shortkey.py'abc' 'gnome-terminal' '<Shift><Alt>R'
shift+alt+r 终端显示出来了,哈哈,美滋滋的。
目前我还只是在linux系统的ubuntu上做了实验,其他版本还没有做实验,目前还不清楚是否linux所有的发行版本都实用。不过gsettings 是dconf的api,感觉还是挺通用的,毕竟每个系统肯定都有自己的api供大家操作,大同小异,旨在参考。
PS: 发现一个有趣的键盘操作库pyautogui
安装:
$ pip install pyautogui
# 我在‘import pyqutogui’的时候报错【ModuleNotFoundError: No module named 'Xlib'】,
#于是就安装了xlib,具体情况具体分析,可以参考其他博客安装,我这里只是提一下。命令如下:
$ pip install xlib
pyqutogui 操作可以参考这个PyAutoGUI 简介
欢迎留言交流。周六三点下班。
参考