问题
I'm writing a GUI application using Python and Qt as a GUI library. I would like to perform certain scheduled actions after e.g. 3 days or so (but some more often, some even more rare etc).
I have discovered the QTimer() app but my understanding is that it only tracks time while the software is running.
So, for example, suppose a user has checked the option to check the automatic updates every 5 days. If he runs it on day one, everything is fine. The countdown clock starts ticking. But if he runs it for the second time on day 6, how to make sure the application does indeed download an update (other than writing the date every time to some file and comparing the two)?
I hope I'm clear enough, if I'm not, please let me know and I'll try to elaborate even better.
回答1:
Either your app has to run all the time, eq. as a little systray icon on windows, or you need the operating system to run a version of your app regularly to check for updates.
What operating system are you using?
edit: on windows see this answer to get your program run at scheduled intervals Programmitically how to create task scheduler in windows server 2008
回答2:
Creating a scheduler outside of the running PyQt app is a bit outside the scope of PyQt itself, and is platform-dependant. Unless you create a second app that runs strictly as a Qt.WindowSystemMenuHint
in the system tray and actually performs the update separate of your main app.
So here is an example of something that records the updates in a QSettings
. Every time the app loads, it checks when the last update occurred, and whether we are overdue, or have time left. If there is time left, the timer will be adjusted appropriately for the difference:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.resize(150,150)
self._update_secs = 30
self.button = QtGui.QPushButton("Update")
self.button.setFixedSize(100,100)
self.setCentralWidget(self.button)
self.button.clicked.connect(self.doUpdate)
self._loadSettings()
def _loadSettings(self):
self._settings = QtCore.QSettings("mycompany", "myapp")
# checkpoint = self._settings.value('checkpoint')
lastUpdate = self._settings.value('lastUpdate')
now = QtCore.QDateTime.currentDateTimeUtc()
# update_time = 60*60*24*5
secs = self._update_secs
if not lastUpdate.isNull():
secs = abs(lastUpdate.toDateTime().secsTo(now))
if secs >= self._update_secs:
print "Update is past due at load time"
self.doUpdate()
return
else:
print "Still %d seconds left from last load, until next update" % secs
self._startUpdateTimer(secs)
def doUpdate(self):
print "performing update!"
now = QtCore.QDateTime.currentDateTimeUtc()
self._settings.setValue("lastUpdate",now)
self._startUpdateTimer(self._update_secs)
def _startUpdateTimer(self, secs):
print "Starting update timer for %d seconds" % secs
try:
self._updateTimer.stop()
except:
pass
self._updateTimer = QtCore.QTimer()
self._updateTimer.timeout.connect(self.doUpdate)
self._updateTimer.start(secs*1000)
if __name__ == "__main__":
app = QtGui.QApplication([])
win = Window()
win.show()
app.exec_()
You can try loading this up, closing it soon after, and reloading it. It should report that there is still time left. Once an update occurs, you can close it and wait past the 30 second deadline, then open. It should say the update is overdue.
来源:https://stackoverflow.com/questions/13096650/check-something-at-regular-intervals-in-a-python-qt-application