简体   繁体   中英

How to use QNetworkAccessManager in different classes? General sharing of important data between classes?

I have a MainWindow application I'm working on to learn C++ and Qt (C++ and QT 4.8). I want to do HTTP requests in different objects of my application, such as Dialogs/Wizard and in the MainWindow. I know I'm basically supposed to have one QNetworkAccessManager per application. My question is, what is the proper way to pass this QNAM around between classes?

At the moment I have it as a pointer I pass to the constructor of my wizard but this seems... inelegant and inflexible. What is the proper way to give my Dialogs or whatever other classes I decide to make, access to my one QNetworkAccessManager? I guess I have the same question about any piece of data I need to give everything access to.

What is the properly C++-designed solution here? The singleton pattern seems like an option, but a bad one as I understand. I have a bit of code here to show my question.

My MainWindow constructor and slot which launch my wizard:

MyMainWindow::MyMainWindow
{
    qnam = new QNetworkAccessManager();
}

...

MyMainWindow::wizardStarter
{
    mywizard = MyWizard(vari, qnam, this);
}

My Wizard Constructor in which I'm making network requests and parsing data after getting data from the user, and therefore in which I need a QNetworkAccessManager:

MyWizard::MyWizard(SomeOtherArgument *vari, QNetworkAccessManager *qnam, QObject *parent)
{
    ...
    this->ourQnam = qnam;
    ...
}

MyWizard::launchRequest(QUrl newUrl)
{
    ourQnam->get(QNetworkRequest(newUrl));
}

From your question, I think you're really asking which form of (ie injecting your dependent QNetworkAccessManager into objects) to use. (即将依赖的QNetworkAccessManager注入对象)。

In your case you're using . This is a perfectly known and accepted form of injection. It strongly communicates your wizard class the QNetworkAccessManager which makes your code easy for people to understand. QNetworkAccessManager,它使您的代码易于人们理解。 If you were to use a singleton to simply grab a static QNetworkAccessManager from inside the wizard class implementation, while it has the benefit of removing the constructor injection, it hides that your wizard class uses the QNetworkAccessManager.

Another well known form of injection is ie setDelegate( delegate ) setDelegate( delegate )

Professionally speaking there is nothing wrong with your current approach as again it clearly communicates your wizard class the QNetworkAccessManager object. QNetworkAccessManager对象。

Here is a bit of reading if you if you're interested in learning more about dependency injection.

Dependency Injection

Dependency Injection in C++

Another way is shown in this post:

The canonical way to manage such global application-tied objects is to keep them as automatic variables in main and use helper functions to access them. The QPointer automatically tracks the lifetime of the object, and thus won't ever be dangling.

Thus:

main.h - interface

QNetworkAccessManager *nMgr();

main.cpp - implementation

// This pointer is local to the translation unit, and is an
// implementation detail. It's not used anywhere else.
static QPointer<QNetworkAccessManager> globalManager;

// The global accessor method
QNetworkAccessManager *nMgr() {
  Q_ASSERT(!qApp || QThread::currentThread() == qApp->thread());
  return globalManager;
}

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);
  QNetworkAccessManager mgr;
  globalManager = &mgr;
  ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM