pythonpyqtpyqt5qtnetwork

Checking internet connectivity using QtNetwork and PyQt5


I'm trying to check network connectivity the hard way using QtNetwork but can't figure out how to do it properly. This is the code I'm working on it seems that neither finished nor error signals are called. What I'm missing here?

import sys
from PyQt5 import QtCore, QtNetwork, QtWidgets


class CheckConnectivity:
    def __init__(self):
        url = QtCore.QUrl("https://www.google.com/")
        req = QtNetwork.QNetworkRequest(url)
        net_manager = QtNetwork.QNetworkAccessManager()
        self.res = net_manager.get(req)
        self.res.finished.connect(self.processRes)
        self.res.error.connect(self.processErr)
        self.msg = QtWidgets.QMessageBox()

    def processRes(self):
        if self.res.bytesAvailable():
            self.msg.information(self, "Info", "You are connected to the Internet.")
        else:
            self.msg.critical(self, "Info", "You are not connected to the Internet.")
        self.msg.show()
        self.res.close()

    def processErr(self, *args):
        print(*args)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    ic = CheckConnectivity()
    sys.exit(app.exec_())

Solution

  • the problem is caused because net_manager is removed, remember that a variable only exists in the context where it was created, in your case net_manager is a local variable that will be deleted when the __init__ method ends.

    class CheckConnectivity(QtCore.QObject):
        def __init__(self, *args, **kwargs):
            QtCore.QObject.__init__(self, *args, **kwargs)
            url = QtCore.QUrl("https://www.google.com/")
            req = QtNetwork.QNetworkRequest(url)
            self.net_manager = QtNetwork.QNetworkAccessManager()
            self.res = self.net_manager.get(req)
            self.res.finished.connect(self.processRes)
            self.res.error.connect(self.processErr)
            self.msg = QtWidgets.QMessageBox()
    
        @QtCore.pyqtSlot()
        def processRes(self):
            if self.res.bytesAvailable():
                self.msg.information(None, "Info", "You are connected to the Internet.")
            self.res.deleteLater()
    
        @QtCore.pyqtSlot(QtNetwork.QNetworkReply.NetworkError)
        def processErr(self, code):
            self.msg.critical(None, "Info", "You are not connected to the Internet.")
            print(code)
    

    It is advisable to use the pyqtSlot() decorator since its use helps the application to be a little faster and consume less memory but for this the class must inherit from QObject.