zeromq / libzmq

ZeroMQ core engine in C++, implements ZMTP/3.1
https://www.zeromq.org
Mozilla Public License 2.0
9.64k stars 2.35k forks source link

Calling a QT Button (C++) From the External Python Script using zeromq #4302

Open seymseym opened 2 years ago

seymseym commented 2 years ago

I am working on a project that is mainly written on Python, but the part where the camera captures are being processed is in a QT project (C++).

For ex: There is a start button in the QT which activates several functions that are written in C++:

in main.qml:

Button {
    id: startbutton
    x: 910
    y: 822
    text: qsTr("Start")

    onPressed: {
        VideoStreamer.startcapturing()
    }
}

For now, I am clicking on this button manually, but I need to write a function that activates this button whenever it is needed in the Python algorithm.

--> So the Python script should call the start button somehow.

As a starting point, I send a message to the C++ file and receive a message from it like that:

Python:

context = zmq.Context()
socket = context.socket(zmq.REQ)
port = "5555"
socket.connect("tcp://localhost:%s" % port)

socket.send(b"saying hello from python")
message = socket.recv()
print("Received reply from server (C++):", message)

C++

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

    // forever loop
    while (true) {
        zmq::message_t request;

        //  Wait for next request from client
        socket.recv(&request);
        std::string replyMessage = std::string(static_cast<char *>(request.data()), request.size());
//        std::string replyMessage = std::string((request.data())., request.size());
        // Print out received message
        std::cout << "Received from client (Python): " + replyMessage << std::endl;

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

        //  Send reply back to client
        std::string msgToClient("greeting from C++");
        zmq::message_t reply(msgToClient.size());
        memcpy((void *) reply.data(), (msgToClient.c_str()), msgToClient.size());
        socket.send(reply);
    }

This is just a simple string message. I want to be able to call VideoStreamer.startcapturing() method from C++ in the Python script. Is it possible to do this using ZEROMQ? I've read tons of things but could not manage to apply them, so can you please give some examplery codes like the above code snippets for calling methods?

Notes: OS: Ubuntu 18.04.6 LTS

All the projects are in the same PC

ljluestc commented 2 weeks ago

#include <zmq.hpp>
#include <iostream>
#include <unistd.h>
#include <QString>
#include <QCoreApplication>
#include <QDebug>

// Define your Qt class
class VideoStreamer {
public:
    void startcapturing() {
        qDebug() << "Capturing started!";
        // Add your capturing code here
    }
};

void processRequest(const std::string &request) {
    static VideoStreamer videoStreamer;
    if (request == "start_capture") {
        videoStreamer.startcapturing();
    } else {
        std::cerr << "Unknown command: " << request << std::endl;
    }
}

int main() {
    QCoreApplication app(argc, argv);

    // Prepare ZeroMQ context and socket
    zmq::context_t context(1);
    zmq::socket_t socket(context, ZMQ_REP);
    socket.bind("tcp://*:5555");

    // Main loop to process requests
    while (true) {
        zmq::message_t request;
        socket.recv(&request);
        std::string replyMessage(static_cast<char *>(request.data()), request.size());
        std::cout << "Received from client (Python): " << replyMessage << std::endl;

        // Process the request
        processRequest(replyMessage);

        // Send reply back to client
        std::string msgToClient("Command processed");
        zmq::message_t reply(msgToClient.size());
        memcpy(reply.data(), msgToClient.c_str(), msgToClient.size());
        socket.send(reply);
    }

    return 0;
}