Another xterm /QTextEdit issues
-
Here is a debug output of the code .
It shows where xterm output (winId 12582986)
it verifies that subwindow actually detected SINAL 'textChanged - run CCC_MdiChild::TextChanged()
and sort of closed the task by test running bool CCC_MdiChild::maybeSave()If there are activities in the current sub window - highlight a word or character -
click /double click I expect "selecctionChanged " SIGNAL and have "connect" setup for it.
It never comes.I think this is related not able to actually link to current subwindow to retrieve text - cannot get text if I cannot
generate ' selectionChangged' SIGNAL...params ("-T", "bluetoothctl no options (interactive) case 1 -hold file ", "-fa", "Monospace", "-fs", "14", "-hold", "-into", "12582986", "-geometry", "200x200+1000+1000", "-e", "bluetoothctl | tee /tmp/temp.txt")
QProcess::start: Process is already running
processTERMINAL->waitForStarted() OK
""
""
TRACE_MDI_XTERM int CCC_MdiChild::TextChanged()
TRACE_MDI_XTERM @line "128"
TRACE_MDI_XTERM bool CCC_MdiChild::maybeSave()
TRACE_MDI_XTERM @line "433"ADDENDUM
This maybe a clue to figure out "who is on first " - the xterm has "geometry" option - it may be set wrong, but the resulting widow does not reflect those dimensions set in "geometry " the default size setting is so far unknown.
So it this window true MDI subwindow or something else?
It can be move / resized / delete etc - as a subwindow should.ONE MORE ADDENDUM - I am hoping it will help finding the solution
I can highlight the selected text using mouse - so some events SIGNALs are generated.
I can move the mouse into the subwindow and the cursor gets highlighted - cannot be "screen shot " ,SECOND ADDENDUM
This indicates that the actuall size of the subwindow is "causing" the problem.
Both displays are results of same xterm parameters / options .
The actual results are different AFTER the first xterm is processed - that is normal....
The display in TAB MDI are in "frame", the display in MDI is in QTextEdit subwindow - that are the differences.I cannot find where is the default size of the subwindow set.... nor how to set if when xterm QProcess is executed.
Maybe I really need to add "form" to QTextEdit - could somebody help me to do that ? ( Request posted in another thread ...
so far no answer ...) -
@AnneRanch said in Another xterm /QTextEdit issues:
it verifies that subwindow actually detected SINAL 'textChanged - run CCC_MdiChild::TextChanged()
Since
QMdiSubWindow
does not have atextChanged
signal, I presume you are still working with your case where you specify aQTextEdit
(orQPlainTextEdit
) for an MDI child widget.I said to you in https://forum.qt.io/topic/139328/more-xterm-in-mdi-example-challenge/2
so long as you use
xterm -into
you will not be able to access its output programatically from your code, it will be sent to the widget directly from thexterm
.But you replied:
Secondly - as you said - he command output goes to QTextEdit object , hence it should not be that hard to work on.
I am afraid that is not the case, you will not be able to "work on" any of the command output (or input) via
QTextEdit
. The text you see in the terminal window is not sent there as "text" known to Qt, rather the xterm is writing it directly to a native window. You might as well make your widget aQWidget
instead of aQTextEdit
, it will behave the same.You will find you do not get any
textChanged
signal (or any other signal) as text appears in the xterm, and most importantlyQTextEdit::toPlainText()
(or any other method trying to access the "text" in theQTextEdit
or any otherQWidget
) will always deliver""
, i.e. no text. (For unknown reasons, you/I get a couple of spurioustextChanged
signals when theQTextEdit
is very fist shown, which may relate to yourCCC_MdiChild::TextChanged()
mention. However, even inside these the text reported is empty, and no more signals are received once the window has been shown.)Similarly, you will not receive
selectionChanged()
signals, nor can you can access any text which might be selected in the xterm window, and so on.What is going inside the xterm window is "opaque" to Qt. The xterm is writing/reading directly to an X11 native window. No text, or selections, are visible to Qt. Qt has a
QWindow
"wrapper" around this native window to allow it to work inside aQWidget
, but that is the limit of Qt's interaction. And btw the fact that you are using an MDI sub window is not relevant/does not affect the behaviour.the xterm has "geometry" option - it may be set wrong, but the resulting widow does not reflect those dimensions set in "geometry " the default size setting is so far unknown.
For this item. The default size of a
QTextEdit
is 256x192 pixels. This is shown in your non-tab-widgetdocument0.txt
windows. In your tab-widget it is the same size as the other tab widget pages. The fact that you have asked the xterm to be whatever-geometry
width and height (your200x200
asking for 200 rows and 200 columns) does not propagate through to the size of theQTextEdit
. You would have to calculate the pixel size corresponding to the desired-geometry
yourself and explicitlyQTextEdit::resize()
to try to make them the same size. -
@JonB I was going to update my original post, but since your reply is pretty close what I am guessing, I will ad it here .
Here is what I think is happening with MDI Area and its subwindows.
These subwindows are QTextEdit - no ui form is coded .
The xterm is directing the output of the command ( bluetootctl) to SOME window specified as 'winID" and it has no relation to QTexrEdit window.That is why I get only "textChanged " SIGNAL - which is misleading - there is no real "text changed" when the QTextEdit window is initially created...
To make the story short
- what is this "winID" for real ? I believe you call it "Native window"
2**. it obviously exists so why I cannot attach it to Qt widget ?**
- It ( CORRECT SIZING ) works in TAB because TAB "window" has "form" with "frame"....
apparently "winId" is linked to this form / frame somehow - but I have not try to "extract text "
from TAB, so it may be same story. - If I subclass the QTextEdit - add form - will it work ? ( I am coding that right now...)
PS I need to digest your post - after I mow the lawn..... later
-
@AnneRanch said in Another xterm /QTextEdit issues:
The xterm is directing the output of the command ( bluetootctl) to SOME window specified as 'winID" and it has no relation to QTexrEdit window.
Yes.
That is why I get only "textChanged " SIGNAL - which is misleading - there is no real "text changed" when the QTextEdit window is initially created...
Seems to happen to me 4(?) times during very initial creation. Dunno why, it's spurious, just ignore them. Never get a
textChanged
once it's up and running.what is this "winID" for real ?
You create a
QWidget
of some kind in Qt, that causes the system (X11) to create a window. That has an associated native "window id" (from X11), which is how X11/windowing system (not Qt) refers to it.QWidget::winId()
gets that system window id. Runningxterm -into winId()
ask xterm to run, but instead of creating its own window as it normally would you are telling it "I have already created a window with this id for you, please use that instead of creating your own".QWidget::winId()
returns the window id of the X11 window which is already attached to whateverQWidget
you call it from (e.g. yourQTextEdit
).I don't know what you mean by "form" in "If I subclass the QTextEdit - add form - will it work ?", but no matter what you do --- even standing on your head --- will not alter the fact that the xterm is writing directly into your widget and you won't get text, selections etc., it will just be a "blackbox" that works. Which is fine if that is all you want.
So long as you run your
bluetoothctl
program viaxterm
you won't be able to "see" (from your Qt program) its input or output. The xterm will internally handle all the input/output for thebluetoothctl
. It will work, but you cannot "monitor" or "interact" with what is going on.If you really want to be able to "control" the
bluetoothctl
program --- provide it with input, look at its output etc. --- you must run it (fromQProcess
) without that xterm. You can hand it input (e.g. from aQLineEdit
the user types into) and display its output (e.g. append to aQTextEdit
) while also "examining" or "driving" it in code, and also not worry about the "geometry", but not if running in an xterm. -
If you really want to be able to "control" the bluetoothctl program --- provide it with input, look at its output etc. --- you must run it (from QProcess) without that xterm. You can hand it input (e.g. from a QLineEdit the user types into) and display its output (e.g. append to a QTextEdit) while also "examining" or "driving" it in code, and also not worry about the "geometry", but not if running in an xterm.
I need to go back few weeks to figure out why I actually wanted to use any terminal...
OK, if i remove -into option I get this "native xterm window "
The $64 question - how to identify it to Qt app can access it ?
It physically exist...
it looks as main window , has a title etc etc -
@AnneRanch Allow me to continue
Here is what happens when I run
processTERMINAL->start("bluetoothctl ", params);
no params and QProcess exec parameter is "bluetoothctl" not "gnome-terminal" .
It opens a window and runs Linux "terminal"
is that a product of what ?
QProcess ?or another "native window" ?
where does the title of this "window" come from?
the app running is terminal AKA gnome-terminal
how ?processTERMINAL->start("bluetoothctl ", params);
-
@AnneRanch here is the result with
params << "-e" << "bluetoothctl | tee /tmp/temp.txt"; processTERMINAL->start("xterm", params);
Note the title of "native window " is the optional tee file name ....
How is it getting there ?I can enter text to the "native window" and I did enter "help" .
The result is full size output...There got to be a way to send this "native window' to Qt "as is "...
Now I recall ONE of the reasons to use xterm - the bluetoothctl outputs control characters and it is a pain to remove them
IF my objective is to take an word from one style of bluetoothctl output and insert it to another - without having to deal with control characters - then direct access to xterm (native window) is necessary.
-
@AnneRanch
This seems to be such complicated issue - everybody is looking for single system questionand cannot look at the whole task...
So for all Qt affectations, who wants only Qt question
if I move mouse from MDIArea to QTextEdit subwindowAND THE CURRENTLY STEADY CURSOR STARTS BLINKING
what event SIGNAL of QT , which object / class , triggered it ?
SECOND QT question
if I highlight text in QTextEdit (sub)windowwhat event , SIGNAL did that or was triggered by doing that ??
(hint NOT "selectionChanged " SIGNAL of QTextEdit ) -
@AnneRanch said in Another xterm /QTextEdit issues:
processTERMINAL->start("bluetoothctl ", params);
It opens a window and runs Linux "terminal"
is that a product of what ?
QProcess ?
It does not open any "terminal", or any other window, for me. You should look carefully through your code for something else you are doing which might open a terminal/window.
QProcess
itself does not open any "windows" or "terminals".Your
program
argument toprocessTERMINAL->start()
is incorrect. You have specified"bluetoothctl "
, that has a trailing space character and there is no such command/executable. If you checked for errors correctly you would find that no process is being run for this. You must specify"bluetoothctl"
, exactly that.params << "-e" << "bluetoothctl | tee /tmp/temp.txt";
Note the title of "native window " is the optional tee file name ....
How is it getting there ?When
xterm
is invoked with this-e "..."
, and no-T
is specified, it isxterm
which decides to take thattemp.txt
from the end of the command line and use it for the window's title.Now I recall ONE of the reasons to use xterm - the bluetoothctl outputs control characters and it is a pain to remove them
The following regular expression should remove all the "ANSI escape sequences" from the output of
bluetoothctl
:QString output = whateverOutputFromBluetoothctl(); output.remove(QRegularExpression("\\033\\[[^@-~]*[@-~]"));
However note there are still other things to deal with, such as it outputting
\r
to move back to beginning of line, and sequences which erase existing characters from the terminal. It will not be perfect. The sources ofbluetoothctl
show that it insists on outputting these control sequences (including when run as a sub-process without a terminal like from your Qt app), even if it is not outputting to a terminal which understands them, and cannot be switched off.Using the above, here is a sample session sending commands to
bluetoothctl
and displaying its output in aQTextEdit
. It is for illustration of the approach and the removal of output ANSI control sequences. You would want some more/different code for your actual goal of maintaining an interactive session.#include <QProcess> #include <QRegularExpression> #include <unistd.h> // only for `sleep()` below #include "widget.h" Widget::Widget(QWidget *parent) : QTextEdit(parent) { this->resize(800, 400); this->setAcceptRichText(false); QProcess process; process.setReadChannelMode(QProcess::MergedChannels); process.start("bluetoothctl", QStringList()); process.waitForStarted(); sleep(2); // "naughty" in Qt, don't use, but allows time for `bluetoothctl` to generate its start-up "Agent registered" message process.write("version\n"); process.write("show\n"); process.write("exit\n"); process.waitForFinished(); QString output = process.readAllStandardOutput(); output.remove(QRegularExpression("\\033\\[[^@-~]*[@-~]")); this->append(output); }
And the output looks like (I don't have any Bluetooth devices!):
-
Just to continue this thread , and I am not sure if this is the one I want to continue .
- I have mentioned few times - I DO NOT want / need TO use regular expression to "convert " the "terminal"
output to humanly readable format. - I want "cut and paste" selected text from one MDI subwindow to another - I do not need to extract the text at all , but I know how to do it and have done it. .
I can highlight the wanted (subwindow) text - hence the QT is doing something - but I do not know what is QT doing - I need somebody to help me to identify the QT action.
What event is triggered?
**PLEASE - If your know the answer post it... other contributions are superfluous at this point **
- I have mentioned few times - I DO NOT want / need TO use regular expression to "convert " the "terminal"
-
@AnneRanch said in Another xterm /QTextEdit issues:
I can highlight the wanted (subwindow) text - hence the QT is doing something - but I do not know what is QT doing - I need somebody to help me to identify the QT action.
What event is triggered?
**PLEASE - If your know the answer post it...
As I have said several times, Qt is not "doing something", there is no Qt action. No Qt event or signal is triggered. You keep asserting "there must be", but there is not. Don't know how to say it more clearly than that.
All events --- key presses, mouse drags, selections --- in the xterm are handled by the xterm. Just like if you open an xterm totally outside of your Qt application, so Qt is not involved, it still behaves exactly the same.
You can copy and paste between the xterm and any other desktop window, including your Qt application and its MDI windows, via the usual windowing system clipboard functions, like Ctrl+C & Ctl+V, or right-clicking on selected text/in the xterm window. You cannot interrogate the xterm window, to discover e.g. that a selection has been made or what is selected, from your Qt application. Even though I know you would like to be able to do that.
If you want to use the xterm:
- Your user will need to go into the xterm window and drag to select. (Your Qt application does not know this has happened.)
- Your user will need to copy that text to clipboard, whichever way xterm allows you to do that. (Your Qt application does not know this has happened.)
- Your user will need to click in your destination MDI window and either Ctrl+V to paste or you can provide a button/menu option for user to click whose action is paste from clipboard.