如何在 Qt 中为 Linux 下启动的进程打开控制台 window?
How to open a console window for started process under Linux in Qt?
我使用 QProcess
打开控制台 window 但没有显示 window。
QProcess *process = new QProcess();
process->startDetached(command);
我想打开一个 window 来启动文本模式命令,例如adb -s xxxxx shell
打开 shell window 访问 Android 设备。
我找到关键字 CREATE_NEW_CONSOLE
但我不知道如何使用它。
我找到了解决方案,但我认为这是不好的方法:
QString program = "gnome-terminal";
QStringList arguments = QStringList()<<"-e"<< adbCommand;
process->startDetached(program, arguments);
在 Windows 上,控制台和 GUI 可执行文件在可执行格式级别 上存在区别;当启动控制台可执行文件时,操作系统本身要么回收当前控制台(如果父进程本身已经存在于控制台中),要么为新启动的进程分配一个新控制台。
在Linux上,反而没有这样的区别;系统对终端仿真器(这是常规应用程序)一无所知,当可执行文件启动时,它会从父级继承控制终端(尽管有系统调用会影响它),得到 stdin/stdout/stderr 附加到它(再次,除非执行重定向)并开始做它的事情。 GUI 程序只是不希望通过终端进行交互的程序,"happen" 与 X(或 Wayland)服务器对话,但同样,系统无法知道这一点,这都是约定俗成的。
要解决您的问题:当您从 "GUI" 应用程序直接从 adb
到 QProcess
开始时,子进程会继承您的应用程序具有的任何控制终端;因此,如果您的程序是通过 Qt Creator 启动的,您将在 "Application Output" 窗格中看到它的输出,当您从控制台启动它时,您将能够通过它与 adb
交互,并且等等。
如果你想打开 adb
到一个单独的终端,你必须明确地启动终端模拟器,告诉它依次调用 adb
;一旦您知道要启动的终端仿真器是什么,这通常很简单,因为任何值得使用的终端仿真器都将接受 -e program_name arguments
选项(模仿 xterm
)。
然而,我们的处境很糟糕,因为在典型的 Linux 时尚中,没有标准的、与桌面无关的方式来了解什么是 "default" 终端模拟器,即使几乎每个DE/panel/whatever 某处有此设置。
寻找这种与桌面无关的东西的地方通常是 freedesktop.org(以前称为 X Desktop Group,因此您会在他们的大部分东西中看到首字母缩写词 XDG),其中有a still unresolved bug from 2015 about this kind of issue1. You can see in this mailing list thread 曾考虑过修复它的方法,但 AFAIK 它刚刚消失。
所以,在我看来你有两个选择:
刚刚启动xterm
;它不是特别漂亮,但是没有它就没有图形化的 Linux 安装(即使它不是 "real" xterm
,也会有一个恰当命名的符号链接),所以你确定它会起作用。
QStringList arguments;
// keep your arguments separated to avoid surprises with escaping
arguments << "-e" << "adb" << "-s" << "xxxx" << "shell";
process->startDetached("xterm", arguments);
如果你想对你的用户特别友好,你可以让终端模拟器使用一个设置,默认设置为 xterm
以确保一般情况下正常工作。
无论如何,请不要对您的特定 DE 使用的终端模拟器进行硬编码 - 并非每个人都使用 gnome-terminal
,许多人甚至都没有安装它。
- 这个问题特别是关于 "what should
xdg-open
do when meeting .desktop
(=launcher) files that say "这个程序必须 运行 在一个单独的控制台中”,这几乎就是您要解决的问题。如上所述,几乎任何 DE 都支持此标志,但与桌面无关的 xdg-open
不能,因为无法向当前 DE 询问默认终端是什么。
我使用 QProcess
打开控制台 window 但没有显示 window。
QProcess *process = new QProcess();
process->startDetached(command);
我想打开一个 window 来启动文本模式命令,例如adb -s xxxxx shell
打开 shell window 访问 Android 设备。
我找到关键字 CREATE_NEW_CONSOLE
但我不知道如何使用它。
我找到了解决方案,但我认为这是不好的方法:
QString program = "gnome-terminal";
QStringList arguments = QStringList()<<"-e"<< adbCommand;
process->startDetached(program, arguments);
在 Windows 上,控制台和 GUI 可执行文件在可执行格式级别 上存在区别;当启动控制台可执行文件时,操作系统本身要么回收当前控制台(如果父进程本身已经存在于控制台中),要么为新启动的进程分配一个新控制台。
在Linux上,反而没有这样的区别;系统对终端仿真器(这是常规应用程序)一无所知,当可执行文件启动时,它会从父级继承控制终端(尽管有系统调用会影响它),得到 stdin/stdout/stderr 附加到它(再次,除非执行重定向)并开始做它的事情。 GUI 程序只是不希望通过终端进行交互的程序,"happen" 与 X(或 Wayland)服务器对话,但同样,系统无法知道这一点,这都是约定俗成的。
要解决您的问题:当您从 "GUI" 应用程序直接从 adb
到 QProcess
开始时,子进程会继承您的应用程序具有的任何控制终端;因此,如果您的程序是通过 Qt Creator 启动的,您将在 "Application Output" 窗格中看到它的输出,当您从控制台启动它时,您将能够通过它与 adb
交互,并且等等。
如果你想打开 adb
到一个单独的终端,你必须明确地启动终端模拟器,告诉它依次调用 adb
;一旦您知道要启动的终端仿真器是什么,这通常很简单,因为任何值得使用的终端仿真器都将接受 -e program_name arguments
选项(模仿 xterm
)。
然而,我们的处境很糟糕,因为在典型的 Linux 时尚中,没有标准的、与桌面无关的方式来了解什么是 "default" 终端模拟器,即使几乎每个DE/panel/whatever 某处有此设置。
寻找这种与桌面无关的东西的地方通常是 freedesktop.org(以前称为 X Desktop Group,因此您会在他们的大部分东西中看到首字母缩写词 XDG),其中有a still unresolved bug from 2015 about this kind of issue1. You can see in this mailing list thread 曾考虑过修复它的方法,但 AFAIK 它刚刚消失。
所以,在我看来你有两个选择:
刚刚启动
xterm
;它不是特别漂亮,但是没有它就没有图形化的 Linux 安装(即使它不是 "real"xterm
,也会有一个恰当命名的符号链接),所以你确定它会起作用。QStringList arguments; // keep your arguments separated to avoid surprises with escaping arguments << "-e" << "adb" << "-s" << "xxxx" << "shell"; process->startDetached("xterm", arguments);
如果你想对你的用户特别友好,你可以让终端模拟器使用一个设置,默认设置为
xterm
以确保一般情况下正常工作。
无论如何,请不要对您的特定 DE 使用的终端模拟器进行硬编码 - 并非每个人都使用 gnome-terminal
,许多人甚至都没有安装它。
- 这个问题特别是关于 "what should
xdg-open
do when meeting.desktop
(=launcher) files that say "这个程序必须 运行 在一个单独的控制台中”,这几乎就是您要解决的问题。如上所述,几乎任何 DE 都支持此标志,但与桌面无关的xdg-open
不能,因为无法向当前 DE 询问默认终端是什么。