QProcess running "xterm" - how to read / write directly to "xterm"
-
This post is sort off continuation of this
https://forum.qt.io/topic/118925/qprocess-c-syntax-passing-program-and-argumentsI went to use QProcess to run "xterm" , because it was getting too complex dealing with file generated by QProcess using "system call". .
Now I like toread directly from xterm - not from QProcess - something similar to using readAllStandardOutput()'
write directly to xtermI am missing the "link" / connection (pointer / object ?) between QProcess and running "xterm".
I have a basic understanding how QProcess builds and manges another task / application.
In my example the QProces "exe" application - xterm - builds GUI - in very basic terms a gui window.
It is not a widget, it is not yet apart of the Qt , it is just "top floating window".I did some tests building generic widget , in code , using "layout" etc. it did build a true widget, still free floating and not related to the rest of the QT application.
Now QDesigner has "frame" and "widget" widgets - so is there a way to utilize these to integrate window generated by Qprocess - after "xterm" is running ?
If the free floating window is not part of QTabWidget - switching tabs does not work - it keeps adding new process /xterm windows....
Any help would be appreciated.
-
@AnneRanch said in QProcess running "xterm" - how to read / write directly to "xterm":
I am missing the "link" / connection (pointer / object ?) between QProcess and running "xterm".
The only QProcess mediated link between the input and output of the managed process and your program is the standard input/output streams. If a program does not use these streams, as is the case with the xterm GUI terminal, then QProcess does not have those facilities.
I did some tests building generic widget , in code , using "layout" etc. it did build a true widget, still free floating and not related to the rest of the QT application.
Now QDesigner has "frame" and "widget" widgets - so is there a way to utilize these to integrate window generated by Qprocess - after "xterm" is running ?I think you mean, "Can I embed another application within a Qt widget?"
You may be able to achieve this with QWindow::fromWinId() (see this Stack Overflow question). Obtaining the window id of the child xterm may be the hardest part.
Note that this is very different from having control of what is going on inside that external program.
If the free floating window is not part of QTabWidget - switching tabs does not work - it keeps adding new process /xterm windows....
"It" in this context is your code. If your code creates a new xterm instance every time you switch tabs then you need to put that creation code somewhere else.
-
I was going to start another thread but it seems that I can continue here.
I have several issues with my application and it is hard , for me , keep them separated because they do interact-
Ability to directly read /write to xterm
I have plenty of working code to retrieve and write data to the whatever "TERMINAl" I choose to use. The issue is getting the
data to and from the actual command - "bluetooothctl" - it contains control code , color etc...
I can manage that task. -
I need better , direct interaction, with "bluetoothctl;" and that is why I am using "terminaL
I can manage putting data into QTabWidget - from files. ' -
What I need now is to include the window created by QProcess as a widget in QTabWidget.
The attached test code does that with plain button . I have combined QCreator with QDEsigner to accomplish that.
QPushButton *button1 = new QPushButton("TEST button One"); //QHBoxLayout *layout = new QHBoxLayout(ui->widget_2); ui->widget_2->layout()->addWidget(button1); // ui->widget_2->layout()->addWidget(process);
I can add code build widget to form / QDesigner implemented "widget" just fine... it goes to tab and shows when such tab is selected. and "goes away" when not selected.
Now the real , current issue , QProcess is NOT a widget - it cannot be simply added to the TAB /widget /layout
( i think 'qterminal" is a widget , but it has an issue processing multiple arguments passed to command ... hence useless for me but I may try to hack it , again ...)
)
That is my current task I need help with resolving . -how to change the QProcess object (?) to QWidget.?
I am truly sorry about this mess, but to accomplish my ultimate goal I need to go "baby steps " and solve each problem in some sequential fashion. Unfortunately it is not always "just about x" and some folks have issues with "putting the question into correct category / box".
I am sorry if I did not reply to concerns expressed in the last post...
-
-
@AnneRanch said in QProcess running "xterm" - how to read / write directly to "xterm":
how to change the QProcess object (?) to QWidget.?
You cannot.
What I need now is to include the window created by QProcess as a widget in QTabWidget.
See my last post.
Unless I have misunderstood this entire trail of posts over months, your actual requirement is to scan for and display Bluetooth devices. You could not make QBlueTooth work for you, you moved on to running
bluetoothctl
through QProcess and could not make that work, and now you want to complicate that by trying to controlbluetoothctl
when it is running inside an independent GUI terminal. Forgive me for thinking that you are actively moving further away from the original problem.What does your program have to achieve?
-
@AnneRanch This may be OT but maybe QTermWidget might be an option for you to execute programs and get the output control you need.
-
@AnneRanch said in QProcess running "xterm" - how to read / write directly to "xterm":
What I need now is to include the window created by QProcess as a widget in QTabWidget.
Now the real , current issue , QProcess is NOT a widget - it cannot be simply added to the TAB /widget /layout
If that is really what you want it is easy. You do not need @ChrisW67's "Obtaining the window id of the child xterm may be the hardest part" nor @DerReisende's "QTermWidget". All you need is the couple of lines code shown in the accepted solutuon at Embeding Xterm into Qt5 application in c++, which leverages the
-into
argument toxterm
and should take you a couple of minutes to test. This will "embed" an xterm into aQWidget
window in your application instead of it using its own, external console.However, I am with @ChrisW67 when he writes
Unless I have misunderstood this entire trail of posts over months, your actual requirement is to scan for and display Bluetooth devices. You could not make QBlueTooth work for you, you moved on to running bluetoothctl through QProcess and could not make that work, and now you want to complicate that by trying to control bluetoothctl when it is running inside an independent GUI terminal. Forgive me for thinking that you are actively moving further away from the original problem.
I looked at your post yesterday and that is the thought I came to. If you want to be able to access the output (or input) of
bluetoothctl
program you do not want to interpose any xterm. The embedding above will give you an interactive terminal in a Qt window. You can type there and stuff will output there, but it will not allow you to access the output, that will just appear in that window. Maybe that is what you want, maybe it is not.Basically you can either run your
bluetoothctl
in a terminal and interact with it by typing and looking at its output, or you can run it directly without a terminal and then be able to examine its output in your code. If you want to directly interact withbluetoothctl
's input/output you can do that by running it directly fromQProcess
without any terminal. -
@JonB said in QProcess running "xterm" - how to read / write directly to "xterm":
All you need is the couple of lines code shown in the accepted solutuon at Embeding Xterm into Qt5 application in c++, which leverages the -into argument to xterm and should take you a couple of minutes to test.
Nice pickup. Should work OK as long as all you want to embed is an actual
xterm
and not just an arbitrary X11 terminal. -
@DerReisende I did look into QTermWigfet and its "derivative " qterminal. As far as i can tell they are rather typical "build something on shaky foundation, because it is cool..." - I do tell how I feel and do not care if the public gets offended. For example "qterminal" cannot handle multiple arguments options. Their latest githnub notes are full of "corrected argument passing ..."
-
Thanks for all the comments. I was not aware of -info option - it looks promising.
I would like to stress - I an trying to resolve TWO issues - communicating with "bluetootctl" and embedding any terminal application in QTabWidget.
I have the communication part under control...To embed "terminal" in QTabWidget it has to be widget.
The example referenced does exactly that - creates a widget based dialog - that should work...
What got me going wrong direction - at one point the "window" created by QProcess had a default icons and title of my entire application - that tells me it has to be something compatible with widget or QT object - but I was unable to find what it is and how it fits n my application hierarchy.... so I called it "top floating window ". ( I think QProcess doc may have something about the actual GUI it builds ...)
-
@AnneRanch
Honestly,QProcess
does not build any GUI. It knows nothing about widgets, windows or anything UI. It just runs an external program.You can either embed a visual terminal and then your code cannot interact with a spawned
bluetoothctl
program, or you can send/receive i/o to/from it via stdin/out and no visual terminal, but not both. So long as you keep the embedded terminal and the communicating withbluetoothctl
as separate things that is OK. -
This is embarrassing, but I am stomped - again.
I have solved the embedded issue - with simple dialog etc.I have been using QTABWidget and never had this issue - switching tabs does not stop showing the previous tab
Apparently I am missing a step ....especially when the tab contains a dialog. (Why ?)I found this "slot" on_tabWidget_26_tabCloseRequested(int index) but cannot find anything on how and why to use it .
I really do not want to "close" tab anyway- just switch to another one.switch(index) { case 0: { Form_TERM_Dialog *FTD = new Form_TERM_Dialog(); FTD->show(); break; } case 1: { Form_TERM_Dialog *FTD = new Form_TERM_Dialog(); FTD->show(); break; } case 2: { Form_TERM_Dialog *FTD = new Form_TERM_Dialog(); FTD->show(); break; } }
-
@AnneRanch
QDialog
s --- assuming that is what yourForm_TERM_Dialog
is --- cannot/should not be shown in tabs. From the docs:A dialog window is a top-level window mostly used for short-term tasks and brief communications with the user.
So I don't know what you have meant by "the tab contains a dialog". If you mean the code you show is executed on changing tab, then it creates and shows a quite separate dialog window. Switching to another tab would not in any way close or affect any dialog created from code on switching to a tab previously.
This might be what you mean by "switching tabs does not stop showing the previous tab" --- it won't affect showing a previously opened dialog.
If --- and I don't whether it is --- your goal is to be able to close these previously opened dialogs from code (as opposed to the user clicking its close box) you will need to store your
Form_TERM_Dialog *FTD
somewhere else than in a local variable, so that you can access it at a later time. -
@JonB I hope I can clear or restate what is happening
- My primary user interface is QTabWidget - lets leave the details out of the discussion.
- To add QProcess into the tab - it has to be a widget - hence dialog .
That part works but the link between tab and its dialog is not clear.
That is not why I added the dialog .
It still looks as an "dependent ", but real dialog and top floating
So - the tab code can create / build the dialog BUT it is NOT part of the QTabWidget - since switching tabs DOES not affect that.
It is relatively irrelevant what to call this setup - it does not do the task indeed.
Back to the drawing board....PS I am going back to the "pop-up" dialog - already forgot the name ....
-
@AnneRanch said in QProcess running "xterm" - how to read / write directly to "xterm":
To add QProcess into the tab - it has to be a widget - hence dialog .
A
QTabWidget
acceptsQWidget
s as the "pages". The example I referred you to for an embedded terminal, for instance, uses aQWidget
. AQDialog
is not suitable for a tab widget page, as already pointed out it is designed to be a top-level widget, not a child in a tab widget.From what I can see of the code you showed you are not adding a widget or dialog to the tab widget. You are opening an unrelated, separate dialog each time.
-
Partial success , but still not home free...
I have made a major mistake NOT specificity the "parent " of the test widget.
After correcting that I can see the test label ( from test widget) in proper "page" and I switch the tabs / pages - no problem.I assumed that the QProcess should also use the passed parent.
That does not have expected result - being able to close the page and open another one.
In other words - attaching the QProcess (display) to same parent instantiate the QProcess but cannot be closed /
switched as part of the TAB widget fynction .On top of that - I am having a real difficult time to debug / step thru the code - it seems that GDB does not handle code with "time dependency" well.
If I am on right track establishing "parent" hierarchy (?) I am back to my "floating window " theory - I cannot prove the QProcess "parent " using GDB.
Edit
I have added simple debug messagevoid MainWindow::SubWindow(int index) index 10
parent QWidget(0x561010725df0, name="tab_148")
processTERMINAL->waitForStarted() OK
""
"" -
Some "news" - not sure if good or bad
As far as switching tabs / pages
After adding "page as parent " I can open the new page AND the old one moves into background - way below the main MDI window. ( I am not really sure if it is because the parent addition ... did not observed that before...)
So it is back to "windows " hierarchy - from being on top - it is now "on bottom of the totem pole " .
So - if it can be moved by whatever unknown process - I should be able to delete it ... -
..for time being - I am cheating
I just maximize the main window and do not care how many copies of xtrem are hiding behind it .
TEMPORARY HACKED -
More success...
After adding -info to xterm options the xterm is now actual part of QTabWidget and tabs gets switched properly.
If the first page xterm has +hold option it works fine , however every other page has to have -hold . If +hold is also optioned
the page just flashes...However -the xterm never gets terminated , its GUI just no longer shows... - something to work on
Interestingly and somewhat expected - the QProcess "window / frame " no longer shows either - perhaps another option ??
I would like to express my appreciation to all who helped with this messy task.
After all this I realized I want to have multiple "xterm" - with different options - visible ...
I think "MDI" is next.
Thanks