Reputation: 1174
I write a python application for measurements in a laboratory, which saves data into a remote database over an unstable network connection. When connection is broken, a question pops up (I use QMessageBox.question
), asking user to whether repeat the last transaction or cancel it.
Recently application was modified to do automatic measurement autonomously during the night. There is no operator anymore to click on the default option "Retry"! It should be selected automatically after some timeout, still giving the user opportunity to make other choice.
This means, I need a version of QMessageBox that clicks a default button after a timeout is elapsed, if user did not make any other choice.
There is similar question, but it is C++
-specific.
Upvotes: 2
Views: 1422
Reputation: 1174
This answer is a Python
adaptation of C++
code posted by Jeremy Friesner in a similar question:
from PyQt4.QtGui import QMessageBox as MBox, QApplication
from PyQt4.QtCore import QTimer
class TimedMBox(MBox):
"""
Variant of QMessageBox that automatically clicks the default button
after the timeout is elapsed
"""
def __init__(self, timeout=5, buttons=None, **kwargs):
if not buttons:
buttons = [MBox.Retry, MBox.Abort, MBox.Cancel]
self.timer = QTimer()
self.timeout = timeout
self.timer.timeout.connect(self.tick)
self.timer.setInterval(1000)
super(TimedMBox, self).__init__(parent=None)
if "text" in kwargs:
self.setText(kwargs["text"])
if "title" in kwargs:
self.setWindowTitle(kwargs["title"])
self.t_btn = self.addButton(buttons.pop(0))
self.t_btn_text = self.t_btn.text()
self.setDefaultButton(self.t_btn)
for button in buttons:
self.addButton(button)
def showEvent(self, e):
super(TimedMBox, self).showEvent(e)
self.tick()
self.timer.start()
def tick(self):
self.timeout -= 1
if self.timeout >= 0:
self.t_btn.setText(self.t_btn_text + " (%i)" % self.timeout)
else:
self.timer.stop()
self.defaultButton().animateClick()
@staticmethod
def question(**kwargs):
"""
Ask user a question, which has a default answer. The default answer is
automatically selected after a timeout.
Parameters
----------
title : string
Title of the question window
text : string
Textual message to the user
timeout : float
Number of seconds before the default button is pressed
buttons : {MBox.DefaultButton, array}
Array of buttons for the dialog, default button first
Returns
-------
button : MBox.DefaultButton
The button that has been pressed
"""
w = TimedMBox(**kwargs)
w.setIcon(MBox.Question)
return w.exec_()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = TimedMBox.question(text="Please select something",
title="Timed Message Box",
timeout=8)
if w == MBox.Retry:
print "Retry"
if w == MBox.Cancel:
print "Cancel"
if w == MBox.Abort:
print "Abort"
In this implementation the default button is the first one in the argument buttons
.
Upvotes: 6