如何在 Qt 中打开 Linux 下启动进程的控制台窗口?

Posted

技术标签:

【中文标题】如何在 Qt 中打开 Linux 下启动进程的控制台窗口?【英文标题】:How to open a console window for started process under Linux in Qt? 【发布时间】:2018-05-31 11:17:30 【问题描述】:

我使用QProcess打开一个控制台窗口,但没有显示任何窗口。

QProcess *process = new QProcess();
process->startDetached(command);

我想打开一个窗口来启动一个文本模式命令,例如adb -s xxxxx shell 打开 shell 窗口以访问 android 设备。

我找到了关键字CREATE_NEW_CONSOLE,但我不知道如何使用它。

【问题讨论】:

你想在控制台而不是 qtCreator 上看到你的调试消息吗? 没有。我想运行一个脚本 你的linux 是什么...你知道它的终端应用程序名称吗? 是ubuntu 14 我试过了。但我需要打开一个窗口而不是 qtcreator 控制台 【参考方案1】:

在 Windows 上,在可执行格式级别关于控制台和 GUI 可执行文件有区别;当控制台可执行文件启动时,操作系统本身要么回收当前控制台(如果父进程本身已经存在于控制台中),要么为新启动的进程分配一个新控制台。

相反,在 Linux 上,没有这样的区别;系统对终端仿真器(它们是常规应用程序)一无所知,并且当启动可执行文件时,它会从父级继承控制终端(尽管有可能影响这一点的系统调用),附加 stdin/stdout/stderr到它(再次,除非执行重定向)并开始做它的事情。 GUI 程序只是不期望通过终端进行交互并“发生”与 X(或 Wayland)服务器对话的程序,但同样,系统无法知道这一点,这都是约定俗成的。

解决您的问题:当您从“GUI”应用程序直接启动adbQProcess 时,子进程将继承您的应用程序具有的任何控制终端;因此,如果您的程序是通过 Qt creator 启动的,您将在“应用程序输出”窗格中看到它的输出,当您从控制台启动它时,您将能够通过它与 adb 进行交互,依此类推。

如果你想在一个单独的终端中打开adb,你必须显式启动终端模拟器,然后告诉它调用adb;一旦您知道要启动的终端模拟器是什么,这通常很简单,因为任何值得使用的终端模拟器都会接受-e program_name arguments 选项(模仿xterm)。

但是,我们处于一个可悲的境地,因为在典型的 Linux 方式中,没有标准的、与桌面无关的方式来知道什么是“默认”终端仿真器,即使几乎每个 DE/面板/任何东西都有这个设置某处。

寻找这种与桌面无关的东西的地方通常是 freedesktop.org(以前称为 X Desktop Group,因此您会在他们的大部分东西中看到首字母缩写词 XDG),其中有 a still unresolved bug from 2015 约这类问题1。您可以在 this mailing list thread 中看到已考虑修复它的方法,但 AFAIK 它刚刚消失了。

所以,我认为你有两个选择:

只需启动xterm;它不是特别漂亮,但是没有它就没有图形 Linux 安装(即使它不是“真正的”xterm,也会有一个恰当命名的符号链接),所以你确信它会工作。

QStringList arguments;
// keep your arguments separated to avoid surprises with escaping
arguments << "-e" << "adb" << "-s" << "xxxx" << "shell";
process->startDetached("xterm", arguments);
1234563

无论如何,请不要对特定 DE 使用的终端仿真器进行硬编码 - 不是每个人都使用 gnome-terminal,而且很多人甚至没有安装它。


    这个问题特别是关于“当遇到.desktop (=launcher) 文件说“这个程序必须在单独的控制台中运行”时,xdg-open 应该做什么,这几乎就是你正在尝试的问题解决。如上所述,几乎所有 DE 都支持此标志,但与桌面无关的 xdg-open 不能,因为无法询问当前 DE 的默认终端是什么。

【讨论】:

【参考方案2】:

我有一个解决方案,但我认为这是不好的方法:

QString program = "gnome-terminal";
QStringList arguments = QStringList()<<"-e"<< adbCommand;
process->startDetached(program, arguments);

【讨论】:

是的,这是一个不好的方法——例如在我的机器上这不会启动,因为我没有使用(甚至没有安装)gnome-terminal,而是konsole。一般来说,唯一安全的事情是启动xterm(几乎所有图形安装都应该存在),尽管默认终端可能有一些 XDG 设置。 您能给我建议一个更好的解决方案吗?谢了。

以上是关于如何在 Qt 中打开 Linux 下启动进程的控制台窗口?的主要内容,如果未能解决你的问题,请参考以下文章

linux 如何启动,停止,查看服务

【fd】Linux文件描述符

linux下QT中如何使用QProcess运行linux命令。

Linux下如何查看进程打开的文件以及修改进程打开文件数上限

Linux下Tomcat的启动关闭杀死进程

如何在 systemd 下管理linux系统的时间和日期