-1

I use QProcess to open a console window but no window is shown.

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

I want to open a window to start a text-mode command, e.g. adb -s xxxxx shell to open a shell window to access an Android device.

I found the keyword CREATE_NEW_CONSOLE but I don't know to use it.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
kien bui
  • 1,760
  • 2
  • 17
  • 33

2 Answers2

0

I got a solution but I think this is bad way:

QString program = "gnome-terminal";
QStringList arguments = QStringList()<<"-e"<< adbCommand;
process->startDetached(program, arguments);
kien bui
  • 1,760
  • 2
  • 17
  • 33
  • Yes, it is a bad way - on my machine for example this won't start a thing, as I don't use (nor even have installed) `gnome-terminal` but `konsole`. In general, the only safe thing is to start `xterm` (which should be present on pretty much any graphical installation), although it's possible that there's some XDG setting for the default terminal. – Matteo Italia Jun 01 '18 at 06:59
  • Could you suggest for me a better solution? Tks. – kien bui Jun 01 '18 at 07:03
0

On Windows there's a distinction at executable format level about console and GUI executables; when console executables are started, the operating system itself either recycles the current console (if the parent process itself already lives in a console) or allocates a new one for the newly started process.

On Linux, instead, there's no such distinction; the system doesn't know a thing about terminal emulators (which are regular applications), and when an executable is started it inherits the controlling terminal from the parent (although there are syscalls that can affect this), gets stdin/stdout/stderr attached to it (again, unless redirection is performed) and goes off to do its stuff. GUI programs are just programs that don't expect interaction through a terminal and "happen" to talk to an X (or Wayland) server, but again, the system has no way to know about this, it's all convention.

To come to your problem: when you start straight adb through QProcess from your "GUI" application, the child process inherits whatever controlling terminal your application has; so, if your program has been launched through Qt creator you'll see its output in the "Application Output" pane, when you launch it from a console you'll be able to interact with adb through it, and so on.

If you want to open adb into a separate terminal, you'll have to start the terminal emulator explicitly, telling it in turn to call adb; once you know what is the terminal emulator you want to start, this is generally simple, as any terminal emulator worth using will accept the -e program_name arguments option (mimicking xterm).

However, we are in a sad situation, as in a typically Linux fashion there's no standard, desktop-agnostic way to know what is the "default" terminal emulator, even if pretty much every DE/panel/whatever have this setting somewhere.

The place to look for this kind of desktop-agnostic stuff is generally freedesktop.org (formerly known as X Desktop Group, hence the acronym XDG that you'll see in much of their stuff), which has a still unresolved bug from 2015 about this kind of issue1. You can see in this mailing list thread the approaches that have been considered to fix it, but AFAIK it just died out.

So, in my opinion you have two options:

  • just launch xterm; it's not particularly beautiful, but there's no graphical Linux installation that will ship without it (and even if it's not the "real" xterm, there will be an aptly-named symlink), so you are sure that it will work.

    QStringList arguments;
    // keep your arguments separated to avoid surprises with escaping
    arguments << "-e" << "adb" << "-s" << "xxxx" << "shell";
    process->startDetached("xterm", arguments);
    
  • if you want to be extra nice to your users, you can make the terminal emulator to use a setting, set by default to xterm to keep the general case surely working.

In any case, please don't hardcode the terminal emulator used by your particular DE - not everybody uses gnome-terminal, and many don't even have it installed.


  1. The issue in particular is about "what should xdg-open do when meeting .desktop (=launcher) files that say "this program has to be run in a separated console", which is pretty much the problem you are trying to solve. As said above, pretty much any DE honor this flag, but the desktop-agnostic xdg-open cannot, as there's no way to ask to the current DE what the default terminal is.
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299