如何在pyobjc中生成线程

时间:2015-08-11 16:46:34

标签: python grand-central-dispatch pyobjc

我正在学习如何使用pyobjc进行一些基本的原型设计。现在我有一个主UI设置和一个运行主应用程序的python脚本。唯一的问题是当脚本运行时,脚本在主线程上运行,从而阻止UI。

所以这是我的示例代码片段,我在python中尝试使用线程导入:

def someFunc(self):
    i = 0
    while i < 20:
        NSLog(u"Hello I am in someFunc")
        i = i + 1

@objc.IBAction
def buttonPress(self, sender):
    thread = threading.Thread(target=self.threadedFunc)
    thread.start()

def threadedFunc(self):
    NSLog(u"Entered threadedFunc")
    self.t = NSTimer.NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(1/150., self,self.someFunc,None, True)
    NSLog(u"Kicked off Runloop")
    NSRunLoop.currentRunLoop().addTimer_forMode_(self.t,NSDefaultRunLoopMode)

单击按钮时,threadedFunc中的NSLog将打印到控制台,但它永远不会进入someFunc

所以我决定使用NSThread开始一个帖子。在Apple的文档中,Objective-C调用如下所示:

(void)detachNewThreadSelector:(SEL)aSelector
                   toTarget:(id)aTarget
                 withObject:(id)anArgument

所以我将其翻译成我为pycjc调用objective-c函数的规则:

detachNewThreadSelector_aSelector_aTarget_anArgument_(self.threadedFunc, self, 1)

因此,在上下文中,IBAction函数如下所示:

@objc.IBAction
def buttonPress(self, sender):
    detachNewThreadSelector_aSelector_aTarget_anArgument_(self.threadedFunc, self, 1)

但是当按下按钮时,我收到以下消息:全局名称&#39; detachNewThreadSelector_aSelector_aTarget_anArgument _&#39;没有定义。

我也曾尝试使用大型中央调度进行类似的尝试,但同样的消息仍然没有定义全局名称some_grand_central_function

显然,我不了解python线程的细微差别,或pyobjc调用约定,我想知道是否有人可以阐明如何继续。

2 个答案:

答案 0 :(得分:2)

所以我得到了我想要遵循以下结构的结果。就像我在回复评论中所述:对于后台线程,NSThread不允许您执行某些任务。 (即更新某些UI元素,打印等)。所以我使用performSelectorOnMainThread_withObject_waitUntilDone_来完成我需要在线程操作之间执行的操作。这些操作很短,而且不是很密集,因此不会对性能产生太大影响。谢谢Michiel Kauw-A-Tjoe指出我正确的方向!

def someFunc(self):
    i = 0
    someSelector = objc.selector(self.someSelector, signature='v@:')
    while i < 20:
        self.performSelectorOnMainThread_withObject_waitUntilDone(someSelector, None, False)
        NSLog(u"Hello I am in someFunc")
        i = i + 1

@objc.IBAction
def buttonPress(self, sender):
    NSThread.detachNewThreadSelector_toTarget_withObject_(self.threadedFunc, self, 1)

def threadedFunc(self):
    NSLog(u"Entered threadedFunc")
    self.t = NSTimer.NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(1/150., self,self.someFunc,None, True)
    NSLog(u"Kicked off Runloop")
    self.t.fire()

答案 1 :(得分:0)

翻译的函数名称应为

Bitmap b = Bitmap.createBitmap(p.getWidth(), p.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
p.draw(c);
Paint paint = new Paint();
paint.setAlpha((int) (255 * g.opacity));
mCanvas.drawBitmap(b, 0, 0, paint);

您目前正在将转换规则应用于参数部分而不是Objective-C调用部分。使用示例中的参数调用函数:

detachNewThreadSelector_toTarget_withObject_(aSelector, aTarget, anArgument)