我正在创建一个python脚本,它从API中获取信息并创建一个上下文菜单,使您可以访问它们。我想使用线程,因为它在调用API时运行有点慢,但我不确定如何使用我的代码实现线程。我正在使用这个站点进行线程引用:http://www.ibm.com/developerworks/aix/library/au-threadingpython/我理解代码中的逻辑我不想为每个我想要线程化的方法编写一个线程类。
这是创建上下文菜单然后解析返回的json的类,我想我应该将它添加到run命令中的for循环中。非常感谢任何帮助。
class SyncsnippetsCommand(sublime_plugin.TextCommand):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def buildLexerDict(self,snippets):
lexers = snippets[0]['user']['lexers']
lexer_dict = {}
for lexer in lexers:
lexer_dict[lexer] = []
return lexer_dict
def buildsnippetsContextDict(self,snippets,lexer_dict):
snippets_dict = lexer_dict
for snippet in snippets:
snippets_dict[snippet['lexer']].append({"id":str(snippet['id']),
"title":snippet['title']})
return snippets_dict
def run(self, edit):
snippet_url = buildsnippetURL()
snippets_count = 1;
snippets = getsnippets(snippet_url)
context_menu = '['
context_menu += '\n\t{ "caption": "snippets", "id": "file", "children":'
context_menu += '\n\t\t['
if snippets == None:
{"caption":"No snippets available"}
else:
snippets = snippets['objects']
lexers = self.buildLexerDict(snippets)
snippets_dict = self.buildsnippetsContextDict(snippets, lexers)
for j,key in reversed(list(enumerate(reversed(snippets_dict.keys())))):
... loop through JSON and create menu ...
if j == 0:
context_menu += ''
else:
context_menu += ','
context_menu += '\n\t\t]'
context_menu += '\n\t}'
context_menu += '\n]'
f = open(sublime.packages_path() + '\snippetSync\\Context.sublime-menu', 'w')
f.write(context_menu)
f.close
self.view.set_status('snippet', 'snippet Sync: Added ' + str(snippets_count) + ' snippets from your account.')
sublime.set_timeout(lambda: self.view.erase_status('snippet'), 3000)
return
答案 0 :(得分:2)
这是一个带有线程的简单Sublime Text 2插件。它的作用是在3秒后插入Hello World!
。您会注意到,您仍然可以在这三秒钟内移动光标。
在您的情况下,看起来您只需要从API中获取一堆片段并从返回的数据创建上下文菜单。然后会在底部显示一条通知,告诉您添加了多少个代码段。我可能是错的,但您应该能够修改此代码以使您的插件正常工作。
import threading
import time
import sublime
import sublime_plugin
"""
The command just creates and runs a thread.
The thread will do all the work in the background.
Note that in your Thread constructor, you will need to pass in an
instance of your Command class to work with in your thread.
"""
class ExampleCommand(sublime_plugin.TextCommand):
def run(self, edit):
exampleThread = ExampleThread(self, edit)
exampleThread.start()
"""
Extend the Thread class and add your functionality in
the run method below.
One thing to remember when moving your code over is
you need to use self.cmd instead of self.
"""
class ExampleThread(threading.Thread):
"""
Remember to pass in the parameters you need
in this thread constructor.
"""
def __init__(self, cmd, edit):
threading.Thread.__init__(self)
self.cmd = cmd
self.edit = edit
"""
Add your functionality here.
If you need to access the main thread, you need to
use sublime.set_timeout(self.callback, 1).
In my example here, you can't call insert text into the editor
unless you are in the main thread.
Luckily that is fast operation.
Basically, time.sleep(3) is a slow operation and will block, hence it
is run in this separate thread.
"""
def run(self):
time.sleep(3)
sublime.set_timeout(self.callback, 1)
"""
This is the callback function that will be called to
insert HelloWorld.
You will probably need to use this to set your status message at
the end. I'm pretty sure that requires that you be on main thread
to work.
"""
def callback(self):
self.cmd.view.insert(self.edit, 0, "Hello, World!")
<强>更新强>
我发现有些时候使用上面概述的方法整合您的代码段。您仍然需要填写一些空白,但希望这可以让您了解代码的放置位置。我测试了基本骨架仍然有效,这就是为什么你在构建上下文菜单的部分在这个例子中被注释掉了。
import threading
import time
import sublime
import sublime_plugin
def buildsnippetURL():
return ""
def getsnippets(snippet_url):
time.sleep(3)
return ""
class SyncsnippetsCommand(sublime_plugin.TextCommand):
def run(self, edit):
syncsnippetsThread = SyncsnippetsThread(self, edit)
syncsnippetsThread.start()
class SyncsnippetsThread(threading.Thread):
def __init__(self, cmd, edit):
threading.Thread.__init__(self)
self.cmd = cmd
self.edit = edit
def buildLexerDict(self,snippets):
lexers = snippets[0]['user']['lexers']
lexer_dict = {}
for lexer in lexers:
lexer_dict[lexer] = []
return lexer_dict
def buildsnippetsContextDict(self,snippets,lexer_dict):
snippets_dict = lexer_dict
for snippet in snippets:
snippets_dict[snippet['lexer']].append({"id":str(snippet['id']),
"title":snippet['title']})
return snippets_dict
def run(self):
snippet_url = buildsnippetURL()
snippets_count = 1;
snippets = getsnippets(snippet_url)
"""
context_menu = '['
context_menu += '\n\t{ "caption": "snippets", "id": "file", "children":'
context_menu += '\n\t\t['
if snippets == None:
{"caption":"No snippets available"}
else:
snippets = snippets['objects']
lexers = self.buildLexerDict(snippets)
snippets_dict = self.buildsnippetsContextDict(snippets, lexers)
for j,key in reversed(list(enumerate(reversed(snippets_dict.keys())))):
... loop through JSON and create menu ...
if j == 0:
context_menu += ''
else:
context_menu += ','
context_menu += '\n\t\t]'
context_menu += '\n\t}'
context_menu += '\n]'
f = open(sublime.packages_path() + '\snippetSync\\Context.sublime-menu', 'w')
f.write(context_menu)
f.close
"""
sublime.set_timeout(lambda: self.callback(snippets_count), 1)
def callback(self, snippets_count):
self.cmd.view.set_status('snippet', 'snippet Sync: Added ' + str(snippets_count) + ' snippets from your account.')
sublime.set_timeout(lambda: self.cmd.view.erase_status('snippet'), 3000)