8

I'm building a Qt Symbian Project and I want to show a notification for the user that should auto close after some seconds. I have seen that Nokia uses this a lot in their ui.

Right now I'm using the code below so that the user can close the QMessageBox but I would like it if it was possible to auto close the QMessageBox after 1 or 2 seconds. How can I do this using Qt?

QMessageBox msgBox;
msgBox.setText("Hello!");
msgBox.setIcon(QMessageBox::Information);
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.exec();
demonplus
  • 5,613
  • 12
  • 49
  • 68
Martin
  • 1,675
  • 11
  • 34
  • 46

6 Answers6

8

Thanks really much! My solution:

I created my own class (MessageBox) this is my code for showing it:

MessageBox msgBox;
msgBox.setText("Hello!");
msgBox.setIcon(QMessageBox::Information);
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setAutoClose(true);
msgBox.setTimeout(3); //Closes after three seconds
msgBox.exec();

This is my class:

class MessageBox : public QMessageBox

int timeout;
bool autoClose;
int currentTime;

void MessageBox::showEvent ( QShowEvent * event ) {
    currentTime = 0;
    if (autoClose) {
    this->startTimer(1000);
    }
}

void MessageBox::timerEvent(QTimerEvent *event)
{
    currentTime++;
    if (currentTime>=timeout) {
    this->done(0);
    }
}
Mohsen Zahraee
  • 3,309
  • 5
  • 31
  • 45
Martin
  • 1,675
  • 11
  • 34
  • 46
  • 1
    where is your definition of startTimer? – qed Nov 12 '14 at 00:31
  • 5
    You can also use QAbstractPushButton.animateClick method by simply adding `msgBox.setStandardButtons(QMessageBox::Ok); msgBox.button(QMessageBox::Ok).animateClick(timeout)` – jung rhew Nov 26 '14 at 06:12
  • 1
    Objects have multiple timers and you have to check if the timer event you're receiving is actually the one you expect. Secondly, the timer can be set for the entire time at once, i.e. `closeTimer.startTimer(timeout*1000)`, where: `QBasicTimer closeTimer`. Then: `void MessageBox::timerEvent(QTimerEvent *e) { if (e->timerId() == closeTimer.timerId()) done(0); }` – Kuba hasn't forgotten Monica Aug 24 '18 at 18:37
4

I would suggest to subclass QMessageBox to add your own desired behavior...

It would be interesting to add methods like setAutoClose(bool) and setAutoCloseTimeout(int) and trigger a QTimer on showEvent when the AutoClose option is enabled !

This way, you could even alter the apparence of your QMessageBox and had a text saying "This box will close automatically in XXX seconds..." or a progress bar, etc...

demonplus
  • 5,613
  • 12
  • 49
  • 68
Andy M
  • 5,945
  • 7
  • 51
  • 96
2

Instead you can use Singleshot Timer to close any dialog box or QLabel with much ease:

QTimer *timer;
QTimer::singleShot(10000, msgBox, SLOT(close()));
user28434'mstep
  • 6,290
  • 2
  • 20
  • 35
Tachi
  • 21
  • 1
2

This may help someone,

msgBox.button(QMessageBox::Ok)->animateClick(5000);

The messageBox closes after 5 seconds.

shwink
  • 309
  • 2
  • 12
2

For Python, something like QTimer.singleShot(5000, lambda : qm.done(0)) may work.

The below example will time out close after 5 seconds, triggering the "No" option if it times out.

import sys

from PySide2.QtCore import *
from PySide2.QtWidgets import *

app = QApplication(sys.argv)

qm = QMessageBox()
qm.setText("Continue?")
qm.setStandardButtons(QMessageBox.Yes)
qm.addButton(QMessageBox.No)
qm.setDefaultButton(QMessageBox.No)
QTimer.singleShot(5000, lambda : qm.done(0))
if qm.exec_() == QMessageBox.Yes:
    print("Yes!")
else:
    print("No!")
amasmiller
  • 335
  • 2
  • 7
1

With this code:

QTimer *timer;
QTimer::singleShot(10000, msgBox, SLOT(close()));

you get:

QObject::connect: Incompatible sender/receiver arguments
        QTimer::timeout() --> QMessageBox::

Becouse msgBOx (the receiver) must be a QtCore object.. and QMessageBox subclassing QtGui. See https://srinikom.github.io/pyside-docs/PySide/QtCore/QTimer.html#PySide.QtCore.PySide.QtCore.QTimer.singleShot

gabofer82
  • 63
  • 2
  • 12