PDA

View Full Version : QTextEdit textChanged() signal occurs way too frequently



dsab123
18th June 2012, 22:04
Not sure why, but the QTextEdit textChanged() signal seems to be happening infinitely many times for me..is there some caveat to using this signal I didn't see in the docs somewhere?

Basically I'm just trying to implement a poor man's terminal. It works, but the printf's I've thrown in along the way get printed many many times..the way I want to implement the terminal is like this: when text is changed in the terminal, it signals the textChanged signal, which is connected to the getCommand slot. getCommand sends the command to the serialComms method, which does some processing, then emits the serial signal with the processed output string as its parameter. finally, the output string is printed on the terminal. I'm pretty sure I went overboard on the signal generation, but this should still work, according to my research on QTextEdit

my code is very messy and spread out across many files, so sorry if there's any confusion.

ctor of the class that holds the 'terminal':


terminal = new QTextEdit();
terminal -> setText(">>");
terminal -> setReadOnly(FALSE);

connect(terminal, SIGNAL(textChanged()), this, SLOT(getCommand()));


method for getting command from QTextEdit:


void advancedTab::getCommand() {
QString text = terminal -> toPlainText();
QByteArray ba = text.toLocal8Bit();
char *message = ba.data();


printf("emitting signal inputComm.\n");

emit inputComm(message);
}


method for printing out command on 'terminal':


void advancedTab::outputComm ( char* rawMessage) {
QString output = QString(rawMessage);

terminal -> setPlainText(rawMessage);
printf("MESSAGE GOTTEN!\n");
}


method for processing command:


QString serialComms(char *stringy) {
//processing stuff
}


main method:


//ops is an instance of some other class, in which the serialComms method lies
//advanced is an instance of the class that houses the terminal

QObject::connect (&ops, SIGNAL(serial(char*)), advanced, SLOT(outputComm(char*)));
QObject::connect(advanced, SIGNAL(inputComm(char*)), &ops, SLOT(serialComms(char *)));


note: this happened before to me, when I was just trying out a simple example with QTextEdit. This is why I think I may be missing some obvious detail about textChanged().
Also, when commands are typed into the terminal carefully and no key is pressed forever, which would (I think) call the signal too many times.

wysota
18th June 2012, 22:23
When does serial() get emitted?

dsab123
18th June 2012, 23:02
wysota, you sure are quick, and you're pretty awesome for that.

I think I've isolated the problem enough where it's not a problem with QTextEdit; i replaced the body of getCommands with a simple printf and it only printed out when I ty.

To answer your question, serial should be emitted at the end of serialComms, my mistake for leaving that out. serialComms should really look like:


QString serialComms(char *stringy) {
//processing stuff
emit serial (someString);
}


Added after 14 minutes:

well, I figured out the error.

I was putting text back to into the terminal in outputComm, which would signal the textCHanged() signal all over again, thus beginning a neverending cycle..good job me.

Added after 19 minutes:

Ok, now I've run into some trouble.

How can I add text to the QTextEdit without signaling the textChanged() signal?

ChrisW67
18th June 2012, 23:35
How can I add text to the QTextEdit without signaling the textChanged() signal?
You can't... that would defeat the purpose of the signal. Unfortunately QTextEdit does not seem to have an equivalent of the QLineEdit::textEdited() signal.

You can chose to ignore the signal with a simple boolean lock flag. Set it true before you write to the edit box from the code, write the data, and set it false. In the slot immediately return if the flag is true.

You could try QObject::blockSignals() on the edit box unless other objects are depending on the edit's signals.

dsab123
19th June 2012, 00:25
I think what I'll most likely end up doing is using QKeyEvent to react to the return key, and go from there.

Thanks guys!