Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Triying to create a custom signal with threads
QtWS25 Last Chance

Triying to create a custom signal with threads

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 1.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    aurquiel
    wrote on last edited by aurquiel
    #1

    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 char*MPEG2_TS) in ../PIZZA_FILE/mainwindow.cpp:88

    mrjjM 1 Reply Last reply
    0
    • A aurquiel

      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 char*MPEG2_TS) in ../PIZZA_FILE/mainwindow.cpp:88

      mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

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

      1 Reply Last reply
      0
      • A Offline
        A Offline
        aurquiel
        wrote on last edited by aurquiel
        #3

        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?

        mrjjM 1 Reply Last reply
        0
        • A aurquiel

          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?

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by mrjj
          #4

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

          1 Reply Last reply
          0
          • kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by
            #5

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

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            1
            • A Offline
              A Offline
              aurquiel
              wrote on last edited by aurquiel
              #6

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

              1 Reply Last reply
              0
              • A Offline
                A Offline
                aurquiel
                wrote on last edited by
                #7

                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)

                1 Reply Last reply
                1

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved