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 char*MPEG2_TS) in ../PIZZA_FILE/mainwindow.cpp:88
-
@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*))); -
@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. -
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 withQ_DECLARE_METATYPE
, but actually register it at runtime withqRegisterMetatype<>
. -
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)