Search code examples
pythonpyqt5infinite-loopqlineeditqmessagebox

How to prevent PyQt Line Edit and Message Box from being stuck in an infinite loop?


In the code below, after any sort of editing or completion in the line edit box, the modify function will be called. Then, the program will be stuck in an infinite loop, resulting in continuous QMessageBox pop-ups and 'modifying..' print statements, followed by the eventual crash of the program.

I've tried to put self.win.processEvents() at different places, but it doesn't help.

from PyQt5 import QtWidgets


class Test:
    def __init__(self):
        self.app = QtWidgets.QApplication([])
        self.win = QtWidgets.QMainWindow()
        self.le_dwell_filter = QtWidgets.QLineEdit()
        self.le_dwell_filter.editingFinished.connect(self.modify)
        self.win.setCentralWidget(self.le_dwell_filter)
        self.win.show()

    def modify(self):
        print('Modifying...')
        msgbox = QtWidgets.QMessageBox()
        msgbox.setText('modification done!')
        msgbox.show()

    def start(self):
        self.app.exec()


if __name__ == '__main__':
    my_test = Test()
    my_test.start()

I would have thought this will print one 'Modifying...', but somehow QMessageBox keeps popping up and the printing keeps happening.. I think it has to do with PyQt Event loop?


Solution

  • You want to have a single QMessageBox so why do you create a new QMessageBox in the modify method ?, what you have to do is reuse:

    class Test:
        def __init__(self):
            self.app = QtWidgets.QApplication([])
            self.win = QtWidgets.QMainWindow()
            self.le_dwell_filter = QtWidgets.QLineEdit()
            self.le_dwell_filter.editingFinished.connect(self.modify)
            self.win.setCentralWidget(self.le_dwell_filter)
            self.win.show()
            self.msgbox = QtWidgets.QMessageBox()
    
        def modify(self):
            print('Modifying...')
            self.msgbox.setText('modification done!')
            self.msgbox.show()
    
        def start(self):
            self.app.exec()