I have a problem: my project is a very simple one with a QTextEdit and a QSyntaxHighlighter, I'm trying to load a .cpp file and highlighting just the eighth line of that file, but the QTextEdit can't load the entire file if I ask it to highlight the line.
The following image shows the problem:
The relevant code of the application is the following:
void MainWindow::openFile(const QString &path)
{
QString fileName = path;
if (fileName.isNull())
fileName = QFileDialog::getOpenFileName(this,
tr("Open File"), "", "C++ Files (*.cpp *.h)");
if (!fileName.isEmpty()) {
QFile file(fileName);
if (file.open(QFile::ReadOnly | QFile::Text))
editor->setPlainText(file.readAll());
QVector<quint32> test;
test.append(8); // I want the eighth line to be highlighted
editor->highlightLines(test);
}
}
and
#include "texteditwidget.h"
TextEditWidget::TextEditWidget(QWidget *parent) :
QTextEdit(parent)
{
setAcceptRichText(false);
setLineWrapMode(QTextEdit::NoWrap);
}
// Called to highlight lines of code
void TextEditWidget::highlightLines(QVector<quint32> linesNumbers)
{
// Highlight just the first element
this->setFocus();
QTextCursor cursor = this->textCursor();
cursor.setPosition(0);
cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, linesNumbers[0]);
this->setTextCursor(cursor);
QTextBlock block = document()->findBlockByNumber(linesNumbers[0]);
QTextBlockFormat blkfmt = block.blockFormat();
// Select it
blkfmt.setBackground(Qt::yellow);
this->textCursor().mergeBlockFormat(blkfmt);
}
However if you want to test the project with the cpp file I used (in the directory FileToOpen\diagramwidget.cpp), here's the complete source
http://idsg01.altervista.org/QTextEditProblem.zip
I've been trying to solve this for a lot of time and I'm starting to wonder if this isn't a bug or something similar
The QTextEdit can't accept such a big amount of text at one piece. Split it, for example like this:
if (!fileName.isEmpty()) {
QFile file(fileName);
if (file.open(QFile::ReadOnly | QFile::Text))
{
QByteArray a = file.readAll();
QString s = a.mid(0, 3000);//note that I split the array into pieces of 3000 symbols.
//you will need to split the whole text like this.
QString s1 = a.mid(3000,3000);
editor->setPlainText(s);
editor->append(s1);
}
It seems that the QTextEdit control needs time after each loading, setting a QApplication:processEvents(); after setPlainText() solves the problem although it's not an elegant solution.
Related
I am working on VS2015 with qt framework. In my source code, I have a function for printing in the GUI screen.
This function is called each time something needs to be printed.
It goes like this.
void Trial::Print_MessageBox(QString string)
{
ui.MessagesScreen->appendPlainText(string);
Cursor_Messagebox.movePosition(QTextCursor::End);
ui.MessagesScreen->setTextCursor(Cursor_Messagebox);
ui.MessagesScreen->ensureCursorVisible();
}
// Output in MessageBox
void Trial::Print_MessageBox(QFlags<QNetworkInterface::InterfaceFlag> flags)
{
QString str = QString("Flag %1").arg(flags);
ui.MessagesScreen->appendPlainText(str);
}
The above function has no problems and running well.
Now I am trying to read a text file. This has set of values in no order or size. An example for this:
231, 54, 4 \n
47777, 2211, 676, 9790, 34236, 7898\n
1, 3\n
Objective is to convert these into integers (line by line) and print them in the GUI and also send them (line by line) to other system. So I tried to do it with the following.
void Trial::ReadFile_Data()
{
QFile file("input.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
Print_MessageBox("Error in reading File");
return;
}
QTextStream in(&file);
while (!in.atEnd())
{
QString line = in.readLine();
Print_MessageBox(line);
int conv = line.toInt();
QString str = QString("%1 %2").arg("Values are: ").arg(conv);
Print_MessageBox(str);
QStringList fields = line.split(",");
}
file.close();
}
When I print the "line", it is just printing the same values as in the file. When I do the conversion and printing, I get an error (which is expected) Now I try to remove "," with the help of split then I get QstringList which I cannot use as I have the Qstring function to print(this cant be changed)
I am not getting any pointers from here. Please help me out as this is bugging me since long time.
Just simple...
QStringList::const_iterator constIterator;
for (constIterator = fonts.constBegin(); constIterator != fonts.constEnd();
++constIterator) {
cout << (*constIterator).toLocal8Bit().constData() << endl;
}
where fonts is your QStringlist
Your question reduces to "How do I iterate over a QStringList".
Like this:
// C++11
for (auto field : fields) Print_messageBox(field);
// C++98
foreach (QString field, fields) Print_messageBox(field);
See here for information about how foreach a.k.a Q_FOREACH was implemented.
I have an HTML file stored locally that I have to extract text from.
Now I managed to prompt the user for the location and display the HTML file in a QTextBrowser by pressing a button. Now from what I understand the next step would be to convert to a string to be able to search for text inside the source code.
Here's my Button_clicked method so far
void MainWindow::on_getHTMLButton_clicked()
{
QString filename = openFilenameDialog();
if (filename.isEmpty())
{
QMessageBox::information(this, tr("File Name"), "Es wurde keine gültige Datei angegeben.");
}
else
{
QFile file(filename);
if (!file.open(QIODevice::ReadOnly))
{
QMessageBox::information(0, "Info", file.errorString());
}
else
{
QTextStream in(&file);
ui->textBrowserHTML->setText(in.readAll());
}
}
}
The HTML file shows in textBrowser without any issues.
My understanding so far is that I need to create a string to search for a substring in the source code.
Now my problem is that I cannot seem to create a string object with the source of the HTML file as content.
Something like
QString string = in.readAll();
does not seem to work...
I had to learn that after having read out the stream and putting it to the ui by
ui->textBrowserHTML->setText(in.readAll());
the stream is empty – so when I attempt to to do a readAllagain it results in an empty string.
Currently I am copying the text to a LineEdit and on click PushButton it will write the text to a file which is "data.txt". I have written a readfile() which will read the text from data.txt and on click PushButton it should display the text in new line format at LineEdit.
Here is my code:
void MainWindow::writefile()
{
QString str = ui->lineEdit->text();
QString filename = "data.txt";
QFile file(filename);
file.open(QIODevice::WriteOnly|QIODevice::Text);
QTextStream out(&file);
out<<str<<endl;
file.close();
}
void MainWindow::readfile()
{
QString filename = "data.txt";
QFile file(filename);
file.open(QIODevice::ReadOnly|QIODevice::Text);
QTextStream in(&file);
QString str = in.readLine();
ui->lineEdit_2->setText(str);
file.close();
}
void MainWindow::on_pushButton_2_clicked()
{
readfile();
}
void MainWindow::on_pushButton_clicked()
{
writefile();
}
Please suggest how to separate those comma-separated strings and must display in new line format
The documentation of QLineEdit says:
A line edit allows the user to enter and edit a single line of plain text [...]
A related class is QTextEdit which allows multi-line, rich text editing.
Thus, you should use the QTextEdit widget instead of QLineEdit to allow multi-line text. It also has a setText, so you can use it the same way.
To replace commas with new line characters use the replace method:
// ...
QString str = in.readLine();
str = str.replace(",", "\n");
ui->textEdit_2->setText(str);
//...
I need to create qt gui push button with line edit, where I press the button which leads to browsing a folder to find a textfile I want to import. The textfile will be parsed afterwards. I would prefer to use combobox but I have no idea how to browse the folder through gui. Perhaps something like QDir related stuff should work but please help.
Basically, I want to import/open a textfile using push button/combobox.
What you are looking for is QFileDialog
connect the clicked() signal of your QPushButton to a slot that performs:
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Text file"), "", tr("Text Files (*.txt)"));
Then you can parse the file using for instance QFile and QTextStream:
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream in(&file);
while (!in.atEnd())
{
QString line = in.readLine();
process_line(line);
}
EDIT
If you want to parse a file where each line contains 31 floats that you want to store in a float data[31], I would first create the class:
struct FloatLine { float data[31]; };
Then store all the lines in a QList<FloatLine>, this way:
QList<FloatLine> floatLines;
QTextStream in(&file);
while (!in.atEnd())
{
QString line = in.readLine();
QTextStream lineStream(&line);
floatLines << FloatLine();
for(int i=0; i<31; i++)
lineStream >> floatLines.last().data[i];
}
You might want to use QFileDialog, there are few example at that QtDocument.
There are two slots for open & close in my gui.
When i open a file its content are shown in text editor, then i press close button changes are save to file.
But Now when i again press, open & reload the same file. Nothing is shown in text editor, blank editor.
Why file is not reloading ?
private:
Ui::MainWindow *ui;
QFile file;
QTextStream out;
QString url; // the url of the file
void MainWindow::on_actionOpen_triggered()
{
QString openfileurl = QFileDialog::getOpenFileName();
if(openfileurl.isEmpty() || openfileurl == url) return;
file.setFileName(openfileurl);
//if(file.open(QIODevice::ReadOnly|QIODevice::Text))
if(file.open(QIODevice::ReadWrite|QIODevice::Text))
{
url = openfileurl;
ui->textEdit->setPlainText(QString::fromUtf8(file.readAll()));
}
//Set file to -- Qtextstream
out.setDevice(&file);
}
void MainWindow::on_actionClose_triggered()
{
//Set file to -- Qtextstream
out << ui->textEdit->toPlainText();
file.close();
ui->textEdit->clear();
}
Try this way
void MainWindow::on_actionClose_triggered()
{
//Set file to -- Qtextstream
out << ui->textEdit->toPlainText();
file.close();
ui->textEdit->clear();
uri.clear();
}
I think you should clear uri before make this check:
if(openfileurl.isEmpty() || openfileurl == url) return;
It will blowup when openfileurl == url. And it will do it definitely sure if you didn't cleared the uri. And here you are:
reload the same file
...with the same content... so, the if statement goes true and returns that's why the code below is not executing the second time.