Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QNetworkAccessManager at global scope



  • I want to use QNetworkAccessManager from a global function (not a class member).

    I've got the beginnings of a concept - below:

    void ::replyFinished(QNetworkReply * reply)
    {
    	QByteArray buffer = reply->read(reply->bytesAvailable());
            reply->deleteLater();
    }
    bool CheckVersion(CString & strVersion)
    {
    	static QNetworkAccessManager manager;
    
    	QObject::connect(&manager, &QNetworkAccessManager::finished,
    		::replyFinished);
    
    	manager.get(QNetworkRequest(QUrl("http://deepskystacker.free.fr/download/CurrentVersion.txt")));
    }
    

    But that leaves the manager object lying around when the job is done.

    Can I use a pointer to QNetworkAccessManager and call deleteLater() to delete that as well?

    Help most welcome
    David


  • Qt Champions 2019

    @Perdrix said in QNetworkAccessManager at global scope:

    I want to use QNetworkAccessManager from a global function

    Why?
    Global objects are almost always a sign of bad design.



  • Yes, but a major application redesign of legacy code is not something one undertakes lightly!

    I've actually moved the code into a class now rather than having it as global.

    Q about deleteLater still applies ...


  • Lifetime Qt Champion

    Hi,

    Usually QNetworkManager is used as a class variable and thus destroyed along with said class. There's no real need to put it on the heap. But if you need to, just give it a parent and it will be destroyed with it.


  • Lifetime Qt Champion

    @SGaist

    Is static safe within a function in relation not being initialized before QApplication?


  • Lifetime Qt Champion

    @mrjj good question, I did not even consider it an option and I currently don't know for sure. I would stay in the line of: do not allocate static QObject based classes.


  • Lifetime Qt Champion

    @SGaist
    It seems that its first called on first use when its not a POD.

    Frankly im not sure either. I rarely use static inside functions as its rarely truly useful and
    very annoying for unit testing with mockups.



  • It's now allocated on the the heap:

    Here's the current code for comments (networkManager is an mv of CStackingDlg):

    void CStackingDlg::versionInfoReceived(QNetworkReply * reply)
    {
    	QString string(reply->read(reply->bytesAvailable()));
    
    	if (string.startsWith("DeepSkyStackerVersion="))
    	{
    		QString verStr = string.section('=', 1, 1);
    		int version = verStr.section('.', 0, 0).toInt();
    		int release = verStr.section('.', 1, 1).toInt();
    		int mod = verStr.section('.', 2, 2).toInt();
    
    		if ((version > DSSVER_MAJOR) ||
    			(version == DSSVER_MAJOR && release > DSSVER_MINOR) ||
    			(version == DSSVER_MAJOR && release == DSSVER_MINOR && mod > DSSVER_SUB)
    			)
    		{
    			CString	strNewVersion;
    
    			strNewVersion.Format(IDS_VERSIONAVAILABLE, CString((wchar_t *)verStr.utf16()));
    			m_Infos.SetTextColor(RGB(255, 0, 0));
    			m_Infos.SetText(strNewVersion);
    			m_Infos.SetLink(true, false);
    			m_Infos.SetHyperLink("https://github.com/deepskystacker/DSS/releases/latest");
    		};
    	}
    	reply->deleteLater();
    	networkManager->deleteLater();
    };
    
    void CStackingDlg::retrieveLatestVersionInfo()
    {
    #ifndef DSSBETA
    	ZFUNCTRACE_RUNTIME();
    
    	QSettings			settings;
    
    	bool checkVersion = settings.value("InternetCheck", false).toBool();
    	if (checkVersion)
    	{
    		networkManager = new QNetworkAccessManager();
    
    		QObject::connect(networkManager, &QNetworkAccessManager::finished,
    			[this](QNetworkReply * reply) { this->versionInfoReceived(reply); });
    
    		networkManager->get(QNetworkRequest(QUrl("http://deepskystacker.free.fr/download/CurrentVersion.txt")));
    	}
    #endif
    }
    

    Please note the CStackingDlg is not derived from QObject but from CDialog (MFC) so I can't rely on QObject as parent to delete stuff.

    David


  • Qt Champions 2019

    @mrjj said in QNetworkAccessManager at global scope:

    Is static safe within a function in relation not being initialized before QApplication?

    A local static is initialized when the function is first called. Since c++11 the creation of the local static is even thread-safe (as long as it's a object, not a pointer)


Log in to reply