Close QMessageBox after timer's timeout. If mouse events are detected, timer has to be reset

43 Views Asked by At

I am trying to auto-close a QMessageBox instance after timer times out. Also, if there is a mouse movement detected then the messagebox should not auto-close and reset the timer.

To achieve this, I have written a custom class:

import sys
from PyQt5.QtGui import QCloseEvent

from PyQt5.QtWidgets import QApplication, QDialog, QLabel, QVBoxLayout, QMessageBox
from PyQt5.QtCore import QTimer, Qt, QEvent

class TimerBasedMessageBox(QMessageBox):
  """_summary_

  Timeout in milliseconds
  Args:
      QMessageBox (_type_): _description_
  """  
  
  def __init__(self, timeout_in_ms:int = 3000):
    super().__init__()

    self.__timeout_in_ms = timeout_in_ms
    
    self.__window_title = "Timeout Dialog"
    
    
    self.setWindowTitle(self.__window_title)
    self.setText("Custom Information is shown here")
    self.setInformativeText("Informative text : This dialog box will close within 5 seconds of spawn")
    self.setDetailedText("If possible this will be showed with a button on the UI's dilaog box - just wanted this message to be very big!")
    self.setStandardButtons(self.Ok|self.Cancel) # since we already inherit the QMEssageBox here!

    self.timer = QTimer(self)
    self.timer.timeout.connect(self.closeDialog)
    self.timer.start(self.__timeout_in_ms)  # 30 seconds in milliseconds
    
    self.installEventFilter(self)


  def closeDialog(self):
    self.timer.stop()
    print("Close by Timeout!")
    self.accept()
      


  def closeEvent(self, a0: QCloseEvent) -> None:
    print(f"{self.timer.remainingTime()}")
    self.timer.stop()
    print("Close event method was called, this closes the window?")
    return super().closeEvent(a0)

  def eventFilter(self, obj, event):
      if event.type() == QEvent.MouseMove or event.type() == QEvent.MouseButtonPress: # or event.type() == QEvent.KeyPress
        print("Mouse move detected")
        # self.timer.stop()
        self.timer.start(self.__timeout_in_ms)
      return super().eventFilter(obj, event)
  

if __name__ == "__main__":
    app = QApplication(sys.argv)
    dialog = TimerBasedMessageBox(timeout_in_ms=5000)
    reply = dialog.exec_()
    if reply == QMessageBox.Ok:
      print("From main function :Ok button was pressed")
    sys.exit()

Though the event is captured and the self.timer.start() is given, the messagebox still auto-closes and the timer would not reset. Why is this?

P.S. I have tried to self.timer.stop() before the start() call. The actual use case would be: to show a messagebox and auto close after 'x' seconds. But if user activity is detected (i.e., mouse movements) then the messagebox should not auto close. Once the user is Idle ( no mouse movements), then the messagebox can close after 'x' seconds from now.

0

There are 0 best solutions below