pythonpyqt5qdatetime

How to add current time and date widget with PyQt5?


I designed a GUI that opens camera, shows date, time and has QSpinBox. But it shows the date and time according to when I run the application and the time does not advance. The code I have given below works fine. Both the camera start and stop buttons and the QSpinBox work fine. But no matter what I tried I couldn't get the date and time progress. How do I fix it?

import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import cv2

class Thread1(QThread):
    changePixmap = pyqtSignal(QImage)

class Thread2(QThread):

    def __init__(self, *args, **kwargs):
        super().__init__()
        self.active = True

class Video(QWidget):

    def __init__(self):
        super(Video, self).__init__()
        self.frame = []
        self.detectFlag = False
        self.cap = []
        self.timer_camera = QTimer()

        self.resize(900, 600)
        self.setWindowTitle("Proje")

        self.label = QLabel(self)
        self.label.setFixedSize(800, 500)
        self.label.move(50, 40)

        self.btn = QPushButton(self)
        self.btn.setText("Start")
        self.btn.setToolTip("Start the camera.")
        self.btn.setFixedSize(100, 30)
        self.btn.move(60, 540)
        self.btn.clicked.connect(self.slotStart)

        self.btn_stop = QPushButton(self)
        self.btn_stop.setText("Stop")
        self.btn_stop.setToolTip("Stop the camera.")
        self.btn_stop.setFixedSize(100, 30)
        self.btn_stop.move(180, 540)
        self.btn_stop.clicked.connect(self.slotStop)

        self.datetimeedit = QDateTimeEdit(self)
        self.datetimeedit.setDateTime(QDateTime.currentDateTime())
        self.datetimeedit.setDateTimeRange(QDateTime(1900, 1, 1, 00, 00, 00), QDateTime(2100, 1, 1, 00, 00, 00))
        self.datetimeedit.setDisplayFormat('yyyy.MM.dd hh:mm:ss')
        self.datetimeedit.setFixedSize(200, 30)
        self.datetimeedit.move(580, 540)
        self.datetimeedit.setToolTip("This widget shows the time and date.")

        self.spin = QSpinBox(self)
        self.spin.setToolTip("This is an increasing and decreasing number widget as you want.")
        self.spin.move(800, 540)
        self.spin.setFixedSize(30, 30)

        self.th1 = Thread1(self)
        self.th1.changePixmap.connect(self.setImage)
        self.th1.start()

    def slotStart(self):
        self.cap = cv2.VideoCapture(0)
        self.timer_camera.start()
        self.timer_camera.timeout.connect(self.openFrame)

    def slotStop(self):

        if self.cap != []:
            self.cap.release()
            self.timer_camera.stop()

    def openFrame(self):

        if (self.cap.isOpened()):
            ret, self.frame = self.cap.read()
            if ret:
                frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
                height, width, bytesPerComponent = frame.shape
                bytesPerLine = bytesPerComponent * width
                q_image = QImage(frame.data, width, height, bytesPerLine,
                                 QImage.Format_RGB888).scaled(self.label.width(), self.label.height())
                self.label.setPixmap(QPixmap.fromImage(q_image))
            else:
                self.cap.release()
                self.timer_camera.stop()

    @QtCore.pyqtSlot(QImage)
    def setImage(self, qImg1):

        self.image_label.setPixmap(QPixmap.fromImage(qImg1))

    def controlTimer(self):

        if not self.saveTimer.isActive():
            self.saveTimer.start()
            self.th2 = Thread2(self)
            self.th2.active = True
            self.th2.start()
        else:
            self.saveTimer.stop()
            self.th2.active = False
            self.th2.stop()

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    my = Video()
    my.show()
    sys.exit(app.exec_())

Solution

  • You must refresh the time displayed every second (or any other period). For this, create a QTimer and connect its timeout signal to a lambda that refreshes your widget.

    Place this code after the block that creates self.datetimeedit

        # creating a timer object
        timer = QTimer(self)
    
        # adding action to timer
        timer.timeout.connect(lambda: self.datetimeedit.setDateTime(QDateTime.currentDateTime()))
    
        # update the timer every second
        timer.start(1000)