Triying to create a custom signal with threads



  • I am working with two threads one for receive data a another to write data in a file, three different class one to handle buttons that do some operations and initialization stuff, one class to receive the data and another class to write the data received.

    One thread dealing with the data received, other thread dealing with the writing.

    I have problems trying to make the signal of data received, then call the slot of data writing

    Mainwindow.cpp

    //Threads for write and receive usb transfer
        QThread *threadReceive = new QThread();
        QThread *threadWrite = new QThread();
    
        //Objects of calss receive and write
        receive *receive_usb = new receive();
        write *write_to_file = new write();
    
        //passing the usb handle deveice
        receive_usb->device_handle_receive=usb_channels->device_handle;
    
        //create the file ts
        write_to_file->create_file();
    
        //Move to threads
        receive_usb->moveToThread(threadReceive);
        write_to_file->moveToThread(threadWrite);
    
        //Strat the threads
        threadReceive->start();
        threadWrite->start();
    
        //When the buffer fills and emited the signal of receive write
        connect(receive_usb,SIGNAL(received(unsigned char*MPEG2_TS)), write_to_file, SLOT(write_to_file(unsigned char*MPEG2_TS)));
    

    In the received class

    #ifndef RECEIVE_H
    #define RECEIVE_H
    #include <libusb-1.0/libusb.h> //Include libsub
    #include <QObject>
    
    class receive: public QObject
    {
        Q_OBJECT
    public:
        receive();
        libusb_device_handle *device_handle_receive;
    
    public slots:
        void transfer_usb(); //recieving tranfer from USB
    
    private:
        //Creating the buffer to receive 245760 bytes= 240 Kb
        unsigned char MPEG2_TS[245760];
    
        //Variable to register the errors
        unsigned int error_receive;
    
        //Private function to emit the singal, receive parameter buffer
        void emitreceived(unsigned char *MPEG2_TS);
    
    signals:
        //Signal emited
        void received(unsigned char *MPEG2_TS);
    
    };
    
    #endif // RECEIVE_H
    

    receive.cpp

    #include "receive.h"
    
    receive::receive()
    {
    
    }
    
    //-----------------------FUNCTION FOR USB RECEIVING BEGIN----------------
    
    void receive::transfer_usb()
    {
        while(1)
        {
        //It's a return of libusb_interrupt_transfer with the number of bytes that were transferred
        int transferred=0;
    
        //It's a return of libusb_interrupt_transfer return 0 if the transfer was successful
        int resultado=0;
    
        //Receiving Transfer
        resultado=libusb_interrupt_transfer (device_handle_receive,   //The device handle
                                        0x82,                 //Endponit 2
                                        MPEG2_TS,             //Buffer
                                        245760,               //Size of Buffer
                                        &transferred,         //Return the number of bytes transferred
                                        0                     //waiting time to receive the answer
                                      );
    
        if (resultado!=0) error_receive=10;   //For error 10: "Error in transfer in thread one"
        //Private function to emit the signal or received
        emitreceived(MPEG2_TS);
        }
    }
    
    //-----------------------FUNCTION FOR USB RECEIVING END------------------
    
    //Private function t emit the signal
    void receive::emitreceived(unsigned char *MPEG2_TS)
    {
        emit received(MPEG2_TS);
    }
    

    Now in the write class i have

    write.h

    #ifndef WRITE_H
    #define WRITE_H
    #include <QFile>   //To use files
    #include <QDataStream> //To stream to the file
    #include <QObject>     //To use the Macro of Qobject
    
    class write : public QObject
    {
        Q_OBJECT
    public:
        write();  //constructor
        //--------------FUNCTION TO CREATE A FILE BEGIN-------------
        void create_file(); //Create the File
        //--------------FUNCTION TO CREATE A FILE END---------------
    
    public slots:
        void write_to_file(unsigned char *MPEG2_TS);  //Write to File
    
    private:
        //--------------VARIABLES TO CREATE THE FILE BEGIN-----------
        QFile file;                                      //File to write the ts packets
        QDataStream out;                                 //To write in the file
        //--------------VARIABLES TO CREATE THE FILE END-------------
    };
    

    write.cpp

    #include "write.h"
    
    write::write()
    {
    
    }
    
    void write::create_file()
    {
        //Name of the file
        file.setFileName("data.ts");
    
        //Creation of the file, mode writeonly
        file.open(QIODevice::WriteOnly);
    }
    
    void write::write_to_file(unsigned char *MPEG2_TS)
    {
        out.setDevice(&file); //to hadel the file writing
    
        for (unsigned int j=0;j<245760-1;j++)
        {
        out<<MPEG2_TS[j]; //Insert the bytte o he file
        }
    }
    

    When i debugging the program, the signal is not recognized

    QObject::connect: No such signal receive::received(unsigned charMPEG2_TS) in ../PIZZA_FILE/mainwindow.cpp:88*


  • Qt Champions 2016

    @aurquiel said in Triying to create a custom signal with threads:

    connect(receive_usb,SIGNAL(received(unsigned charMPEG2_TS)), write_to_file, SLOT(write_to_file(unsigned charMPEG2_TS)));

    Hi
    Only include the type, not parameter name
    qDebug() << "status conn:" << connect(receive_usb,SIGNAL(received(unsigned char*)), write_to_file, SLOT(write_to_file(unsigned char*)));



  • yes it was that but my program doesn't do anything the file remains empty, can i pass the buffer through the signal emit to the slot?

    There is a way to debug the threads to see the values of the variables that their change?


  • Qt Champions 2016

    @aurquiel
    You can pass anything with the signal but maybe you can use a QString or QbyteArray as its known
    how to copy/queue it. For a custom class/structure you must register it.
    I think you need to use Qt::QueuedConnection for the connect.


  • Qt Champions 2016

    If you're not stuck to Qt4, convert to the Qt5 connect syntax so you at least get compile-time checking of the signals and slots. Aside from that @mrjj is correct, you need to register whatever it is transfered between the threads (if not over a Qt::DirectConnection connection) as a metatype. Not only declare the type with Q_DECLARE_METATYPE, but actually register it at runtime with qRegisterMetatype<>.



  • I stop the threads, i just connect the signals and not moving that objects to a the thread, i put a break point in the receive class.

    I am going to explain the code i have been writing

    Three class "backend" "receive" "write", and the main window

    I have a button in the main window with two connects

    Minwindow.cpp

    i have three objects for the three class

    backend * usb_channels=new backend;
    receive *receive_usb = new receive();
    write *write_to_file = new write();
    

    The connects

    connect(ui->pushButton,SIGNAL(clicked()),usb_channels,SLOT(channel_521000_57856()));
    

    this slot goes to a function in backend class i put a breakpoint there so the program goes there when a click the button

    connect(ui->pushButton,SIGNAL(clicked()),receive_usb,SLOT(transfer_usb()));
    

    Connect to a function in receive class that will emit the signal to write in the write class, put a break point in that function but is like the program doesn't use it nothing happends

    An this connection will do that to write

    connect(receive_usb,SIGNAL(received(QByteArray*)), write_to_file, SLOT(write_to_file(QByteArray*)));
    

    Now i am using QByteArray and not threads.

    Maybe there is a conflict for have multiplex connects to the same button, its like the program only recognize one connect the first one to backend function class, and not the second one to receive class. The Debug never cares about the breakpoint in the receive class in the function usb_transfeer()



  • I make it work, i just delete my building folder and build and.

    It works with threads and for connect i could pass unsigned char in the connect

    connect(receive_usb,SIGNAL(received(unsigned char*)), write_to_file, SLOT(write_to_file(unsigned char*)));
    

    My file is filling with ts (transpor stream packets from the usb)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.