2013-02-21 3 views
1

API로부터 정보를 가져와 파이썬 스크립트에 대한 액세스를 제공하는 컨텍스트 메뉴를 만드는 파이썬 스크립트를 만들고 있습니다. API 호출 한 조금 느린 실행되는 스레딩을 사용하려는 있지만 내 코드 스레딩을 구현하는 방법을 잘 모르겠습니다. 이 사이트를 스레딩 참조 용으로 사용하고 있습니다. http://www.ibm.com/developerworks/aix/library/au-threadingpython/ 코드의 논리를 이해합니다. 스레딩하려는 모든 메서드에 대한 스레딩 클래스를 작성하고 싶지 않습니다.for 루프에서 파이썬 스레딩

다음은 컨텍스트 메뉴를 만든 다음 반환 된 json을 구문 분석하는 클래스입니다. 실행 명령의 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

threading.Thread는 SyncsnippetsCommand의 기본 클래스 여야하지만 sublime_plugin.TextCommand 만 포함해야합니다. 나는 스레딩으로 약간만 연주했기 때문에 예외가있을 수 있습니다. – Octipi

+0

통찰력을 고맙게 생각하고 이해합니다. - 특정 시나리오에 대한 최선의 접근 방식을 찾고있을 때 실제로 스레딩을 구현하지 못했음을 알 수 있습니다. 감사. – gregwhitworth

답변

2

여기는 스레딩 기능이있는 간단한 Sublime Text 2 플러그인입니다. 그것이하는 것은 3 초 후에 Hello World!을 삽입하는 것입니다. 주목할 것은 3 초 동안 커서를 움직일 수 있다는 것입니다.

경우에 따라 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) 
+0

그래서이 스레드가 원하는 각 메서드에 대한 스레드를 처리하는 사용자 지정 클래스를 만들 필요가 의미합니까? 항상 도움을 주셔서 감사합니다. – gregwhitworth

+0

플러그인 작동 방식에 따라 다릅니다. 이 경우에는 하나의 스레드 만 사용할 수 있다고 생각합니다. 백그라운드에서 실행하려는 코드 블록으로 생각하십시오. Thread 클래스의 run 메소드에있는 것은 백그라운드에서 실행됩니다. 따라서 다른 메소드/함수를 호출 할 수 있어야합니다. 스레드 프로그래밍에서주의해야 할 중요한 점은 여러 스레드에서 상태가 수정되는 충돌입니다. 이 경우 문제가 될 것이라고 생각하지 않습니다. – Gohn67