How to read/write a text file in qt? - qt

I have a QPlainTextEdit in my Form and I want to read the whole Resource.txt document which is placed in Other Files of my project and after a timer ticks i want the application save the contents of the QPlainTextEdit in the document.
I know it's a dumb question but I can't find a solution.

QTextStream.readAll() lets you read a file to a QString. This constructor (or the method setPlainText) for QPlainTextEdit lets you set a string displayed in the editor. Use a QTimer to trigger a slot which reads the contents of the QPlainTextEdit into a QString with the toPlainText method after a desired amount of time. Write the result to file using a QTextStream again.

The tutorial Getting Started Programming with Qt takes you through building a text editor, once you have followed this, try adding a QTimer to trigger a save.

Related

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

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}

QTextEdit or QTextBrowser performance issue

I have a heavy QString.
I need to display it as an output.
I tried both QTextEdit or QTextBrowser. And all methods of setting text like setText, append, setPlainText.....The performance is really poor. The most annoying things is that setting thing on user interface meaning blocking the main thread. So the program will become unresponsive during the process.
Is there any better way to display visual text result?
At least if the document is rich text, every time you append to the document, it is apparently reparsed.
This is A LOT more performant: If you want each append to actually show quickly & separately (instead of waiting until they've all been appended before they are shown), you need to access the internal QTextDocument:
void fastAppend(QString message,QTextEdit *editWidget)
{
const bool atBottom = editWidget->verticalScrollBar()->value() == editWidget->verticalScrollBar()->maximum();
QTextDocument* doc = editWidget->document();
QTextCursor cursor(doc);
cursor.movePosition(QTextCursor::End);
cursor.beginEditBlock();
cursor.insertBlock();
cursor.insertHtml(message);
cursor.endEditBlock();
//scroll scrollarea to bottom if it was at bottom when we started
//(we don't want to force scrolling to bottom if user is looking at a
//higher position)
if (atBottom) {
scrollLogToBottom(editWidget);
}
}
void scrollLogToBottom(QTextEdit *editWidget)
{
QScrollBar* bar = editWidget->verticalScrollBar();
bar->setValue(bar->maximum());
}
The scrolling to bottom is optional, but in logging use it's a reasonable default for UI behaviour.
This actually seems a kind of trap in Qt. I would know why there isn't a fastAppend method directly in QTextEdit? Or are there caveats to this solution?
(My company actually paid KDAB for this advice, but this seems so silly that I thought this should be more common knowledge.)
Original answer here.
Just got the same problem, and the resolution is very simple! Instead of creating a document + adding it immediately to the QTextBrowser/QTextEdit and then use cursor/set text to modify it, just postpone setting the document to the widget till AFTER you set the text / formatting... a complete life changer :)
The best way would be to load text partially as background operation with thread that periodically emit signal to redraw GUI, or better: just use QTimer.
Load first N lines, and then start QTimer that'll read more lines and append text inside widget. After reaching eof just kill that timer.
I believe that example can be helpful.

qt malloc(): smallbin double linked list corrupted

In my Qt widget I sometimes get this error:
malloc(): smallbin double linked list corrupted
It does not happen all the time but I think I have narrowed it down to when it starts.
I have a QGraphicsView and QGraphicsScene and there I'm drawing lines whos points are stored in a vector. Reason for this is I need to pass this points to another library. Once I draw the points I have an option if I click on a line I'm prompted to another window where I can change the coordinates of a line.
ResizeDialog *dialog = new ResizeDialog(this);
dialog->exec();
delete dialog;
The above code is the code I use to open a new QDialog. I know if I use this->close() the
qt malloc(): smallbin double linked list corrupted does not appear but then I lose the instance of QGraphicsView. Reason I need to keep the QGraphicsView window open if I need to chose to add further lines.
Any advice on how I can eliminate this issue wold be helpful.
Rather than using delete dialog;, use dialog->deleteLater();. I assume the small code portion is inside a slot of the object referenced by "this", and direct deletion is source of trouble as ResizeDialog *dialog = new ResizeDialog(this); affect the parent object this.

QFileDialog used as widget

My goal is: user can choose file (only *mp3) and after clicking twice on it it should play (so the QString to file should be send to play() function)
Firstly I started to work with QTreeView, but it has signal when the file is selected.
So I decided to create QFileDialog and used it as widget built-in into MainWindow.
The only problem that I have, that after double-click it disappears. It is possible to avoid it?
Should I work with some QDialog::finished() signal or, QDialog::done()?
First, you can get a double-click signal from QTreeView; it's:
void doubleClicked( const QModelIndex & index );
Second, if you really want to use the QFileDialog that way, first override closeEvent( QCloseEvent * event). Inside, if you want to close the dialog, do event->accept();, otherwise just do event->ignore();. Connect to QFileDialog::currentChanged( const QString & path ); to get the filename the user double-clicks. One last thing--be sure to create the QFileDialog on the heap (using new), not on the stack (a local), and call show() on it instead of exec().
Remember that you can supply it with a parent (this) and you won't need to delete it later.
connect(file_dialog, SIGNAL(finished(int)), file_dialog, SLOT(open()));
This seems to work fine. The geometry stays fixed and it remembers the last path allright..

How to control the position of QDialog?

Is there any easy way to open the Qt dialogs in the same position as they were the last time the application was open ?
i.e. preserve position of dialogs between application sessions ?
By easy way I mean not to have manually write the window position in file, and then read :)
You can use the QSettings class to achieve this. It's an abstraction class that allow your applications to store its settings in order to retrieve them at next launch.
Save settings:
QSettings settings("ValueName", "Value");
Read settings:
QString v = settings.value("ValueName");
Use QSettings along with QWidget::restoreGeometry() and QWidget::saveGeometry().
Better to save dialog->pos(), dialog->size(), dialog->isMaximized(), cause dialog->saveGeometry() doesn't maximize the window.
QSettings is the preffered way to save configuration

Resources