Qt4、QProcess、R:标准输出中的垃圾,行较长

Posted

技术标签:

【中文标题】Qt4、QProcess、R:标准输出中的垃圾,行较长【英文标题】:Qt4, QProcess, R: garbage in standard output with longer lines 【发布时间】:2011-04-03 03:13:59 【问题描述】:

我正在为 R 开发另一个 GUI 前端(主要是在或多或少相关材料上研究 Qt4),并且我偶然发现了所涉及组件的异常行为。 如果我尝试通过 QProcess 向 R 的标准输入写入一行 76 个字符或更长的字符,则输出(命令的回声)返回时包含垃圾,并且该行的部分内容被重复。例如:

freq.some <- recode(freq, "'some' = 'no'; 'all or most' = 'yes'; else = NA");

回显为

freq.some <- recode(freq, "'some' = 'no'; 'all or most' = 'yes'; else = NA"
< "'some' = 'no'; 'all or most' = 'yes'; else = 
NA")                         ;

我尝试在 QByteArray 级别上使用输出,但异常已经存在。

我的 Qt 版本是 4.6.3,R v. 2.11.1,Debian Squeeze。相关代码sn-ps如下:

这就是我开始 R 的过程:

arrr = new QProcess(this);
QString program = "R --interactive --no-readline";
arrr->start(program, QProcess::Unbuffered | QProcess::ReadWrite);

这就是我将命令写入 R 进程的方式:

QString cmd = ui->lineEdit->displayText();
QString tmp = cmd + "\n";
arrr->write(tmp.toUtf8().data());

这是我读取进程输出的方式:

QByteArray output;
QTextStream *ts = new QTextStream(&output);
output = arrr->readAllStandardOutput();
QString r_output = ts->readAll();

readyRead() 信号发生在进程中的读取。

如果我的问题不符合本网站公认的标准,我提前道歉。谢谢。

【问题讨论】:

【参考方案1】:

我担心从长远来看,您可能会发现管道进入 R 并读取标准输出相当麻烦。我建议您可以考虑一些替代方案:

Rserve 提供您通过 tcp/ip 连接的无头 R 服务器;存在一个示例 C++ 客户端

根据“编写 R 扩展”手册直接嵌入 R(但您会使用大量相当裸机的 C 代码)

RInside 使用同级包 Rcpp 包装了 R API,用于嵌入到更高抽象的 C++ 中。另外,我最近从Qt 添加了一个详细的示例,它现在在 SVN 中(但还没有在 CRAN 中);还有一个 detailed blog post 关于它。

【讨论】:

(1) 我可能应该提一下,在我从 Lenny 升级到 Squeeze 之前,并没有出现这个问题。 (2) 我尝试制作一个简单的跨平台解决方案。我担心需要独立服务器或使用额外的库可能会使该目标变得复杂或无法实现。 (1) 如果您可以将其归结为可重现的示例(最好不需要 Qt),那么 R-devel 肯定会想听听。 (2) 当然,您需要权衡灵活性和可靠性。你这里没有后者。 Rcpp 在 Debian 中(由我维护),我可以轻松添加 RInside(还没有需求),那时它是“所有库存的 Debian”,所以谁在乎是否加载了另一个共享库?并不是说 R 本身是轻量级的…… (1) 如何将 Qt 应用程序归结为非 Qt 示例? R 本身作为控制台应用程序工作得很好。据我了解,问题出在 Qt 框架内。我的应用程序要做的就是写入和读取 R 进程,并成为上面的“漂亮”层(特别是,允许​​分块编辑 R 的输出以生成整洁的报告)。 (2) “Crossplatfrom”确切地说是相当一部分目标受众既不使用特定的 Debian,也不使用一般的 Linux。 (1) 你可以使用 echo 管道进入 R;并通过 sed/perl/python/... 接收答案。请记住,旨在演示 R 中的错​​误。请以易于复制错误的方式进行。 (2) 人生充满了取舍。 (1) 是的,我正在尝试进一步调查此问题。到目前为止,我可以说,如果我使用 qprocess 使用 wine 启动 Windows 版本的 R,输出将按应有的方式处理。我现在将尝试管道,看看它是 R 还是 Qt。 (2) 确实如此,但如果我无法在 windows 下运行该应用程序,它就没有任何价值。另外,我自己没有 MS Windows,所以我提供跨平台兼容性的唯一希望是坚持使用 Qt 及其跨平台安全结构。

以上是关于Qt4、QProcess、R:标准输出中的垃圾,行较长的主要内容,如果未能解决你的问题,请参考以下文章

QT4:为啥 bash shell 比使用 QProcess 调用的相同脚本更快?

如何确定在 Linux 上使用 Qt4 终止 QProcess 的信号?

无法在 Qt4 的 QProcess 中正确启动 mysqldump

QProcess 从标准输入和标准输出的文件开始

使用 QProcess 读取标准输出

QProcess -> 在 Linux 上从 sftp 读取标准输出