【问题标题】:Qt: Cannot queue arguments of type 'QProcess::ProcessError' - QProcess::ProcessError(FailedToStart)Qt:无法对“QProcess::ProcessError”类型的参数进行排队 - QProcess::ProcessError(FailedToStart)
【发布时间】:2017-08-12 16:58:04
【问题描述】:

我正在尝试将序列化图像传递给我在 Qt 程序中启动的进程。 但是,这样做时,我会收到以下错误消息:

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

我试图传递的图像是一个 cv::Mat,我将其转换为 QImage,然后再转换为 QString。

在将参数流式传输到变量 params 时,有人能告诉我我做错了什么吗?我目前的猜测是问题在于图像的序列化形式,即它包含许多双引号,这就是为什么在下面的行中插入 matQStr 的值(将其流式传输到参数)时,会出现误解

其他一切都很好,只是在尝试传递图像时出现问题。

如果您可能需要这些信息,我正在启动的过程是一个 python 函数,它使用 openCV 带 1 个参数,即我试图传递的图像。序列化图像以将其传递给函数,显然是最简单的解决方案。

代码:

double myClass::runPythonScrypt()
{
    cv::Mat imageParameter = cv::imread("/home/John/Desktop/image1.jpg", CV_LOAD_IMAGE_COLOR);
    QImage img((uchar*)imageParameter.data, imageParameter.cols, imageParameter.rows, imageParameter.step1(), QImage::Format_RGB32);
    std::string matStdString(imageParameter.begin<unsigned char>(), imageParameter.end<unsigned char>());
    QString matQStr = QString::fromStdString(matStdString);

    QProcess p;
    QStringList params;
    connect(&p, &QProcess::errorOccurred, qApp, &QApplication::aboutQt );
    int a=55;
//I added "this is the end in the string because in the beginning I thought maybe some overflow occured and therefor not the entire image was passed to the process, yet you can see that this sentence gets printed"
    params<< "-c" << "import cv2; import imp; foo = imp.load_source('myTest', '/home/John/fw/demos/myTest.py'); from myTest import myClass; myClassObj = myClass(); print myClassObj.myTestFunction( "+ matQStr +" ) this isthe end;";



        qDebug()<<params;
        p.start("python2", params);
        if(! p.waitForFinished(-1))
        {qDebug()<<"it failedddd";}

        qDebug()<<"error that occured: "<<p.error();

        QString errors = p.readAllStandardError();
        qDebug()<<"occured errors:"<<errors;

        QString p_stdout = p.readAllStandardOutput();


...

}

生成的输出:

started recognition thread
("-c", "import cv2; import imp; foo = imp.load_source('myTest', '/home/John/fw/demos/myTest.py'); from myTest import myClass; myClassObj = myClass(); print myClassObj.myTestFunction(

...etc...

����������������������Ѧ����<\u0013\u001B\u0014�������������������������������������������������������������������
����������������������������������������������������������������������u0011\u0017\u0005\b=
*\u0007\u0005\u0016=/\"6=;<@@;;>AA@:311373//+1HcVFPs\u007FeH?z\u007FBY�f\\�oJV��������������������t?
>K\\`RJMTY`a[RSWQMJECBDDIEEEJKN
KJGJHF>@AGFHDC=<89:AA<0/4*%%+/../+##.657>9;=@BBBA@A@><:9<?@@?>?BB;;:88:;<>;;;>>=<;<@@>=<<<;:::;;<998:7337:;<;:
88955555677;;956:954578887879::8533146764441/./0110/--0563/1220./2665420/011222147;FEA>?>;8>=<BGG;04,,-%$&$ \")0
1./3332/,))++)),.)

etc...

