如何在nautilus中设置快捷键以打开所选文件?

厌倦了右键单击打开以在特定应用程序中打开文件,我想设置一个快捷方式来打开文件,例如Gimp。 我不想更改默认的打开操作。 (Ubuntu 14.04)

我尝试了什么:

我已经设置了一个键盘快捷键来运行下面的脚本,在指定的应用程序(gimp)中打开所选的Nautilus文件。

!/bin/sh for file in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS do /usr/bin/gimp "$file" done 

和…

 !/bin/sh /usr/bin/gimp "$1" 

但它永远不会正确地在nautilus窗口中选择所选文件。

有没有办法做到这一点?

注意 :在这个答案中有两种解决方案,每种解决方案都有其自身的优点。 鼓励用户找出哪一种最适合他们的具体情况。

介绍

Nautilus本身并不提供定义自定义键盘快捷键及其操作的方法。 这是您尝试的脚本失败的主要原因。 $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS只能通过右键单击子菜单使用。 但我们可以利用其他东西来实现所需的结果 – 在设置和系统剪贴板中定义的快捷方式。

Nautilus内置称为Gtk工具包。 它是一个用于创建图形应用程序的扩展库,除此之外,它还具有与系统剪贴板连接的实用程序。 作为文件管理器的Nautilus特别之处在于它将一个URI列表(格式为file:///home/user/Pictures/encoded%image%name.png )输出到剪贴板(不是对大多数用户来说众所周知的事实,我最近也学到了很多东西。 显然,这是GUI文件管理器复制文件的方式。

我们可以通过复制文件的URI(或者确切地说,URI的列表;即使只有一个,它默认为列表)来利用这一事实。 然后我们可以将该列表传递给gimp 。 下面介绍的两种解决方案完全符合这一想法。

推理2个解决方案:

我个人认为解决方案#1是首选解决方案。 它依赖于首先手动按下复制快捷方式,然后是脚本快捷方式 – 这是两个键盘快捷方式 – 但它具有较少的依赖性。 这是一种更手动的方法,但相当不错。 它使用os.execlp调用,它将用Gimp替换脚本的进程,因此仅作为Gimp的跳板。 在脚本和系统编程中经常使用exec系列函数

第二个解决方案是因为Jacob Vlijm在评论中提到的,无论出于何种原因, execlp函数都不起作用。 我发现这很奇怪,因为execlp属于python的标准os模块,这是默认安装的模块之一。 另外, subprocess.Popen()默认为exec()系列函数; 来自subprocess文档:

在POSIX上,shell = False(默认值):在这种情况下,Popen类使用os.execvp()来执行子程序。 args通常应该是一个序列。 字符串将被视为一个序列,其中字符串作为唯一项(要执行的程序)。

(注意“On POSIX”表示“POSIX兼容操作系统”; Ubuntu符合POSIX标准)

因此,它似乎不是函数本身的问题,而是用户的系统。 不过,我写了第二个脚本。 那个使用subprocess xdotool模块并依赖于xdotool ,它基本上会自动按下Ctrl + C快捷键,然后启动Gimp。 我个人不喜欢这个,因为它需要安装额外的项目,但它只需要一个键盘快捷键。

然而,这个想法是一样的。 我们仍然使用Gtk工具来查询剪贴板内容,并且在每种情况下,必须将脚本绑定到快捷方式。

解决方案#1,两个快捷方式,最小依赖项

用法:选择文件并按Ctrl + C先复制文件,然后按您分配给该脚本的快捷方式。 execlp函数将用gimp替换脚本的进程。

 #!/usr/bin/env python3 # -*- coding: utf-8 -*- from gi.repository import Gtk, Gdk from os import execlp from time import sleep from urllib.parse import unquote import signal import threading import subprocess uris = None def autoquit(): global uris #sleep(0.5) while not uris: # allow sufficient time to obtain uris sleep(2) pass Gtk.main_quit() def get_clipboard_contents(): global uris clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) tr = threading.Thread(target=autoquit) tr.daemon = True tr.start() uris = clip.wait_for_uris() Gtk.main() return [unquote(i).replace('file://','') for i in uris] def main(): signal.signal(signal.SIGINT,signal.SIG_DFL) files = get_clipboard_contents() print(files) args = ['gimp'] + files execlp('gimp',*args) if __name__ == '__main__': main() 

解决方案#2:单一快捷方式,xdotool依赖项

此脚本的用法更简单:在Nautilus中选择文件并按键盘快捷键。 注意 :您必须安装xdotool才能使用,使用sudo apt-get install xdotool

 #!/usr/bin/env python3 # -*- coding: utf-8 -*- from gi.repository import Gtk, Gdk from subprocess import Popen,STDOUT from time import sleep from urllib.parse import unquote import sys def unquote_uri(*args): uris = args[-2] unquoted_args = [ str(unquote(i).replace('file://','')) for i in uris] with open('/dev/null','w') as dev_null: proc = Popen(['gimp',*unquoted_args],stdout=dev_null,stderr=STDOUT) Gtk.main_quit() def main(): # NOTE: xdotool is REQUIRED for this to work Popen(['xdotool','key','Ctrl+c']) sleep(0.5) clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) clip.request_uris(unquote_uri, None) Gtk.main() if __name__ == '__main__': main() 

设置快捷方式

在这两种情况下,您都需要将脚本链接到快捷方式。 打开系统设置 – >键盘 – >快捷方式 – >自定义。 单击+按钮。 将完整(!)路径作为命令提供给file。 例如,/ /home/User_Name/bin/clipboard_launch.py

在此处输入图像描述

将快捷方式指定为合理的东西。 例如,由于我们正在调用Gimp,因此我已将脚本分配给Ctrl + Super + G.

从快捷方式打开特定应用程序中的选定文件

受@Serg(+1)概念的启发,有关如何实现它的不同方法:

剧本

 #!/usr/bin/env python3 import subprocess import pyperclip subprocess.call(["xdotool", "key", "Control_L+c"]) subprocess.Popen(["gimp", pyperclip.paste()]) 

如何使用

  1. 该脚本需要pyperclipxdotool (对于xdotool- less用法,请参阅注释):

    • 对于16.04+:

       sudo apt-get install python3-pyperclip xdotool 
    • 14.04:

       sudo apt-get install python3-pip xdotool sudo pip3 install pyperclip 
  2. 将脚本复制到空文件中,将其另存为open_ingimp.py

  3. 将其添加到短按键:选择:系统设置>“键盘”>“快捷方式”>“自定义快捷方式”。 单击“+”并添加命令:

     python3 /path/to/open_ingimp.py 

而已。 现在选择一个有效的文档,然后按快捷键。 该文件将在Gimp打开。

说明

  • Ctrl + C时 ,选择文件时,文件的路径将复制到剪贴板。 我们用以下方法模拟:

     subprocess.call(["xdotool", "key", "Control_L+c"]) 
  • 事实certificate, pythonpyperclip模块只是生成路径,在使用pyperclip.paste()时从file://剥离(这不会逐字地粘贴,但会在脚本中使路径可用)。
  • 然后我们需要让脚本做的就是运行命令以使用gimp打开文件。

     subprocess.Popen(["gimp", pyperclip.paste()]) 

笔记

  • 如果在按下快捷键之前按Ctrl + C在Gimp中打开文件是可以接受的,我们甚至可以将脚本缩短到几乎一行:

     #!/usr/bin/env python3 import subprocess import pyperclip subprocess.Popen(["gimp", pyperclip.paste()]) 

    这将使xdotool的安装xdotool不必要。

  • 我们可以打扮/改进脚本,当然只运行已定义的扩展,或使应用程序服从参数。 只是提一下。

  • 我们甚至可以设置多个选项:使用应用程序1打开文件类型A,使用application2打开文件类型B,不打乱打开文件的默认应用程序,或者弄乱右键单击选项。