2015-06-02 23 views
0

我有pyqt5 QTimer類和OSX的使用問題。PyQt5:最小化窗口(OSX)後QTimer不同步

如果通過單擊窗口左上角的黃色按鈕使以下簡單應用程序最小化,應用程序將按預期方式移動到停靠欄的右下角,並且定時器每秒增加一次。

奇怪的是,大約2:30分鐘後,定時器減速極端減少,讓說每10秒。我懷疑這與OSX下的「凍結」或「睡眠」模式有關?

我想要的是一個可靠的計時器,每秒計數一次。 pyqt下有一些我不知道的技巧嗎?

----編輯----

這也會發生,如果窗口失去焦點。

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
import time 

from PyQt5.QtWidgets import * 
from PyQt5.QtCore import Qt, QTimer, pyqtSlot 


class Main(QWidget): 

    def __init__(self, parent=None): 
     super().__init__(parent) 
     self.seconds = 0 
     self.init_ui() 

    def init_ui(self): 
     self.timer = QTimer() 
     self.timer.setInterval(1000) 
     self.timer.setTimerType(Qt.PreciseTimer) 
     self.timer.timeout.connect(self.on_timer) 
     self.timer.start() 

    @pyqtSlot() 
    def on_timer(self): 
     self.seconds += 1 
     print(time.strftime("%H:%M:%S", time.gmtime(self.seconds))) 


if __name__ == '__main__': 
    import sys 

    app = QApplication(sys.argv) 

    screen = Main() 
    screen.show() 

    sys.exit(app.exec_()) 

我的一些系統信息:

Python: 3.4.3 
PyQt: 5.4.0 
OSX: 10.9.5 
uname -a: Darwin mac-pro 13.4.0 Darwin Kernel Version 13.4.0: Wed Mar 18 16:20:14 PDT 2015; root:xnu-2422.115.14~1/RELEASE_X86_64 x86_64 
+0

我迄今發現的是一個ThreadsafeTimer類形式https://github.com/robertsj/poropy/blob/master/pyqtgraph/ThreadsafeTimer.py。但是這仍然行不通。我認爲這可能與我作爲GUI程序員的技能有關。 – hetsch

回答

1

這可能與所謂的「AppNap」 OS X的功能,它會主動降低定時器觸發,並同步他們甚至應用程序之間,以節省電池壽命。

您可以通過命令行每個應用-基礎上使用命令

defaults write <domain> NSAppSleepDisabled -bool YES 

其中<domain>是您的應用程序捆綁標識符將其關閉。你甚至可以通過子進程在你的應用程序中調用它 - 這就是我所做的。

雖然這不是一個理想的解決方案,但考慮在計時器周圍工作。根據您的實際使用情況,可能有其他解決方法。

+0

謝謝@deets,我必須嘗試一下,但正如你所說,這不是一個理想的解決方案。但是我擔心它不是那個問題的理想解決方案...... – hetsch

+0

只是爲了讓你知道,我的用例就像是一個秒錶,用於跟蹤正在進行的項目的時間。 – hetsch

0

除了@deets,這將是另一種可能的解決方案,它檢查開始時間並使用delta來計算到該開始時間的偏移量。至少它現在的工作對我來說:

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
import time 
import os 

from datetime import datetime 

from PyQt5.QtWidgets import * 
from PyQt5.QtCore import Qt, QObject, QTimer, QThread, pyqtSlot, pyqtSignal 


class Main(QWidget): 

    def __init__(self, parent=None): 
     super().__init__(parent) 
     self.ellapsed_sec = 0 
     self.init_ui() 

    def init_ui(self): 
     self.timer = QTimer() 
     self.timer.setInterval(1000) 
     self.timer.setTimerType(Qt.PreciseTimer) 
     self.timer.timeout.connect(self.on_timer) 

     self.timestamp_start = datetime.now() 

     self.timer.start(1000) 

    @pyqtSlot() 
    def on_timer(self): 
     self.ellapsed_sec += 1 

     delta = datetime.now() - self.timestamp_start 
     delta = delta.total_seconds() 
     if self.ellapsed_sec != delta: 
      print('Using delta', delta) 
      self.ellapsed_sec = delta 

     print(time.strftime("%H:%M:%S", time.gmtime(self.ellapsed_sec))) 


if __name__ == '__main__': 
    import sys 

    app = QApplication(sys.argv) 

    screen = Main() 
    screen.show() 

    sys.exit(app.exec_())