[Solved]problem of making a Timer with QLCDNumber
-
the following code just makes a Timer with QLCDNumber
what I want to do is to show a message dialog when 4s has elapsed since the startup of this program .however when the message dialog pops up , the time on QLCDNumber doesn’t change ,what should I do to make this program still timing even when the message dialog pops up ?
how to write the code ?
@
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *class MainWindow(QWidget):
def init(self, parent=None):
super(MainWindow, self).init(parent)
self.resize(800,600)self.lcdNumber = QLCDNumber() self.lcdNumber.setNumDigits(8) layout = QVBoxLayout(self) layout.addWidget(self.lcdNumber) self.currentTime = QTime(0,0,0) self.lcdNumber.display(self.currentTime.toString('hh:mm:ss')) self.timer = QTimer(self) self.timer.timeout.connect(self.updateLcdNumberContent) self.timer.start(1000) def updateLcdNumberContent(self): self.currentTime = self.currentTime.addSecs(1) self.lcdNumber.display(self.currentTime.toString('hh:mm:ss')) if self.currentTime == QTime(0,0,4) : msgBox = QMessageBox() msgBox.setWindowTitle('iTimer') msgBox.setIcon (QMessageBox.Information) msgBox.setText("Time Out !!") stopButton = msgBox.addButton("Stop", QMessageBox.ActionRole) ignoreButton = msgBox.addButton(QMessageBox.Ignore) stopButton.clicked.connect(self.timer.stop) msgBox.show()
msgBox.exec_()
if name == 'main':
app =QApplication(sys.argv)
frame = MainWindow()
frame.show()
sys.exit(app.exec_())@
-
The lcd stops updating when you open the dialog with exec_() because the dialogs event loop blocks the main event loop. Therefore you need to use show() and give the QMessageBox your QMainWindow as a parent. Also, calling raise_() will make your dialog the active window (necessary on Mac OSX at least).
Working example:
@
from PyQt4.QtGui import *
from PyQt4.QtCore import *class MainWindow(QWidget):
def init(self, parent=None):
QMainWindow.init(self, parent)self.resize(800,600) self.lcdNumber=QLCDNumber(self) self.lcdNumber.setNumDigits(8) QVBoxLayout(self).addWidget(self.lcdNumber) self.currentTime=QTime(0,0,0) self.lcdNumber.display(self.currentTime.toString('hh:mm:ss')) self.timerId=self.startTimer(1000) def timerEvent(self, event): if not event.timerId()==self.timerId: return self.currentTime=self.currentTime.addSecs(1) self.lcdNumber.display(self.currentTime.toString('hh:mm:ss')) if self.currentTime==QTime(0,0,4): msgBox=QMessageBox( QMessageBox.Information, "iTimer", "Time Out!", parent=self) stopButton=msgBox.addButton("Stop", QMessageBox.ActionRole) ignoreButton=msgBox.addButton(QMessageBox.Ignore) stopButton.clicked.connect(lambda: self.killTimer(self.timerId)) msgBox.show() msgBox.raise_()
if name == 'main':
from sys import argv, exitapp=QApplication(argv) frame=MainWindow() frame.show() frame.raise_() exit(app.exec_())
@
Hope this helps ;o)
-
thanks for your reply ,but now I have another 2 questions both within my code .
1)if QmessageBox’s parent is None , show() shows QmessageBox only for a second ,then it disappeared immediately .why this issue occurs ?
2)what does giving the QMessageBox my QMainWindow as a parent count ? -
I imagine the answer to 1) is that your QMessageBox goes out of context after show() is called as it is not an attribute of your QMainWindow instance, therefore it is drawn and then garbage collected. As to 2): giving a widget a parent in Qt causes it to be owned by that parent which is generally preferable. WRT to QMessageBox, giving it the QMainWindow as a parent associates it with that window and allows for proper behaviour WRT to modality, positioning, window icon etc. Also, in this case, giving the QMessageBox a parent keeps it in context (see answer to 1)).
-
some other people says that giving the QMessageBox my QMainWindow as a parent creating a non-blocking message box.
I checked the doc ,only found "The parent argument, if not None, causes self to be owned by Qt instead of PyQt." is this two the same mean ?
-
The 'blocking' nature of a widget has nothing to do with the parent. If your start a dialog with exec() it starts its own event loop, blocking the main event loop created by QApplication(). If a dialog is started with show() it uses the main event loop and the method returns immediately (i.e. it doesn't block). Whether a widget is owned by Qt or the PyQt bindings is, in this case anyway, irrelevant.
-
I have another question to ask : . If the active window belongs to some other process,how to make the QMessageBox or QmainWindow in front of any overlapping sibling widgets when timeout
I tried raise_() and activateWindow() ,but both don’t work on WinXP
-
When you say "other process" do you mean an application other than your own? For example, a web browser window has been opened on top of your application? If this is the case, the simple answer to your question is that AFAIK you can't and if even if you could, you shouldn't as this would be incredibly annoying from a user perspective. What will happen is that the task bar will signal to the user via the task bar (usually by changing the colour of or flashing you apps entry) that something requires attention (your message box in this case).
-
[quote author="jazzycamel" date="1364483680"]When you say "other process" do you mean an application other than your own? For example, a web browser window has been opened on top of your application? If this is the case, the simple answer to your question is that AFAIK you can't and if even if you could, you shouldn't as this would be incredibly annoying from a user perspective. What will happen is that the task bar will signal to the user via the task bar (usually by changing the colour of or flashing you apps entry) that something requires attention (your message box in this case).[/quote]
yes,that's what I mean.thanks 4 your tips