Question à propos de l'app.exec() et de la boucle dans Qt

0

La question

N'est-ce pas app.exec() une boucle infinie qui renvoie main() ?

Je veux boucle le serveur de communication du client ci-dessous, mais il est exécutée juste alors la fonction principale se termine avec app.exec()

Je suis nouvelle à la fois pour Qt et C++, comment puis-je gérer cette boucle?

int main(int argc, char *argv[])
{
    cout << "Waiting for the next request " << endl;
    QApplication app(argc, argv);

    //  Prepare our context and socket
    zmq::context_t context(1);
    zmq::socket_t socket(context, ZMQ_REP);
    socket.bind("tcp://*:2424");
    zmq::message_t request;


    QQmlApplicationEngine engine;

    VideoStreamer videoStreamer;
    imageProvider *liveOriginalImageProvider(new imageProvider);
    imageProvider *liveMaskedImageProvider(new imageProvider);

    //********SERVER CLIENT COMMUNICATION BEGINS******//

    // Wait for next request from client
    cout << "Waiting for the next request ." << endl;
    socket.recv(&request);
    cout << "Waiting for the next request.. " << endl;
    string replyMessage = string(static_cast<char *>(request.data()), request.size());

    // Print out received message
    cout << "Received from client (Python): " + replyMessage << endl;

    //  See the gradual sending/replying from client
    sleep(1);

    //  Send reply back to client
    string msgToClient("W");
    zmq::message_t reply(msgToClient.size());
    memcpy((void *) reply.data(), (msgToClient.c_str()), msgToClient.size());
    socket.send(reply);

    //*********SERVER CLIENT COMMUNICATION ENDS**********//

    engine.rootContext()->setContextProperty("VideoStreamer",&videoStreamer);
    engine.rootContext()->setContextProperty("liveOriginalImageProvider",liveOriginalImageProvider);
    engine.rootContext()->setContextProperty("liveMaskedImageProvider",liveMaskedImageProvider);

    engine.addImageProvider("liveOriginal",liveOriginalImageProvider);
    engine.addImageProvider("liveMasked",liveMaskedImageProvider);


    const QUrl url(QStringLiteral("qrc:/main.qml"));
    engine.load(url);

    QObject::connect(&videoStreamer,&VideoStreamer::originalImage,liveOriginalImageProvider,&imageProvider::updateImage);
    QObject::connect(&videoStreamer,&VideoStreamer::maskedImage,liveMaskedImageProvider,&imageProvider::updateImage);

    return app.exec();
}

---------Mise à JOUR---------

J'ai créé ce fil en fil.h

class MyThread : public QThread{
public slots:
    void run();
};

dans thread.cpp j'ai déclaré la méthode:

void MyThread :: run() {
    //  Prepare our context and socket
    zmq::context_t context(1);
    zmq::socket_t socket(context, ZMQ_REP);
    socket.bind("tcp://*:2424");
    zmq::message_t request;

    //********SERVER CLIENT COMMUNICATION BEGINS******//

    // Wait for next request from client
    cout << "Waiting for the next request ." << endl;
    socket.recv(&request);
    cout << "Waiting for the next request.. " << endl;
    string replyMessage = string(static_cast<char *>(request.data()), request.size());

    // Print out received message
    cout << "Received from client (Python): " + replyMessage << endl;

    //  See the gradual sending/replying from client
    sleep(1);

    //  Send reply back to client
    string msgToClient("W");
    zmq::message_t reply(msgToClient.size());
    memcpy((void *) reply.data(), (msgToClient.c_str()), msgToClient.size());
    socket.send(reply);

    exec();
    //*********SERVER CLIENT COMMUNICATION ENDS**********//
}

dans main.cpp je l'ai appelé:

QThread *thread = new QThread();

MyThread *myThread = new MyThread();
myThread->moveToThread(thread);
myThread->connect(thread, SIGNAL(started()), myThread, SLOT(run()));

thread->start();

Je reçois Error: Class declaration lacks Q_OBJECT macro. Ne pas QThread hériter de QObject? Comment puis-je appeler la boucle correctement?

c++ qt
2021-11-23 09:48:10
1

La meilleure réponse

0

L'un des principaux projets sur lesquels je travail actuellement utilise Qt et ZMQ - Votre ZMQ sockets besoin pour vivre à l'intérieur d'un QObject qui s'exécute sur la boucle d'évènements, pas à l'intérieur de la main() fonction de votre demande

Voici un très abrégée de vue de la façon dont l'un de nos ZMQ sockets communique sur la boucle d'événement de Qt - l'application dispose d'un ZMQ_SUB prise connectée à un ZMQ_PUB prise à l'autre bout de la publication des événements à partir d'une interface de matériel

int main(int argc, char* argv[])
{
   QApplication app(argc, argv);
   ...
   ConnectionManager connMgr; // Create connection class - is a QObject subclass
   connMgr.connect(target);

   MainWindow mainWin; // Create GUI classes

   return app.exec();
}
void ConnectionManager::connect(std::string target)
{
    context = zmq_ctx_new();

    zsocket = zmq_socket(context, ZMQ_SUB);
    zmq_connect(zsocket, (connection + ":" + REQUEST_PORT).c_str());
    ...

    QTimer pollTimer;
    pollTimer.callOnTimeout(this, &ConnectionManager::onPollTimer);
    pollTimer.start(100);
}

void ConnectionManager::onPollTimer()
{
    uint16_t length = 0;

    const size_t buffer_length = 1024;
    uint8_t* buffer = new uint8_t[buffer_length];

    do
    {
        int64_t more = 0;
        size_t more_size = sizeof more;
        auto len = zmq_recv(zsocket, buffer + length, buffer_length - length, ZMQ_NOBLOCK);
        if (len == -1)
        {
            return;
        }
        else if (len > 0)
        {
            length += len;
            auto rc = zmq_getsockopt(socket, ZMQ_RCVMORE, &more, &more_size);
        }
    } while (more);

    std::cout << "Received" << length << "bytes";
    HandleMessage(buffer, length); // Process the incoming message
}

En essence, app.exec() Permet de créer une boucle infinie, mais qui existe au sein de la boucle QApplication objet, pas celui qui vient à plusieurs reprises exécute le main() fonction où il a été appelé, et de faire usage de la boucle de votre application doit créer des instances supplémentaires de QObject les sous-classes et d'utiliser le signal/slot/QEvent/QTimer mécanismes pour effectuer des actions en réponse aux actions de l'utilisateur/les événements d'entrée/intervalles de temps

2021-11-23 18:47:50

Merci pour l'explication, mais c'est vraiment dur pour moi à mettre en œuvre. Est-il possible de passer par cette situation en utilisant les codes que j'ai écrit ci-dessus?
noobie

Dans votre question, vous avez déclaré "je suis nouveau à Qt et C++" - vous êtes nouveau à la programmation en général ou avez-vous écrit dans d'autres langues, et vous êtes juste maintenant essayer quelque chose en C++/Qt pour la première fois? Je demande parce que ce que vous tentez ici n'est pas quelque chose que je recommanderais d'essayer de mettre en œuvre un programmeur débutant jusqu'à ce que vous avez obtenu beaucoup plus familier avec la langue en général, et puis familiarisé avec le fonctionnement de l'application Qt boucle d'événement et de signal/slot mécanismes de travail, que ce sont des mécanismes fondamentaux pour l'écriture d'applications Qt en général
rdowell

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................