Important: Please read the Qt Code of Conduct -

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


    //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
        //create the file ts
        //Move to threads
        //Strat the threads
        //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
        libusb_device_handle *device_handle_receive;
    public slots:
        void transfer_usb(); //recieving tranfer from USB
        //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);
        //Signal emited
        void received(unsigned char *MPEG2_TS);
    #endif // RECEIVE_H


    #include "receive.h"
    //-----------------------FUNCTION FOR USB RECEIVING BEGIN----------------
    void receive::transfer_usb()
        //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
    //-----------------------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


    #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
        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
        //--------------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-------------


    #include "write.h"
    void write::create_file()
        //Name of the file
        //Creation of the file, mode 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 char*MPEG2_TS) in ../PIZZA_FILE/mainwindow.cpp:88

  • Lifetime Qt Champion

    @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)));

    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?

  • Lifetime Qt Champion

    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.

  • Moderators

    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


    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


    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 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