Issue
I am facing a problem while running the timers simultaneously one by one.The next timer is running and previous one get stopped and after reaching the time the previous one starts. The problematic code is listed below.
import time
from PyQt4 import QtCore, QtGui
import sys
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 Window(QtGui.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 300)
self.setWindowTitle("PyQT tuts!")
self.setWindowIcon(QtGui.QIcon('pythonlogo.png'))
self.home()
def home(self):
self.btn = QtGui.QPushButton(self)
self.btn.setObjectName(_fromUtf8("pb"))
self.btn.clicked.connect(self.timer)
self.btn.setText("Timer1")
self.btn.resize(65,25)
self.btn.move(100,100)
self.btn2 = QtGui.QPushButton(self)
self.btn2.setObjectName(_fromUtf8("pb2"))
self.btn2.clicked.connect(self.timer2)
self.btn2.setText("Timer2")
self.btn2.resize(65,25)
self.btn2.move(100,150)
self.btn3 = QtGui.QPushButton(self)
self.btn3.setObjectName(_fromUtf8("pb3"))
self.btn3.clicked.connect(self.timer3)
self.btn3.setText("Timer3")
self.btn3.resize(65,25)
self.btn3.move(100,200)
self.btn4 = QtGui.QPushButton(self)
self.btn4.setObjectName(_fromUtf8("pb4"))
self.btn4.clicked.connect(self.timer4)
self.btn4.setText("Timer4")
self.btn4.resize(65,25)
self.btn4.move(100,250)
self.show()
def timer(self):
# uin = input("enter the time : ")
when_to_stop = 10
# abs(int(uin))
while when_to_stop > 0:
m, s = divmod(when_to_stop, 60)
h, m = divmod(m, 60)
time_left = str(h).zfill(2) + ":" + str(m).zfill(2) + ":" + str(s).zfill(2)
# print(time_left+'\r')
time.sleep(1.0)
when_to_stop -= 1
self.btn.setText(str(time_left))
QtGui.qApp.processEvents()
def timer2(self):
# uin = input("enter the time : ")
when_to_stop = 10
# abs(int(uin))
while when_to_stop > 0:
m, s = divmod(when_to_stop, 60)
h, m = divmod(m, 60)
time_left = str(h).zfill(2) + ":" + str(m).zfill(2) + ":" + str(s).zfill(2)
# print(time_left+'\r')
time.sleep(1.0)
when_to_stop -= 1
self.btn2.setText(str(time_left))
QtGui.qApp.processEvents()
def timer3(self):
# uin = input("enter the time : ")
when_to_stop = 10
# abs(int(uin))
while when_to_stop > 0:
m, s = divmod(when_to_stop, 60)
h, m = divmod(m, 60)
time_left = str(h).zfill(2) + ":" + str(m).zfill(2) + ":" + str(s).zfill(2)
# print(time_left+'\r')
time.sleep(1.0)
when_to_stop -= 1
self.btn3.setText(str(time_left))
QtGui.qApp.processEvents()
def timer4(self):
# uin = input("enter the time : ")
when_to_stop = 10
# abs(int(uin))
while when_to_stop > 0:
m, s = divmod(when_to_stop, 60)
h, m = divmod(m, 60)
time_left = str(h).zfill(2) + ":" + str(m).zfill(2) + ":" + str(s).zfill(2)
# print(time_left+'\r')
time.sleep(1.0)
when_to_stop -= 1
self.btn4.setText(str(time_left))
QtGui.qApp.processEvents()
def run():
app = QtGui.QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
run()
Solution
time.sleep()
should not be used in the GUI because it will block the GUI eventloop causing problems like not updating the GUI, besides using input (), and consider bad practice calling processEvents()
.
Qt offers QTimer which is a class specialized in calling a specific task every certain interval of time.
In the next part I show an example:
import sys
from PyQt4 import QtCore, QtGui
from functools import partial
class Window(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
centralwidget = QtGui.QWidget()
self.setCentralWidget(centralwidget)
layout = QtGui.QVBoxLayout(centralwidget)
for i in range(4):
button = QtGui.QPushButton("Timer{}".format(i+1))
layout.addWidget(button)
button.clicked.connect(partial(self.onClicked, button))
def onClicked(self, button):
sec = 10 # seconds
timer = button.property("timer").toPyObject()
if timer is None:
timer = QtCore.QTimer(button)
timer.stop()
timer.setInterval(1000)
timer.setProperty("button", button)
timer.setProperty("endTime", QtCore.QTime.currentTime().addMSecs(sec*1000+10))
timer.timeout.connect(partial(self.onTimeout, timer))
self.onTimeout(timer)
timer.start()
button.setProperty("timer", timer)
def onTimeout(self, timer):
button= timer.property("button")
if hasattr(button, 'toPyObject'):
button = button.toPyObject()
tm = timer.property("endTime").toPyObject()
if hasattr(tm, 'toPyObject'):
tm = tm.toPyObject()
ms = QtCore.QTime.currentTime().msecsTo(tm)
if ms < 0:
timer.stop()
else:
button.setText(QtCore.QTime().addMSecs(ms).toString())
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = Window()
ex.show()
sys.exit(app.exec_())
Answered By - eyllanesc
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.