I've searched internet for days but can figure out how to put this code to work. It's a very simple gui (made on Qt Designer) with a lcd and a button. I want it to on the press of the button to start the countdown from 180 seconds back. In the first moment i was able to make to button decrease in one the value but after trying so many different things nothing is working. Can someone help me please? Probably is something very simple. Thank you.
# -*- coding: utf-8 -*-
import sys
import time
from PyQt4 import QtCore, QtGui
from relogio import Ui_relogiocc
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_relogiocc()
self.ui.setupUi(self)
self.timer = QtCore.QTimer()
text = "%d:%02d" % (180/60,180 % 60)
self.ui.QLCDNumber.display(text)
self.timer.start(1000)
self.ui.iniciar.clicked.connect(self.updateTimerDisplay)
def updateTimerDisplay(self):
self.inicio = 180
while self.inicio != 0:
text = "%d:%02d" % (self.inicio/60,self.inicio % 60)
self.ui.QLCDNumber.display(text)
self.inicio - 1
else:
self.timer.stop()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = StartQT4()
myapp.show()
sys.exit(app.exec_())
It seems there are a number of things you are missing here.
Firstly, the timer emits a timeout()
signal whenever each timeout period completes. In your case, this is every one second. However, you're not connecting this signal to anything.
Secondly, your updateTimerDisplay
contains the following line:
self.inicio - 1
This reads the value of self.inicio
, subtracts 1 from it and then throws the result away. Because self.inicio
's value doesn't change your updateTimerDisplay
method goes into an infinite loop.
I'm guessing you meant
self.inicio -= 1
instead, which assigns the new value of self.inicio
back to itself.
Ultimately, however, it seems you're trying to use your updateTimerDisplay
method to start the timer, count it down and also update the display of the timer. I'd recommend breaking this method up to smaller methods.
Firstly, updateTimerDisplay
should only update the display of the timer:
def updateTimerDisplay(self):
text = "%d:%02d" % (self.inicio/60,self.inicio % 60)
self.ui.QLCDNumber.display(text)
Secondly, you'll want a method to start the timer. Something like the following should do:
def startTimer(self):
self.inicio = 180
self.updateTimerDisplay()
self.timer.start(1000)
Of course, you'll also need to connect your iniciar
button's clicked()
signal to this function, instead of to updateTimerDisplay
.
Finally, you'll need a method that handles a tick from the timer. Something like the following should do:
def timerTick(self):
self.inicio -= 1
self.updateTimerDisplay()
if self.inicio <= 0:
self.timer.stop()
You'll also need to connect the timeout()
signal of the timer to this function, using something like:
self.timer.timeout.connect(self.timerTick)
As it has been told in the other answers your code contains some obvious mistakes. Here you have a complete working example (the UI is not created via Designer) that resets properly the counter every time the button is clicked (i.e. stops the timer before starting it again. If you don't do that and click the Start
button before the timer has stopped then the counter counts faster for every button click).
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class MyMainWindow(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.central = QWidget(self)
self.hbox = QHBoxLayout(self.central)
self.lcd = QLCDNumber(self.central)
self.timer = QTimer(self)
self.start_time = 20
self.lcd.display("%d:%02d" % (self.start_time/60,self.start_time % 60))
self.start_button = QPushButton("Start", self.central)
self.hbox.addWidget(self.lcd)
self.hbox.addWidget(self.start_button)
self.setCentralWidget(self.central)
self.start_button.clicked.connect(self.restartTimer)
self.timer.timeout.connect(self.updateLCD)
def restartTimer(self):
# Reset the timer and the lcd
self.timer.stop()
self.start_time = 20
self.lcd.display("%d:%02d" % (self.start_time/60,self.start_time % 60))
# Restart the timer
self.timer.start(1000)
def updateLCD(self):
# Update the lcd
self.start_time -= 1
if self.start_time >= 0:
self.lcd.display("%d:%02d" % (self.start_time/60,self.start_time % 60))
else:
self.timer.stop()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
ui = MyMainWindow()
ui.show()
sys.exit(app.exec_())
There are multiple things wrong with your code. For starters, you wrote self.inicio - 1
instead of -= 1
, and you never actually use the Qtimer
you create. But ignoring that, the structure of your program isn't right: Currently you call updateTimerDisplay
when the user clicks your iniciar
button and loop in there until your countdown reaches zero. What you want to do is start the timer when the user clicks the button and connect the timer (actually its timeout
signal) to a method that just counts down one second and updates the display:
def startTimerDisplay(self):
""" set the countdown value and start the timer """
self.inicio = 180
self.timer.start(1000)
def updateTimerDisplay(self):
""" count down one second, set the text, and check if the timer should stop """
self.inicio -= 1
text = "%d:%02d" % (self.inicio/60,self.inicio % 60)
self.ui.QLCDNumber.display(text)
if self.inicio == 0:
self.timer.stop()
Alter your __init__
method to connect these functions like this:
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_relogiocc()
self.ui.setupUi(self)
self.timer = QtCore.QTimer()
text = "%d:%02d" % (180/60,180 % 60)
self.ui.QLCDNumber.display(text)
#connect the button to the start method ...
self.ui.iniciar.clicked.connect(self.startTimerDisplay)
#... and the timer to the update method
self.timer.timeout.connect(self.updateTimerDisplay)