Python 如何在pyobjc中生成线程

Python 如何在pyobjc中生成线程,python,grand-central-dispatch,pyobjc,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 bu

我正在学习如何使用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)
因此,我将其转换为调用objective-c函数的pyobjc规则:

detachNewThreadSelector\u aSelector\u ataTarget\u anaargument\u(self.threadedFunc,self,1)

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

(void)detachNewThreadSelector:(SEL)aSelector
                   toTarget:(id)aTarget
                 withObject:(id)anArgument
@objc.IBAction
def buttonPress(self, sender):
    detachNewThreadSelector_aSelector_aTarget_anArgument_(self.threadedFunc, self, 1)
但当按下按钮时,我会收到以下消息:全局名称“detachNewThreadSelector\u aSelector\u aTarget\u anArgument\u”未定义

我也尝试过使用grand central dispatch进行类似的尝试,但相同的消息不断出现,即全局名称
某些\u grand\u central\u函数未定义


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

detachNewThreadSelector_toTarget_withObject_(aSelector, aTarget, anArgument)
您当前正在将转换规则应用于参数部分,而不是Objective-C调用部分。使用示例中的参数调用函数:

detachNewThreadSelector_toTarget_withObject_(self.threadedFunc, self, 1)

所以我得到了我想要的结果,按照下面的结构。正如我在回复评论时所说:对于后台线程,NSThread将不允许您执行某些任务。(即更新某些UI元素、打印等)。因此,我使用
performSelectorOnMainThread\u with object\u waitUntilDone\u
来处理线程操作之间需要执行的操作。操作时间短,强度低,因此对性能影响不大。谢谢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()
def someFunc(self):
i=0
someSelector=objc.selector(self.someSelector,signature='v@'))
而我<20:
self.performSelectorOnMainThread_with object_waitUntilDone(someSelector,None,False)
NSLog(u“你好,我在someFunc”)
i=i+1
@objc.IBAction
def按钮按下(自身、发送器):
NSThread.detachNewThreadSelector_到带有对象_的目标_(self.threadedFunc,self,1)
def threadedFunc(自):
NSLog(u“输入threadedFunc”)
self.t=NSTimer.NSTimer.scheduledTimerWithTimeInterval\u target\u selector\u userInfo\u repeats\u(1/150,self,self.someFunc,None,True)
NSLog(u“启动运行循环”)
self.t.fire()

我尝试了您的建议,但它仍然抛出未定义的错误全局名称。需要从NSThread调用它,但第一个参数是选择器:
NSThread.detachNewThreadSelector\u toTarget\u withObject(s,self,None)
其中
s=objc.selector(self.threadedFunc,signature='v@')
。如果函数有一个或多个参数或返回值,则签名应不同。更多的帮助可以在这里找到——哇,这对我来说是一个愚蠢的举动。谢谢你的帮助!但是,它仍然不能启动
threadedFunc
的NSLoopRun部分。它进入
threadedFunc
并退出,但似乎只是跳过
scheduledTimerWithTimeInterval\u target\u selector\u userInfo\u重复它的一部分。谢谢你提供的资源。我将查看该资源。NSTimer函数还需要一个选择器作为参数,前面评论中的链接与示例中的链接具有完全相同的功能。在我上一篇文章之前,我确实根据网站上的示例对我的结构进行了建模,并且出现了相同的行为。