我正在创建一个小脚本来检查我的gmail帐户中的邮件数量并将它们打印到 状态栏。函数gmail()返回新电子邮件的数量。我没有什么问题,但首先这是我迄今为止编写的代码(显然我是个新手):
class MyApplicationAppDelegate(NSObject):
var = 1
def applicationDidFinishLaunching_(self, sender):
NSLog("Application did finish launching.")
global ngmail
self.statusItem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength)
while var == 1 :
ngmail2 = gmail();
if ngmail2 !=ngmail:
self.statusItem.setTitle_("loading")
self.statusItem.setTitle_(ngmail2)
ngmail = ngmail2
time.sleep(6)
1)为什么我需要线路“self.statusItem.setTitle_(“加载”)?如果没有那条线,它就不会自动更新。我真的不知道为什么。在
2)它正常运行,但每当我接近状态栏中的数字时,就会出现旋转轮子。
我想原因是因为我使用while,而应该使用nsrunloop之类的东西。有人能对此提出建议吗?在
3)如果我让我的mac进入睡眠状态并唤醒它,脚本将停止工作。有什么解决办法吗?也许这和上面的问题2)有关。在
谢谢!
你所有的问题都是因为你阻塞了主线程。在
在Cocoa或几乎任何其他GUI框架中,主线程运行一个循环,该循环等待下一个事件,调用事件处理程序,并重复执行直到退出。在
事件处理程序
applicationDidFinishLaunching_
永远不会返回。这意味着可可永远无法处理下一个事件。最后,操作系统会注意到你没有反应,于是就提出了这个问题。在有了Cocoa,有时候每次你给它一个机会,它都会潜入一些其他事件,比如在
setTitle_
调用时,即使你没有响应,操作系统也可以伪造一些东西,比如重新绘制窗口,所以你的应用程序不响应并不总是很明显。但这并不意味着你不需要解决问题。在有很多方法可以做到这一点,但最简单的方法可能是使用后台线程。然后,ApplicationIDfinishLaunching_u可以启动后台线程,然后立即返回,从而允许主线程返回其作业处理事件。在
唯一棘手的是后台线程上运行的代码不能调用UI对象。那你怎么办?在
这就是^{} 的作用。在
下面是一个例子:
唯一棘手的一点是必须使用ObjC名称作为选择器(
setTitle:
),而不是Python名称(setTitle_
)。在但是,您的代码有另一个细微的缺陷:
var
实际上没有同步,所以您可以在主线程中更改它的值,而后台线程却没有注意到。在除此之外,执行
sleep(6)
意味着退出应用程序需要6秒钟,因为后台线程在完成睡眠之前不会到达检查var
的代码。在您可以使用
^{pr2}$Condition
来修复这两个问题。在(我假设您故意使用了
var
的class属性,而不是instance属性,因此我同样将condition设置为class属性,shutdown方法作为类方法。)相关问题 更多 >
编程相关推荐