PyQt5:最小化 window 后 QTimer 不同步 (OSX)
PyQt5: QTimer out of sync after minimizing window (OSX)
我在使用 pyqt5 QTimer class 和 OSX 时遇到问题。
如果通过单击 window 左上角的黄色按钮将以下简单应用程序最小化,应用程序将按预期移动到停靠栏的右下角,并且计时器每秒增加一次。
奇怪的是,在大约 2:30 分钟后,计时器的计数速度极慢,假设每 10 秒一次。我怀疑这与OSX下的"freeze"或"sleep"模式有关?
我想要的是一个可靠的计时器,它可以每秒计数。 pyqt 下有没有我遗漏的一些技巧?
---- 编辑 ----
如果 window 失去焦点,也会发生这种情况。
#!/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
这可能与 OS X 的一项名为 "AppNap" 的功能有关,该功能将大幅减少定时器触发,甚至在应用程序之间同步它们,以节省电池寿命。
您可以使用以下命令在每个应用程序的基础上通过命令行将其关闭
defaults write <domain> NSAppSleepDisabled -bool YES
其中 <domain>
是您的应用程序包标识符。您甚至可以通过子流程在您的应用程序中调用它 - 这就是我所做的。
尽管这不是一个理想的解决方案,请考虑绕过计时器。根据您的实际用例,可能还有其他方法可以解决此问题。
除了@deets,这将是另一种可能的解决方案,它检查开始时间并使用增量来计算到该开始时间的偏移量。至少它现在对我有用:
#!/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_())
我在使用 pyqt5 QTimer class 和 OSX 时遇到问题。
如果通过单击 window 左上角的黄色按钮将以下简单应用程序最小化,应用程序将按预期移动到停靠栏的右下角,并且计时器每秒增加一次。
奇怪的是,在大约 2:30 分钟后,计时器的计数速度极慢,假设每 10 秒一次。我怀疑这与OSX下的"freeze"或"sleep"模式有关?
我想要的是一个可靠的计时器,它可以每秒计数。 pyqt 下有没有我遗漏的一些技巧?
---- 编辑 ----
如果 window 失去焦点,也会发生这种情况。
#!/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
这可能与 OS X 的一项名为 "AppNap" 的功能有关,该功能将大幅减少定时器触发,甚至在应用程序之间同步它们,以节省电池寿命。
您可以使用以下命令在每个应用程序的基础上通过命令行将其关闭
defaults write <domain> NSAppSleepDisabled -bool YES
其中 <domain>
是您的应用程序包标识符。您甚至可以通过子流程在您的应用程序中调用它 - 这就是我所做的。
尽管这不是一个理想的解决方案,请考虑绕过计时器。根据您的实际用例,可能还有其他方法可以解决此问题。
除了@deets,这将是另一种可能的解决方案,它检查开始时间并使用增量来计算到该开始时间的偏移量。至少它现在对我有用:
#!/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_())