pyqt: окно сообщений автоматически закрывается через несколько секунд

Я пытаюсь сделать окно с предупреждающим сообщением, которое автоматически исчезает через несколько секунд. Я сделал этот код:

def warning(self):
   messagebox = QtGui.QMessageBox(self)
   messagebox.setWindowTitle("wait")
   messagebox.setText("wait (closing automatically in {0} secondes.)".format(3))
   messagebox.setStandardButtons(messagebox.NoButton)
   self.timer2 = QtCore.QTimer()
   self.time_to_wait = 3
   def close_messagebox(e):
      e.accept()
      self.timer2.stop()
      self.time_to_wait = 3
   def decompte():
      messagebox.setText("wait (closing automatically in {0} secondes.)".format(self.time_to_wait))
      if self.time_to_wait <= 0:
         messagebox.closeEvent = close_messagebox
         messagebox.close()
      self.time_to_wait -= 1
   self.connect(self.timer2,QtCore.SIGNAL("timeout()"),decompte)
   self.timer2.start(1000)
   messagebox.exec_()

Это работает на самом деле отлично, для части автоматического закрытия. Моя проблема в том, что когда кто-то пытается закрыть его вручную до нескольких секунд, нажав кнопку x в окне, окно сообщения никогда не закрывается. «время ожидания» становится отрицательным, окно сообщения показывает, например, «закрытие автоматически через -4 секунды», и оно никогда не закроется.

Любая идея, как я мог избежать этого? С уважением


person p.deman    schedule 02.12.2016    source источник
comment
попробуй с моим решением   -  person eyllanesc    schedule 02.12.2016


Ответы (1)


Попробуйте мое решение, я создал новый тип QMessageBox с вашими требованиями.

import sys
from PyQt4 import QtCore
from PyQt4 import QtGui


class TimerMessageBox(QtGui.QMessageBox):
    def __init__(self, timeout=3, parent=None):
        super(TimerMessageBox, self).__init__(parent)
        self.setWindowTitle("wait")
        self.time_to_wait = timeout
        self.setText("wait (closing automatically in {0} secondes.)".format(timeout))
        self.setStandardButtons(QtGui.QMessageBox.NoButton)
        self.timer = QtCore.QTimer(self)
        self.timer.setInterval(1000)
        self.timer.timeout.connect(self.changeContent)
        self.timer.start()

    def changeContent(self):
        self.setText("wait (closing automatically in {0} secondes.)".format(self.time_to_wait))
        self.time_to_wait -= 1
        if self.time_to_wait <= 0:
            self.close()

    def closeEvent(self, event):
        self.timer.stop()
        event.accept()


class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        btn = QtGui.QPushButton('Button', self)
        btn.resize(btn.sizeHint())
        btn.move(50, 50)
        self.setWindowTitle('Example')
        btn.clicked.connect(self.warning)

    def warning(self):
        messagebox = TimerMessageBox(5, self)
        messagebox.exec_()


def main():
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
person eyllanesc    schedule 02.12.2016
comment
В вашем счетчике ошибка на единицу. Вы должны переместить self.time_to_wait -= 1 в конец changeContent. Затем удалите вызов setText в __init__ и вызовите self.changeContent() перед запуском таймера. (PS: было бы лучше, если бы вы использовали синтаксис сигналов и слотов в новом стиле). - person ekhumoro; 02.12.2016
comment
@ekhumoro это pyqt4, сигнал нового стиля и синтаксис слотов только для pyqt5 - person eyllanesc; 02.12.2016
comment
Нет, они есть и в PyQt4. Ссылка, которую я дал, предназначена для документов PyQt4. - person ekhumoro; 02.12.2016
comment
@ekhumoro Обновите ответ - person eyllanesc; 02.12.2016
comment
Большой! Но самой важной частью была ошибка «один за другим». Ваш код начинает с ожидания двух секунд, прежде чем изменить текст на 4, а затем, наконец, останавливается на 2, а не на 1. - person ekhumoro; 02.12.2016
comment
@ekhumoro проверьте мое решение - person eyllanesc; 03.12.2016
comment
Я уже проверил это, и у него есть ошибка, которую я описал в своем последнем комментарии. Я также показал, как это исправить в моем первом комментарии. - person ekhumoro; 03.12.2016
comment
Спасибо ! (извините за задержку...) работает отлично. еще раз спасибо !! - person p.deman; 17.01.2017