How to automatically update a QLineEdit with the value of another variable - qt

I've got an std::string object called str;
I've also got an QLineEdit object called line_edit.
I need that str reflects whatever the user writes in line_edit, this I know how to do trough signals and slots.
But I also need that whenever str changes , QLineEdit automatically displays the new contents of str.
How can I do this?
Is it MVC what I need? I've been reading about it but I can't get it yet.
Also, examples I've read try to keep mutually updated subobjects of QWidget
which makes me think there is some magic happening in there.
How can I achieve that reactivity?

First of all it might be easier to use QString instead of std::string.
You can call line_edit->setText(str); to update line_edit from your code.
You can use the signal QLineEdit::textChanged to modify the content of str when writing to the QLineEdit.
There are multiple ways of handling signals, one way would be to use QObject::connect
It might look like this: QObject::connect(line_edit, &QLineEdit::textChanged, this, &YourClassName::setText);
And then you create setText(){ str = line_edit->text}

Related

How to pass a QTextEdit to signal/slot mechanism

I have read some topics here about signals and slots and its parameters but found nothing about following problem:
I am working with Qt 5.7
I simply have 2 classes, inside 1st, I want to emit signal with string message and location(or specific object) where to display it.
Now it is like this: I have 1st class where I emit signal :
emit signalWriteToTextEdit("hallo","textEdit_3");
What I want to do is somehow pass as the second argument an object like textEdit. No QString as its now.
Inside 2nd class is the slot:
void writeToTextEdit(QString info, QString where){
where.append(info); //I would like to do something like this
}
Just dont know how to consider that second parameter "where" as accessible object for example textEdit, so I could change its content.
I am thinking also if this is possible:
Is there some method for Ui object like finding elements by name?
Is it possible to go with foreach over all elements in ui and check their names...? I tried but dont know how to go through that.
If its not clear, I will explain more
After a little digging, I came across the QObject::findChild function. This will allow a string lookup recursively through the UI, those I am unsure of performance.
Edit for more detail:
Returns the child of this object that can be cast into type T and that is called name, or 0 if there is no such object. Omitting the name argument causes all object names to be matched. The search is performed recursively.
If there is more than one child matching the search, the most direct
ancestor is returned. If there are several direct ancestors, it is
undefined which one will be returned. In that case, findChildren()
should be used.
Just use QWidget* or QObject* (if it is not always a widget) as the argument type
signals:
void writeToTextEdit(const QString &what, QWidget *where)
or if it is always a QTextEdit even more specifically
signals:
void writeToTextEdit(const QString &what, QTextEdit *where)
Though it is not clear why the code needs to emit a signal if it has access to the target object, it could simply call setText directly

Qt - signal for when QListWidget row is edited?

I am working in Qt4.7, and I have a QListWidget in my dialog. I have a QString that needs to match the current text in the row of this widget (the individual rows are editable). Looking at the signals associated with QListWidget, there seem to be signals for when a different index is selected but none for when the text of a the currently selected row changes. I thought currentTextChanged(QString) would do it, but it didn't. I also thought to try to connect each individual row to something, but QListWidgetItem doesn't have any built-in signals. Does anyone know of a way to do this? Thanks!
At first it seems like QListWidget::itemChanged is the way to go, but soon you run into a problem: the signal is sent for everything - inserts, changing colors, checking boxes, and anything else that "changes" the item! Predelnik pointed that out in his answer. Some people have tried to put in flags and filter everywhere by intercepting various signals to find out if editing was the actual event. It gets very messy.
There is also QAbstractItemModel::dataChanged , which would seem like a good solution. It even has a parameter "const QVector& lstRoles" so you could scan for Qt::EditRole and see if it was really edited. Alas, there's a catch - it gets called for everything just like QListWidget::itemChanged and unfortunately, for QListWidget anyway, the roles parameter is always empty when it's called (I tried it). So much for that idea...
Fortunately, there's still hope... This solution does the trick! :
http://falsinsoft.blogspot.com/2013/11/qlistwidget-and-item-edit-event.html
He uses QAbstractItemDelegate::closeEditor, but I prefer using QAbstractItemDelegate::commitData.
So make a connect like so...
connect(ui.pLstItems->itemDelegate(), &QAbstractItemDelegate::commitData, this, &MyWidget::OnLstItemsCommitData);
Then implement the slot like this...
void MyWidget::OnLstItemsCommitData(QWidget* pLineEdit)
{
QString strNewText = reinterpret_cast<QLineEdit*>(pLineEdit)->text();
int nRow = ui.pLstItems->currentRow();
// do whatever you need here....
}
Now you have a slot that gets called only when the list item's text has been edited!
I guess you need to look into the following signal:
void QListWidget::itemChanged(QListWidgetItem * item)
But be careful because it's being sent every time some property of item changed, not only text. I remember when we ran into the problem once when we changed item colors and got tons of false positive slots called because of that. If you need more fine tuning I guess it's better to write model/view classes yourself and not rely on QListWidget.

