I need to revise my app concept
-
I need to revise my app concept and I am asking for an advise.
My primary user interface is QTextEdit. I run QProcess and put the result into it. After the QTextEdit is filled I want the user to interact with it. I am using "textChanged" to move the cursor to the correct position for user to add more text.
I can click on correct position and start adding... the "problem" is the entire QTextEdit gets rebuild. That is really not a big deal , but ... When I move the cursor to correct position in code - the QTextEdit looses focus. I tried to regain the focus , but any add - in code - puts the "textChanged" into an infinite loop. I was thinking adding some static flags , but that is pretty hack-ish...
Basically - I need to come up with a replacement of "textChanged" . Any suggestions would be appreciated.
PS if you do not get what I am trying to do , I am sorry but I have no idea how to be more clearer with my descriptions, so just skip this post. -
It looks as if the application is trapped in the slot that updates the
QTextEdit
content, when thetextChanged
signal has been fired: That signal reacts to user-edits as well as programmatic changes. Updating the text from within the slot fires the signal again and enters an infinite loop.
SinceQTextEdit
doesn't have atextEdited
signal (like e.g.QLineEdit
), the signal has to be muted before applying programmatic changes. The easiest way to accomplish that is adding a signal blocker at the beginning of the slot and any other method in the code that modifies the text edit content. In short, it blocks the text edit's signals within current scope and restores the previous signal state when it goes out of scope.Not sure if I fully understood why the text edit gets rebuilt all the time, but I would hazard a guess that a signal blocker fixes that as well.
-
@Axel-Spoerl Thanks. That is in essence the problem. I have used a static flag to act as "signal blocker" - it sort of works but "one way " - I can block selected code in subsequent calls to "textChanged" but cannot unblock it . So it I would need to use a "global flag" for that... I'll give a QSignalBlocker a try. I actually found that I need more than just blocking the text updating...
Tracking the events in "event driven system" is not easy - I am really looking for some kind of "flow chart" tool..... -
Addendum
I am still not sure how to use QSignalBlocker . But I was getting the focus back wrong and that is now solved.
And since this thread has some audience , I appreciate that , I like to post / continue with more issues.
The 'textChanged" has another task - add to the already posted text FROM QInputDialog. That is working, the problem is with the initial "setText" . It does some regular expressions and it is taking time... Ideally I should post an event / SIGNAL AFTER the initial processing is done - when the actual new cursor is in correct position.(BTW - the initial QProcess is "open ended" only 'readyRead" SINGNAL is posted , there is no "finished" to monitor. )
I have never done that and not sure if it is a correct way to solve this timing problem - adding another "timing dependency".
Just for illustration - I am posting the current UNDER CONSTRUCTION part of the code where the timing issue is...
(And I am sorry for taking so much space , sorry )
QString Current_Text = ui->textEdit_112->toPlainText(); qDebug()<< "Temporary Current Text str text " << Current_Text; str= SubRegularExpressionExt("(#)\\W*$", Current_Text,2 ); //TOK line str = str.trimmed(); str= SubRegularExpressionExt("(\\w+)\\W*$", Current_Text,2 ); qDebug()<< "Last word add text " << str; QString LastWord = str; QTextCursor newCursor = ui->textEdit_112->textCursor(); //newCursor.movePosition(QTextCurso MainCodeBlockr::Right); ui->textEdit_112->setTextCursor(newCursor); ui->textEdit_112->setCursorWidth(10); ui->textEdit_112->setFocus(); // flashes on first @position 0,0 #ifdef TASK // NOTE using common str , mabye a bad idea TASKstr = " TASK DONE moving cursor after last word"; qDebug()<< str; // " TASK analyze text chaaged on_textEdit_112_textChanged() "; qDebug()<< "Function " << Q_FUNC_INFO; qDebug()<< "@ line " <<QString::number(__LINE__); ui->textEdit_113->append(str); // " TASK setup command QProcess for bluetoothctl tab "); ui->textEdit_113->append(Q_FUNC_INFO); ui->textEdit_113->append(QString::number(__LINE__)); // scroll down ui->textEdit_113->append("scroll down"); ui->textEdit_113->verticalScrollBar()->setValue( ui->textEdit_113->verticalScrollBar()->maximum()); //ui->textEdit_113->s // no go ui->textEdit_113->moveCursor(QTextCursor::EndOfBlock); #endif
THIS IS WHERE QInputDialog process should take over
{ // QInputDialog code block #ifdef TASK TASKstr = " TASK Process QInputDialog code block "; qDebug()<< TASKstr; // " TASK analyze text chaaged on_textEdit_112_textChanged() "; qDebug()<< "Function " << Q_FUNC_INFO; qDebug()<< "@ line " <<QString::number(__LINE__); ui->textEdit_113->append(TASKstr); // " TASK setup command QProcess for bluetoothctl tab "); ui->textEdit_113->append(Q_FUNC_INFO); ui->textEdit_113->append(QString::number(__LINE__)); // scroll down ui->textEdit_113->append("scroll down"); ui->textEdit_113->verticalScrollBar()->setValue( ui->textEdit_113->verticalScrollBar()->maximum()); //ui->textEdit_113->s // no go ui->textEdit_113->moveCursor(QTextCursor::EndOfBlock); #endif
-
SOLUTION?
I have opted for KISS method. - to enable the QInputDialog to function.
Since the QProcess is done and the objective is to move the cursor to the last word received from it ...
When both of these are true - I stop the QProcess and block the "textChanged" from updating - using simple global flag .
I can modify this flag to "switch" when another QProcess is going to run to finish the interactive entry added by QInputDialog ...
There are some limits (valid entries) to repeating this new QProcess.... so a simple "loop" will do.
I am still looking into QSignalBlocker , but it looks as it will not be as flexible as I need it to be.
I do appreciate all the help and commentaries received. It does help to "bounce off" the ideas , no RTFM can provide.
Cheers