Check something at regular intervals in a Python (Qt) application

只愿长相守 提交于 2019-12-31 04:10:54

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!