QScintilla get the QStringlist from autocompletion

I am currently using QScintilla to develop my own code editor.
QScintilla provide autocompletion and calltips feature already. What I want is to get rid of the autocompletion popup widget , retrieve the list it gets, parse and display them with my own widget.
So here is what I've got:
//disable the autocompletion feature:
QsciScintilla::setAutoCompletionSource( QsciScintilla::AcsNone);
//use this function call to get the list from api class:
void updateAutoCompletionList (const QStringList &context, QStringList &list)
The problem is ,the updateAutoCompletionList only give me the result from QsciScintilla::AcsAPIs, I have no way to get the result from QsciScintilla::AcsDocument.
Is there any way I could get result from QsciScintilla::AcsDocument?
thanks beforehand.
I've solved it myself.
No available API for me to do so, so I read the source code of QsciScintilla class, which has a method called "startAutoCompletion", you can get the answer from that.
Actually it does search all text, collects the words that match the autocompletion context,avoids duplicates. Not that fancy as I throught, but actually the performance is not as slow as I throught either :)

Passing a class through a signal/slot setup in Qt

I'm trying to get the information of several of a class' member variables on the receiving end of a slot/signal setup, so I'd like to pass the entire class through. Unfortunately, after the class has been passed, the member variables seem to be empty. Here's some code snippets:
This sets up the signal to pass the class
signals:
void selected(const ControlIcon *controlIcon);
this is the slot/signal connection
connect(controllerList->serialController, SIGNAL(selected(const ControlIcon*)),
infoView, SLOT(serialControllerSelected(const ControlIcon*)));
I emit the signal from within the class to be passed
emit selected(this);
Here's the code to call on the class' member data
QLabel *ASCIIStringHolder = new QLabel;
ASCIIStringHolder->setText(controlIcon->m_ASCIIString);
Nothing shows up in the label, and when I set a breakpoint, I can see that there's nothing inside m_ASCIIString.
I looked to make sure that it was being assigned some text in the first place, and that's not the problem. I also tried the signal/slot setup with and without const.
Any help would be appreciated.
Qt signal/slot mechanism needs metainformation about your custom types, to be able to send them in emitted signals.
To achieve that, register your type with qRegisterMetaType<MyDataType>("MyDataType");
Consult official QMetaType documentation for more information about this.
First, since you are using an auto connection, do both sender and receiver live in the same thread? If not, it could happen that the call is queued and when it arrives, the data in the sender was already modified. You could try to use a direct connection just to make sure this isn't the problem.
Second, just for the fun of it, did you try to access the sender by using qobject_cast<ControlIcon*>(sender()) within the slot? This is how it is usually done if the signal doesn't pass this as an argument. Like this:
QLabel *ASCIIStringHolder = new QLabel;
// this is instead of the argument to the slot:
ControlIcon *controlIcon = qobject_cast<ControlIcon*>(sender());
ASCIIStringHolder->setText(controlIcon->m_ASCIIString);
The signal can't be declared to be passing a class and then actually pass the child of that class. I changed the signal, slot, and connect() to be SerialController (the child of ControllerIcon), and everything worked fine.

Single function that handle multiple QObjects

Hi I have a problem, in my program I have several QLabel and QTextbrowser, at times, I want each of them to display something, but I want to do this through another function called NewMessage. So NewMessage will receive message from QLabel or QTextbrowser, and process them, then display it. But the problem is I don't want to have overloading function for QLabel and QTextBrowser, I want only 1 NewMessage function that can handle message pass in by either QLabel or QTextBrowser(the objects have to pass themselves in as well), how should I do that? Does it has to do with something called casting? Thank you !
I'm not sure I fully understand what you want to achieve. May be you could start by reading Qt documentation about QObject and qobject_cast :
http://doc.qt.io/qt-5/qobject.html#qobject_cast

Resources