Search code examples
pythonpyqtpyqt5qtserialportqcoreapplication

AttributeError: 'QCoreApplication' object has no attribute 'setQuitOnLastWindowClosed'


I'm getting this error sometimes when I try to quit the Qt event loop. Using a code sample code,

from PyQt5 import QtCore, QtSerialPort

maxcounts = 10
counter = []

app = QtCore.QCoreApplication([]) 

serial_port = QtSerialPort.QSerialPort('COM3')

serial_port.setBaudRate(QtSerialPort.QSerialPort.Baud115200)
serial_port.open(QtCore.QIODevice.ReadWrite) 

serial_port.setDataTerminalReady(1)
serial_port.setDataTerminalReady(0)
serial_port.setDataTerminalReady(1)

def handle_ready_read(): 

    while serial_port.canReadLine():
        resp = serial_port.readLine().data().decode().strip()

        if len(counter) == maxcounts:
            print('closing')
            serial_port.setDataTerminalReady(0)
            serial_port.setDataTerminalReady(1)
            serial_port.setDataTerminalReady(0)
            serial_port.close()
            app.quit() 

        counter.append(1)

        if resp == 'end':
            print('closing')
            serial_port.setDataTerminalReady(0)
            serial_port.setDataTerminalReady(1)
            serial_port.setDataTerminalReady(0)
            serial_port.close()
            app.quit()             

serial_port.readyRead.connect(handle_ready_read) 
 
app.exec_()

Any ideas it would output this error response?

ERROR:tornado.application:Exception in callback functools.partial(<function Kernel.enter_eventloop.<locals>.advance_eventloop at 0x000001DD311F8280>)
Traceback (most recent call last):
  File "C:\Users\me\Anaconda3\lib\site-packages\tornado\ioloop.py", line 741, in _run_callback
    ret = callback()
  File "C:\Users\me\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 314, in advance_eventloop
    eventloop(self)
  File "C:\Users\me\Anaconda3\lib\site-packages\ipykernel\eventloops.py", line 131, in loop_qt5
    return loop_qt4(kernel)
  File "C:\Users\me\Anaconda3\lib\site-packages\ipykernel\eventloops.py", line 117, in loop_qt4
    kernel.app.setQuitOnLastWindowClosed(False)
AttributeError: 'QCoreApplication' object has no attribute 'setQuitOnLastWindowClosed'

I'm not using any windows. It doesn't happen every time though, after running once I usually don't see the error again.

Edit: It may be that setting spyder preference ipython console graphics backend as 'automatic' which may use Qt causes this error, instead of setting it as 'inline'. I found that using app = QtWidgets.QApplication([]) with app.setQuitOnLastWindowClosed(True) while commenting out app.quit() let's the plot show while using the automatic setting, without an error.


Solution

  • It seems that you are using some special environment(seems Spyder) where the developer assumes that you are using QGuiApplication or QApplication as an eventloop that have the setQuitOnLastWindowClosed method. A workaround is to create a class that inherits from QCoreApplication and has that method.

    class CoreApplication(QtCore.QCoreApplication):
        def setQuitOnLastWindowClosed(self, quit):
            pass
    
    
    maxcounts = 10
    counter = []
    
    app = CoreApplication([])
    # ...