Reputation: 23
I am trying to make a PyQt timer application for a project. I have designed the layout using QtDesigner and I am almost finished with all the code. There is just one small problem. I want to make a stop button for my timer, but everytime I make it the timer resets itself as soon as I press start again. I want it to continue as long as the timer has not already timed out. I did partially fix it once, meaning the timer did continue, but the problem with that was that the numbers went into the negatives instead of just stopping on zero. I am very new to Python and even more so to PyQt, so I am sorry if the solution seems obvious (I spent days trying to figure it out).
Anyways here is the code (the one where it resets itself):
from PyQt4 import QtCore, QtGui
import time
from PyQt4.QtCore import pyqtSlot,SIGNAL,SLOT
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_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(351, 200)
MainWindow.setMinimumSize(QtCore.QSize(0, 200))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(_fromUtf8("../../../Pictures/clock-icon-md.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
MainWindow.setWindowIcon(icon)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.gridLayout = QtGui.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.display = QtGui.QLCDNumber(self.centralwidget)
font = QtGui.QFont()
font.setKerning(True)
self.display.setFont(font)
self.display.setLayoutDirection(QtCore.Qt.LeftToRight)
self.display.setAutoFillBackground(False)
self.display.setFrameShape(QtGui.QFrame.Box)
self.display.setFrameShadow(QtGui.QFrame.Raised)
self.display.setMidLineWidth(-2)
self.display.setSmallDecimalPoint(False)
self.display.setNumDigits(5)
self.display.setDigitCount(5)
self.display.setMode(QtGui.QLCDNumber.Dec)
self.display.setSegmentStyle(QtGui.QLCDNumber.Filled)
self.display.setProperty("value", 0.0)
self.display.setProperty("intValue", 0)
self.display.setObjectName(_fromUtf8("display"))
self.gridLayout.addWidget(self.display, 0, 0, 1, 5)
self.minBox = QtGui.QSpinBox(self.centralwidget)
self.minBox.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.minBox.setMaximum(60)
self.minBox.setObjectName(_fromUtf8("minBox"))
self.gridLayout.addWidget(self.minBox, 2, 0, 1, 1)
self.secBox = QtGui.QSpinBox(self.centralwidget)
self.secBox.setMaximum(60)
self.secBox.setObjectName(_fromUtf8("secBox"))
self.gridLayout.addWidget(self.secBox, 2, 1, 1, 1)
self.secLabel = QtGui.QLabel(self.centralwidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.secLabel.sizePolicy().hasHeightForWidth())
self.secLabel.setSizePolicy(sizePolicy)
self.secLabel.setObjectName(_fromUtf8("secLabel"))
self.gridLayout.addWidget(self.secLabel, 3, 1, 1, 1)
self.minLabel = QtGui.QLabel(self.centralwidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.minLabel.sizePolicy().hasHeightForWidth())
self.minLabel.setSizePolicy(sizePolicy)
self.minLabel.setObjectName(_fromUtf8("minLabel"))
self.gridLayout.addWidget(self.minLabel, 3, 0, 1, 1)
self.startBtn = QtGui.QPushButton(self.centralwidget)
self.startBtn.setObjectName(_fromUtf8("startBtn"))
self.gridLayout.addWidget(self.startBtn, 2, 2, 1, 1)
self.ResetBtn = QtGui.QPushButton(self.centralwidget)
self.ResetBtn.setWhatsThis(_fromUtf8(""))
self.ResetBtn.setObjectName(_fromUtf8("ResetBtn"))
self.gridLayout.addWidget(self.ResetBtn, 2, 4, 1, 1)
self.stopBtn = QtGui.QPushButton(self.centralwidget)
self.stopBtn.setObjectName(_fromUtf8("stopBtn"))
self.gridLayout.addWidget(self.stopBtn, 2, 3, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 351, 21))
self.menubar.setObjectName(_fromUtf8("menubar"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.msgBox = QtGui.QMessageBox()
self.msgBox.setWindowTitle('Finished')
self.msgBox.setIcon (QtGui.QMessageBox.Information)
self.msgBox.setText("Time Out !!")
stopButton = self.msgBox.addButton("Stop", QtGui.QMessageBox.ActionRole)
ignoreButton = self.msgBox.addButton(QtGui.QMessageBox.Ignore)
self.started = False
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.home()
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "Timer Application", None))
self.secLabel.setText(_translate("MainWindow", "Seconds", None))
self.minLabel.setText(_translate("MainWindow", "Minutes", None))
self.startBtn.setToolTip(_translate("MainWindow", "<html><head/><body><p>Start the timer</p></body></html>", None))
self.startBtn.setStatusTip(_translate("MainWindow", "Start the timer", None))
self.startBtn.setText(_translate("MainWindow", "Start", None))
self.ResetBtn.setToolTip(_translate("MainWindow", "<html><head/><body><p>Reset the timer</p></body></html>", None))
self.ResetBtn.setStatusTip(_translate("MainWindow", "Reset the timer", None))
self.ResetBtn.setText(_translate("MainWindow", "Reset", None))
self.stopBtn.setToolTip(_translate("MainWindow", "<html><head/><body><p>Stop the timer</p></body></html>", None))
self.stopBtn.setStatusTip(_translate("MainWindow", "Stop the timer", None))
self.stopBtn.setText(_translate("MainWindow", "Stop", None))
def home(self):
self.startBtn.clicked.connect(self.value_calc)
self.stopBtn.clicked.connect(self.stop_timer)
self.ResetBtn.clicked.connect(self.reset_timer)
def stop_timer(self):
self.timer.stop()
if self.value != -1:
self.started = True
else:
self.started = False
def displayer(self):
self.display.display(self.value)
self.value -= 1
if self.value == -1:
self.display.display(0)
self.timer.stop()
self.msgBox.show()
def value_calc(self):
sec_value = self.secBox.value()
min_value = self.minBox.value()
min_value *= 60
self.value = sec_value + min_value
if self.value != -1:
if self.started == False:
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.displayer)
self.timer.start(1000)
else:
self.timer.start(1000)
else:
pass
def reset_timer(self):
self.timer.stop()
self.display.display(0)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Upvotes: 1
Views: 1807
Reputation: 9624
You have a lot of unnecessary if statements in your program and an unnecessary variable called self.started
. Also you need a way to tell your value_calc
function to check the current value of self.value
, this can only be achieved by setting a default value for self.value
in your home
function (you should actually be using __init__
for that) also when you press the reset button you also need to reset self.value
back to it's initial value so you don't start counting from where it stopped, this also prevents your timer from counting into negative values because there will always be a check in value_calc
to check if the self.value
is less than zero
Here is the final code:
from PyQt4 import QtCore, QtGui
import time
from PyQt4.QtCore import pyqtSlot,SIGNAL,SLOT
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_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(351, 200)
MainWindow.setMinimumSize(QtCore.QSize(0, 200))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(_fromUtf8("../../../Pictures/clock-icon-md.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
MainWindow.setWindowIcon(icon)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.gridLayout = QtGui.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.display = QtGui.QLCDNumber(self.centralwidget)
font = QtGui.QFont()
font.setKerning(True)
self.display.setFont(font)
self.display.setLayoutDirection(QtCore.Qt.LeftToRight)
self.display.setAutoFillBackground(False)
self.display.setFrameShape(QtGui.QFrame.Box)
self.display.setFrameShadow(QtGui.QFrame.Raised)
self.display.setMidLineWidth(-2)
self.display.setSmallDecimalPoint(False)
self.display.setNumDigits(5)
self.display.setDigitCount(5)
self.display.setMode(QtGui.QLCDNumber.Dec)
self.display.setSegmentStyle(QtGui.QLCDNumber.Filled)
self.display.setProperty("value", 0.0)
self.display.setProperty("intValue", 0)
self.display.setObjectName(_fromUtf8("display"))
self.gridLayout.addWidget(self.display, 0, 0, 1, 5)
self.minBox = QtGui.QSpinBox(self.centralwidget)
self.minBox.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.minBox.setMaximum(60)
self.minBox.setObjectName(_fromUtf8("minBox"))
self.gridLayout.addWidget(self.minBox, 2, 0, 1, 1)
self.secBox = QtGui.QSpinBox(self.centralwidget)
self.secBox.setMaximum(60)
self.secBox.setObjectName(_fromUtf8("secBox"))
self.gridLayout.addWidget(self.secBox, 2, 1, 1, 1)
self.secLabel = QtGui.QLabel(self.centralwidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.secLabel.sizePolicy().hasHeightForWidth())
self.secLabel.setSizePolicy(sizePolicy)
self.secLabel.setObjectName(_fromUtf8("secLabel"))
self.gridLayout.addWidget(self.secLabel, 3, 1, 1, 1)
self.minLabel = QtGui.QLabel(self.centralwidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.minLabel.sizePolicy().hasHeightForWidth())
self.minLabel.setSizePolicy(sizePolicy)
self.minLabel.setObjectName(_fromUtf8("minLabel"))
self.gridLayout.addWidget(self.minLabel, 3, 0, 1, 1)
self.startBtn = QtGui.QPushButton(self.centralwidget)
self.startBtn.setObjectName(_fromUtf8("startBtn"))
self.gridLayout.addWidget(self.startBtn, 2, 2, 1, 1)
self.ResetBtn = QtGui.QPushButton(self.centralwidget)
self.ResetBtn.setWhatsThis(_fromUtf8(""))
self.ResetBtn.setObjectName(_fromUtf8("ResetBtn"))
self.gridLayout.addWidget(self.ResetBtn, 2, 4, 1, 1)
self.stopBtn = QtGui.QPushButton(self.centralwidget)
self.stopBtn.setObjectName(_fromUtf8("stopBtn"))
self.gridLayout.addWidget(self.stopBtn, 2, 3, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 351, 21))
self.menubar.setObjectName(_fromUtf8("menubar"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.msgBox = QtGui.QMessageBox()
self.msgBox.setWindowTitle('Finished')
self.msgBox.setIcon (QtGui.QMessageBox.Information)
self.msgBox.setText("Time Out !!")
stopButton = self.msgBox.addButton("Stop", QtGui.QMessageBox.ActionRole)
ignoreButton = self.msgBox.addButton(QtGui.QMessageBox.Ignore)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.home()
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "Timer Application", None))
self.secLabel.setText(_translate("MainWindow", "Seconds", None))
self.minLabel.setText(_translate("MainWindow", "Minutes", None))
self.startBtn.setToolTip(_translate("MainWindow", "<html><head/><body><p>Start the timer</p></body></html>", None))
self.startBtn.setStatusTip(_translate("MainWindow", "Start the timer", None))
self.startBtn.setText(_translate("MainWindow", "Start", None))
self.ResetBtn.setToolTip(_translate("MainWindow", "<html><head/><body><p>Reset the timer</p></body></html>", None))
self.ResetBtn.setStatusTip(_translate("MainWindow", "Reset the timer", None))
self.ResetBtn.setText(_translate("MainWindow", "Reset", None))
self.stopBtn.setToolTip(_translate("MainWindow", "<html><head/><body><p>Stop the timer</p></body></html>", None))
self.stopBtn.setStatusTip(_translate("MainWindow", "Stop the timer", None))
self.stopBtn.setText(_translate("MainWindow", "Stop", None))
def home(self):
self.startBtn.clicked.connect(self.value_calc)
self.stopBtn.clicked.connect(self.stop_timer)
self.ResetBtn.clicked.connect(self.reset_timer)
self.value = -1
def stop_timer(self):
self.timer.stop()
def displayer(self):
self.display.display(self.value)
self.value -= 1
if self.value == -1:
self.display.display(0)
self.timer.stop()
self.msgBox.show()
def value_calc(self):
if self.value < 0:
sec_value = self.secBox.value()
min_value = self.minBox.value()
min_value *= 60
self.value = sec_value + min_value
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.displayer)
self.timer.start(1000)
else:
self.timer.start(1000)
def reset_timer(self):
self.timer.stop()
self.display.display(0)
self.value = -1
Also just for next time when comparing Boolean Values in python
if x == True
or if x == False
is equivalent to
if x
or if not x
Upvotes: 1