01/10/2018, 13:53
Lỗi trôi thời gian khi dùng Timer threading
Chào cả nhà.
Em có tham khảo code ở đây:
https://stackoverflow.com/questions/474528/what-is-the-best-way-to-repeatedly-execute-a-function-every-x-seconds-in-python
Và ứng đây là code của em sử dung nó.
Vấn đề là sau khi click OK, 60 giây sau hàm Timer mới chạy. hichic.
Cả nhà giúp em với. Em cám ơn!
import sys
import os
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import matplotlib.pyplot as plt
import matplotlib.dates as dates
from matplotlib.backends.backend_qt4 import NavigationToolbar2QT as NavigationToolbar ## for pan in matplotlib
from Tkinter import *
import tkMessageBox
import subprocess
import time
from datetime import datetime
import threading
from threading import Thread
import pyodbc
from multiprocessing import Process, Event
from threading import Timer
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName(_fromUtf8("Form"))
Form.resize(710, 405)
self.lable_head = QtGui.QLabel(Form)
self.lable_head.setGeometry(QtCore.QRect(0, 0, 711, 51))
self.lable_head.setText(_fromUtf8(""))
self.lable_head.setPixmap(QtGui.QPixmap(_fromUtf8("doreamon.jpg")))
self.lable_head.setScaledContents(True)
self.lable_head.setObjectName(_fromUtf8("lable_head"))
self.tableWidget = QtGui.QTableWidget(Form)
self.tableWidget.setGeometry(QtCore.QRect(0, 100, 191, 261))
self.tableWidget.setObjectName(_fromUtf8("tableWidget"))
self.tableWidget.setColumnCount(2)
self.tableWidget.setRowCount(0)
item = QtGui.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(0, item)
item = QtGui.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(1, item)
self.label_1 = QtGui.QLabel(Form)
self.label_1.setGeometry(QtCore.QRect(70, 70, 91, 20))
self.label_1.setObjectName(_fromUtf8("label_1"))
self.label_2 = QtGui.QLabel(Form)
self.label_2.setGeometry(QtCore.QRect(470, 70, 53, 16))
self.label_2.setObjectName(_fromUtf8("label_2"))
self.graphicsView = QtGui.QGraphicsView(Form)
self.graphicsView.setGeometry(QtCore.QRect(210, 100, 491, 261))
self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
self.lineEdit = QtGui.QLineEdit(Form)
self.lineEdit.setGeometry(QtCore.QRect(0, 370, 521, 31))
self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
self.pushButton_ok = QtGui.QPushButton(Form)
self.pushButton_ok.setGeometry(QtCore.QRect(530, 370, 71, 28))
self.pushButton_ok.setObjectName(_fromUtf8("pushButton_ok"))
self.pushButton_exit = QtGui.QPushButton(Form)
self.pushButton_exit.setGeometry(QtCore.QRect(620, 370, 61, 28))
self.pushButton_exit.setObjectName(_fromUtf8("pushButton_exit"))
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(_translate("Form", "Form", None))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(_translate("Form", "x", None))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("Form", "y", None))
self.label_1.setText(_translate("Form", "Data table", None))
self.label_2.setText(_translate("Form", "matplotlib", None))
self.lineEdit.setText(_translate("Form", "Click Run", None))
self.pushButton_ok.setText(_translate("Form", "OK", None))
self.pushButton_exit.setText(_translate("Form", "Exit", None))
self.pushButton_ok.clicked.connect(self.launch_Thread_run)
self.pushButton_exit.clicked.connect(self.stop_thread)
def Runevery5min(self):
#
# function cal and update table and plot
#
self.lineEdit.setText("Calculate and update data every 5 minutes....")
t = datetime.now()
print (t)
def run(self):
t = datetime.now()
print (t)
# some funct to repare initial data
self.rt = RepeatedTimer(60, self.Runevery5min)
def launch_Thread_run(self):
self.r = threading.Thread(target=self.run())
self.r.start()
def stop_thread(self):
self.rt.stop()
self.lineEdit.setText("Stoped....")
class RepeatedTimer(object):
# Here's an update to the code from MestreLion that avoids drifiting over time
# https://stackoverflow.com/questions/474528/what-is-the-best-way-to-repeatedly-execute-a-function-every-x-seconds-in-python
def __init__(self, interval, function, *args, **kwargs):
self._timer = None
self.interval = interval
self.function = function
self.args = args
self.kwargs = kwargs
self.is_running = False
self.next_call = time.time()
self.start()
def _run(self):
self.is_running = False
self.start()
self.function(*self.args, **self.kwargs)
def start(self):
if not self.is_running:
self.next_call += self.interval
self._timer = threading.Timer(self.next_call - time.time(), self._run)
self._timer.start()
self.is_running = True
def stop(self):
self._timer.cancel()
self.is_running = False
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Form = QtGui.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
Bài liên quan
Tại vì nó phải chạy xong hàm
delayfunc
rồi mới excute. Mình không rành lắm về cái này nên không rõ có parameter nào hỗ trợ không. Thế nên bạn cứ run cái đó trước sau đó rồi hẵng dùng timer run.Do dòng này.
Bạn có thể làm theo cách thô thiển nhất, là chạy chương trình 1 lần trước đã, rồi mới bắt đầu gọi dòng này, hoặc tạo 1 biến là
checkFirstTime
để kiểm tra có phải lần đầu chạy chương trình hay không, nếu True thì chạy hàm ngay, nếu không thì đợi.P/s: 5 phút có bằng 60s đâu mà bạn để timer = 60s?
Em để 60s để test thử xem nó chạy thế nào trước đã. Vẫn chưa hiểu lắm cách anh chỉ.