¿Cómo enviar una señal Qt que contenga un cv :: Mat?

En resumen, me sale el siguiente error:

QObject::connect: Cannot queue arguments of type 'cv::Mat'
(Make sure 'cv::Mat' is registered using qRegisterMetaType().)

Lo que intento hacer es enviar una señal que contenga dos imágenes cv::Mat desde un QThread al hilo principal, para poder mostrar el resultado. No hay error de tiempo de compilación, pero cuando ejecuto el programa, se atasca en un punto de interrupción en qglobal.h (inline void qt_noop() {}).

He intentado agregar Q_DECLARE_METATYPE(cv::Mat) al código, fue en vano. Estoy bastante apestar con lo que hacer ahora.

código

En una clase QThread:

signals:
void sndFlow(cv::Mat &leftEye, cv::Mat &rightEye);

void eyesDriver::run()
{
    forever
    {
        flow->draw(leftEye, rightEye);
        sndFlow(leftEye, rightEye);
    }
}

Capturando en una clase QObject:

public slots:
void recFlow(cv::Mat &leftEye, cv::Mat &rightEye);

void myClass::recFlow(cv::Mat &leftEye, cv::Mat &rightEye)
{
    cv::imshow("left", leftEye);
    cv::imshow("rigth", rightEye);
    cv::waitKey(40);
}

En principal:

Q_DECLARE_METATYPE(cv::Mat)
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qRegisterMetaType< cv::Mat >("cv::Mat");
    // create objects from QThread and QObject class
    QObject::connect(&qthread, SIGNAL(sndFlow(cv::Mat&,cv::Mat&)),
                     &qobject, SLOT(recFlow(cv::Mat&,cv::Mat&)));
    qthread.start();
    return a.exec();
}

Cambiando las variables de ranura de señal a QSharedPointer< cv::Mat > tampoco funciona. Da el mismo error:

QObject::connect: Cannot queue arguments of type 'QSharedPointer<cv::Mat>'
(Make sure 'QSharedPointer<cv::Mat>' is registered using qRegisterMetaType().)

OBRAS

Está bien, parece funcionar. me he mudado qRegisterMetaType< cv::Mat >("cv::Mat"); justo antes de la QObject::connect llamar. Sin embargo, todavía tengo que 'F5' más allá del punto de interrupción en qglobal.h, funciona después.

Puede que me equivoque, pero parece que la ubicación de qRegisterMetaType no es trivial.

preguntado el 10 de marzo de 12 a las 11:03

Para ser honesto, creo que podrías haber cambiado algo más sin darte cuenta, porque no creo que importe dónde llamas a qRegisterMetaType si es antes de la primera conexión. ¿O no lo fue? -

1 Respuestas

Necesitas llamar qRegisterMetaType además de la macro (o en lugar de ella, según sus necesidades). Esto es necesario para que las señales puedan ordenar sus datos a través de subprocesos. Sin embargo, podría ser una idea más inteligente pasar por referencia o puntero inteligente, o puntero sin procesar si está utilizando la jerarquía QObject para administrar la vida útil del objeto.

Respondido 21 Oct 16, 18:10

¿Alguna idea de dónde debo llamar a esa función? Al igual que con la macro, actualmente pruebo ambas en el archivo main.cpp, la macro sobre la función principal, la qRegisterMetaType justo dentro de ella. Eso no lo resuelve, por lo que probablemente deba llamar a esa última función en otro lugar. - Raf Berkvens

Creo que debe hacerse antes de llamar a connect. Asegúrese de que esta clase tenga un constructor público predeterminado (es decir, un constructor sin parámetros), un constructor de copia pública y un destructor público. De lo contrario, debe usar una de mis sugerencias alternativas o escribir un envoltorio QObject personalizado a su alrededor (pero probablemente no lo necesite). - Tamás Szelei

cv::Mat tiene todo esto, pero aún no funcionará. Intenté llamar por referencia o un puntero, pero produce el mismo problema. ¿Qué puntero inteligente sugieres? No estoy familiarizado con esos. - Raf Berkvens

Debe funcionar si pasa por referencia, entonces hay otro problema. ¿Puede publicar la declaración de su señal y ranura, y cómo y dónde los conecta? - Tamás Szelei

¿Cuál es el error que está obteniendo al usar parámetros de referencia? - Tamás Szelei

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.