【发布时间】:2019-04-27 09:58:12
【问题描述】:
我正在编写一个 PyQt 程序,我希望允许用户启动他们喜欢的编辑器来填写 TextEdit 字段。
所以目标是在 tmp 文件上从外部启动一个编辑器(比如 vim),并在编辑器关闭时,将其上下文放入 python 变量中。
我发现了一些类似的问题,例如Opening vi from Python、call up an EDITOR (vim) from a python script、invoke an editor ( vim ) in python。但它们都以类似于git commit 命令的“阻塞”方式工作。我追求的是一种“非阻塞”方式(因为它是一个 GUI),类似于zimwiki 中的“编辑源”功能。
我目前的尝试:
import os
import tempfile
import threading
import subprocess
def popenAndCall(onExit, popenArgs):
def runInThread(onExit, popenArgs):
tmppath=popenArgs[-1]
proc = subprocess.Popen(popenArgs)
# this immediately finishes OPENING vim.
rec=proc.wait()
print('# <runInThread>: rec=', rec)
onExit(tmppath)
os.remove(tmppath)
return
thread = threading.Thread(target=runInThread, args=(onExit, popenArgs))
thread.start()
return thread
def openEditor():
fd, filepath=tempfile.mkstemp()
print('filepath=',filepath)
def cb(tmppath):
print('# <cb>: cb tmppath=',tmppath)
with open(tmppath, 'r') as tmp:
lines=tmp.readlines()
for ii in lines:
print('# <cb>: ii',ii)
return
with os.fdopen(fd, 'w') as tmp:
cmdflag='--'
editor_cmd='vim'
cmd=[os.environ['TERMCMD'], cmdflag, editor_cmd, filepath]
print('#cmd = ',cmd)
popenAndCall(cb, cmd)
print('done')
return
if __name__=='__main__':
openEditor()
我认为它失败了,因为Popen.wait() 只等到编辑器打开,而不是直到它关闭。所以它没有从编辑器中捕获任何内容。
知道如何解决这个问题吗?谢谢!
编辑:
我发现这个answer 我猜是相关的。我正在尝试让os 等待process group,但它仍然无法正常工作。代码如下:
def popenAndCall(onExit, popenArgs):
def runInThread(onExit, popenArgs):
tmppath=popenArgs[-1]
proc = subprocess.Popen(popenArgs, preexec_fn=os.setsid)
pid=proc.pid
gid=os.getpgid(pid)
#rec=proc.wait()
rec=os.waitid(os.P_PGID, gid, os.WEXITED | os.WSTOPPED)
print('# <runInThread>: rec=', rec, 'pid=',pid, 'gid=',gid)
onExit(tmppath)
os.remove(tmppath)
return
thread = threading.Thread(target=runInThread, args=(onExit, popenArgs))
thread.start()
return thread
我假设这个gid=os.getpgid(pid) 给了我组的ID,而os.waitid() 等待组。我也试过os.waitpid(gid, 0),也没用。
我在正确的轨道上?
更新:
似乎对于某些有效的编辑器,例如xed。 vim 和 gvim 都失败了。
【问题讨论】:
-
我的
[os.environ['TERMCMD']是gnome-terminal。 将其上下文放入变量 python 我的意思是在文本编辑器中获取文本并将其保存,以便我可以将其粘贴到 GUI 小部件中。 (对于那些刚接触这个问题的人。)
标签: python pyqt subprocess