10210.,,,-.-/12/*'',-023432-%#')')/04;94:<3.).51/1.((*.10,'1/23547702.0%#0+114; ) this isthe end;")

started recognition thread
QObject::connect: Cannot queue arguments of type 'QProcess::ProcessError'
(Make sure 'QProcess::ProcessError' is registered using qRegisterMetaType().)
it failedddd
error that occured:  QProcess::ProcessError(FailedToStart)
occured errors: ""
name:  ""
certitude:  0
return value:  0
2

编辑:

使用的python脚本:

#!/usr/bin/env python2

import cv2
import os
import numpy as np


class myClass:

    def __init__(self): pass

    def myTestfunction2(self):     
        image= cv2.imread("/home/John/Desktop/image1.jpg")
        cv2.imshow("image", image)

    def myTestFunction(self, a):
        print('my test function showing passed image as parameter')
        cv2.imshow('a', a)        
        cv2.waitKey(0)
        return ('John', a)

请注意,这一行用于流式传输参数而不是当前在我的软件中的参数可以正常工作:

params<< "-c" << "import cv2; import imp; foo = imp.load_source('myTest', '/home/John/fw/demos/myTest.py'); from myTest import myClass; myClassObj = myClass(); print myClassObj.myTestFunction(cv2.imread('/home/John/Desktop/image1.jpg'));";

但它并不能完全满足我的需要,我需要传递一个 cpp 变量而不是使用 cv2.imread()

【问题讨论】:

  • 你可以显示.py
  • @eyllanesc 添加了 python 脚本
  • 从我在您的代码中看到的内容来看,您正在读取图像,将其转换为字符串,并且您想将其作为参数的一部分传递给 qprocess,我认为该字符串中的某处字符")" 出现,即...myTestFunction(partial_string) Another_partial)... 导致应用程序无法启动。
  • @eyllanesc 好吧,QProcess 完美地向他展示了系统甚至没有启动 python,所以实际的 python 代码是否正确并不重要,他使用了 linux 中禁止的巨大参数,那就是为什么系统甚至没有启动应用程序。更多信息在下面我的回答中
  • 好点,我没有考虑到,这是最可能的。

标签: c++ qt opencv


【解决方案1】:

我在您的代码中没有看到注册metaType 行,所以请尝试:

QProcess p;
QStringList params;
qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); // new line
connect(&p, &QProcess::errorOccurred, qApp, &QApplication::aboutQt );

这应该可以解决

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

问题,所以你的连接会工作,你会看到Qt窗口,但如果由于某些原因QProcess无法启动,那么它仍然有问题的原始来源,所以^只是修复用于连接。

无论如何QProcess 在这里向您展示了问题的根源:

 error that occured:  QProcess::ProcessError(FailedToStart)

这通常意味着您尝试使用错误的路径。请重新检查路径或尝试使用absolutePath,也许它会解决原来的问题。

编辑:

好的,在您发表评论之后,很明显,linux 不能接受无限量的参数数据,您尝试在此处编码大量信息,请检查此link f.e.所以实际上你的第一种方法有正常的长度并且它有效,现在你传递了巨大的信息,你甚至不运行 python,是的,这是正确的路径,但系统只是拒绝它并向你显示 QProcess::ProcessError(FailedToStart),当然它可以使用... has too big argument 或类似的信息会更方便,但我们没有。

总结:

所以你的方法是不可能实现的(不同的系统也有不同的限制,所以看起来它甚至很危险(不可移植)),所以你需要重写你的应用程序。我只能建议尝试从Qt 保存tmp 文件并将tmp 路径传递给python 脚本,就像上面链接中建议的那样。

但最好的方法可能只是为C++/Qt 编译OpenCV 并直接在此处使用原始OpenCV 代码而不使用tmp 文件等,这将大大增加performance。如果是某个任务,请与您的 team 讨论这个问题;如果是您的 personal 项目,请执行 as you wish

【讨论】:

  • 好的,添加了您添加的行,确实解决了注册问题。路径是 100% 正确的。如前所述,只要我不传递图像,这条线就可以很好地工作。错误可能在于图像被序列化并流式传输到变量参数的方式(我想这是我的问题的主要原因)。您对 FailedToStart 错误有何建议?
  • 请注意,这一行用于流式传输参数而不是我的软件中当前使用的参数可以正常工作:params
  • @trilolil 请检查编辑,不幸的是我帮不上忙,除非我对大参数列表的想法是错误的
最近更新 更多