Filling some QTableWidgetItems with QString from file - qt

I'm trying to fill a QTableWidget from a file that was exported by my program, but when I try to set text to the table cells they just ignore me, nothing happens.
void MainWindow::on_actionOpen_Project_triggered()
{
QString line, fileName;
fileName = QFileDialog::getOpenFileName(this,tr("Open Project"), "", tr("Project Files (*.project)"));
if(!fileName.isEmpty()){
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
QTextStream in(&file);
for(int i=0;i<ui->code->rowCount();i++){ // goes through table rows
for(int j=0;j<ui->code->columnCount();j++){ // through table columns
ui->code->setCurrentCell(i,j);
QTableWidgetItem *cell = ui->code->currentItem();
in >> line;
if(!line.isEmpty()){
cell = new QTableWidgetItem(line); // relates the pointer to a new object, because the table is empty.
ui->errorlog->append(line); // just for checking if the string is correct visually.
}
}
}
file.close();
}
}
The errorlog object shows on the screen the correct values opened from the file, however the table is not filled. Any problems found?

This line:
cell = new QTableWidgetItem(line);
doesn't do what you think it does. Assigning the cell doesn't change anything in the table – cell is just a local variable, overwriting it doesn't have any effect elsewhere.
You (probably) want to do something like this instead:
cell->setText(line);
Or (if you don't really need to change the current item):
ui->code->item(i,j)->setText(line);
If those give you a segfault, it's that you haven't set the table's widget items yet. In that case, you should do something like:
QTableWidgetItem *cell = ui->code->item(i,j);
if (!cell) {
cell = new QTableWidgetItem;
ui->code->setItem(i,j,cell);
}
if (!line.isEmpty()) {
cell->setText(line);
}
This will populate all the cells with QTableWidgetItems the first time this function is called, and reuse them subsequently.

Related

QPlainTextEdit: How to overwrite the text at the cursor instead of moving it forward

I have a QPlainTextEdit that is supposed to display process output. But when the process outputs CR to reset the line, i struggle to implement the same behaviour the terminal would do.
I basically need to do the same as if user pressed Home, then Insert, and then Ctrl+V with the new text in the clipboard.
I tried
textEdit->setOverwriteMode( true );
textEdit->moveCursor( QTextCursor::StartOfLine );
textEdit->insertPlainText( newText );
but it does not work as expected. The text is still inserted, moving the existing text in front of the cursor forward, instead of overwriting it.
What else can i do to achieve what i need?
I hope I understood your question correctly. So you actually only want to replace a word or text without the existing text being moved in one direction but being replaced.
So you can do that as follows. With an input (eg QLineEdit) you insert the word. The QPlainTextEdit has a find() function that returns true or false if the word is found.
with cursor.movePosition() you iterate over the position you need. The text to be replaced is swapped with the new text.
here is a small example:
void MainWindow::on_pushButton_clicked()
{
QString searchWord = ui->lineEdit->text();
if(ui->plainTextEdit->find(searchWord, QTextDocument::FindWholeWords))
{
QString updateWord = "YourWord/text"; // Your new Word here
QTextCursor cursor = ui->plainTextEdit->textCursor();
// for lines just use: QTextCursor::StartOfLine
cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor, 1);
cursor.insertHtml("<p style=\"background-color:red;color:white;white-space:pre\">" + updateWord + "</p>");
ui->plainTextEdit->insertPlainText(cursor.selectedText());
ui->plainTextEdit->setTextCursor(cursor);
}
}
Or even shorter:
QString searchWord = ui->lineEdit->text();
if(ui->plainTextEdit->find(searchWord, QTextDocument::FindWholeWords))
{
QString updateWord = "YourWord/text"; // Your new Word here
QTextCursor cursor = ui->plainTextEdit->textCursor();
// for single words, just use: QTextCursor::StartOfWord
cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor, 1);
ui->plainTextEdit->insertPlainText(updateWord);
}

Add String from textEdit to a QStack

I am trying to capture the contents from textEdit and add it to a QStack. The content I am splitting so to be able to reverse the order of the sentence captured. I already have that part covered, but I want to be able to convert from QStringList to be pushed to the QStack. This is what I have:
void notepad::on_actionReversed_Text_triggered()
{
QString unreversed = ui->textEdit->toPlainText();
QStringList ready = unreversed.split(QRegExp("(\\s|\\n|\\r)+"), QString::SkipEmptyParts);
QStack<QString> stack;
stack.push(ready);
QString result;
while (!stack.isEmpty())
{
result += stack.pop();
ui->textEdit->setText(result);
}
}
QStack::push only takes objects of it's template type.
i.e. In your case you must push QString's onto the QStack<QString>, and not a list.
So, iterate the list of strings pushing each one in turn.
foreach (const QString &str, ready) {
stack.push(str);
}
Something else that is wrong is that you are updating textEdit inside the for loop. You actually want to build up the string in the loop and afterwards update the text.
QString result;
while (!stack.isEmpty()) {
result += stack.pop();
}
ui->textEdit->setText(result);
An alternate answer could be to do away with the stack and just iterate the QStringList ready in reverse order to build up result string.

How to report progress without going through the entire file before I process

I have to parse a big file with several thousand records. I want to display a progress bar, but I do not know the number of recordings in advance. Do I have to roll over this file twice?
The first to know the number of recording.
The second to perform the treatment
Or is there a more simple way to get the number of records without going through the entire file before I process ?
My code snippet :
void readFromCSV(const QString &filename){
int line_count=0;
QString line;
QFile file(filename);
if(!file.open(QFile::ReadOnly | QFile::Text))
return;
QTextStream in(&file);
while(!in.atEnd()){ //First loop
line = in.readLine();
line_count++;
}
while (!in.atEnd()) { //Second loop
...
line = in.readLine();
process();
...
}
}
Thank you for help
This question is different from the one here : counting the number of lines in a text file
1) The loop process is already done. In this case it is prevention of double shooting.
2) The code is a QT one, not a C++ fonction to add as a redundancy
I think there is no way to count lines without reading the file at least once. To avoid it I wouldn't rely on the number of lines, but rather on how much data I have been read. Here is how I would solve this problem:
QFile file(fileName);
file.open(QFile::ReadOnly | QFile::Text);
const auto size = file.size();
QTextStream in(&file);
while (!in.atEnd()) {
auto line = in.readLine();
// Process line.
// [..]
// Calculate the progress in percent.
auto remains = file.bytesAvailable();
auto progress = ((size - remains) * 100) / size;
printf("progress: %d%%\r", progress);
}

How to can append the value from txt file to the Qlist

How I can to insert the value from txt file in to the Qlist...
QList<QString> list_StRead;
list_StRead.insert();
I can sorting txt file ... its mean that my file is a line by line. than after the insert to the Qlist I want to write in to Qtabelewidget. How I must to do?? u must to be completely understand. see the img file
tnx for all....
Here is the pseudo code.
Please try it. (Not tested, code written in notepad. excuse me any syntax errors).
//Your list
QList<QString> list_StRead;
//Text stream object read data and insert in list.
QTextStream in(&file);
while (!in.atEnd())
{
QString line = in.readLine(); //read one line at a time
list_StRead.push_back(line);
}
//loop your list
for(int i =0; i<list_StRead.size(); i++)
{
//Add by create your tablewidget item and append it.
YourTableWidget->setItem(rowNumber,colNumber,new QTableWidgetItem(list_StRead.at(i)))
}

How to set data source for a list view to contain custom data ? (and associate with QTableView)

I am trying to get listview and tableview working together.
The listview must be used for display, the tableview must be used for editing data. The tableview is created on demand in a popup widget (and it may never be needed).
I populate the listview, on start, from a text file - each row a line, with 2 entries separated by a tab. Easy.
The tableview will have to edit 2 columns separately... also, on listview click, I must be able to retrieve the first part of the split...
I have created a model subclass of QStringListModel.
QListView *m_myView = new QListView();
StringList *m_myList = new StringList();
QTextStream in(&myFile);
while (!in.atEnd())
{
QString temp = in.readLine();
if(!temp.isEmpty())
m_myList->append(temp);
}
myFile.close();
m_myView->setModel(m_myList);
where
class StringList : public QStringListModel
{
public:
void append (const QString& string)
{
insertRows(rowCount(), 1);
QModelIndex m = index(rowCount() - 1);
setData(m, string, Qt::EditRole);
QStringList splist = string.split('\t');
setData(m, splist.at(0), Qt::ToolTipRole);
if(splist.size() > 1)
setData(m, splist.at(1), Qt::StatusTipRole);
else
setData(m, "", Qt::StatusTipRole);
qDebug() << data(m, Qt::EditRole).toString()
<< data(m, Qt::ToolTipRole).toString()
<< data(m, Qt::StatusTipRole).toString();
}
};
The EditRole displays correctly, the others display empty strings.
It seems that QStringListModel is incapable of storing anything except EditRole.
So I am left with 2 options - either do the split on each selection, and also when creating the table view, or - what I would like to try but don't know how - create a QStandardItemModel that can act as data sources for both the listview and the tableview, and can easily retrieve the partial data I require on click.
I thought I can simply use it to set the data on listview (like they do here).
QListView *m_myView = new QListView();
QStandardItemModel *m_myList = new QStandardItemModel();
QTextStream in(&myFile);
int r = 0;
while (!in.atEnd())
{
QString temp = in.readLine();
if(!temp.isEmpty())
{
QStringList splist = temp.split('\t'); // assume I know there will be 2 strings always
QStandardItem *item = new QStandardItem(splist.at(0));
m_myList->setItem(r, 0, item);
QStandardItem *item1 = new QStandardItem(splist.at(1));
m_myList->setItem(r, 1, item1);
++r;
}
}
myFile.close();
m_myView->setModel(m_myList);
connect(m_myListView, SIGNAL(clicked(QModelIndex)),
this, SLOT(listChangedSlot(QModelIndex)));
But this will only set the first string in the listview, I really need both, and I still don't know how to retrieve the data
void listChangedSlot(QModelIndex index)
{
qDebug() << m_myList->item(index.row(), 0)->data().toString()
<< m_myList->item(index.row(), 1)->data().toString();
} // shows empty strings
Or...
In the loading section, try:
if(!temp.isEmpty())
{
QStringList splist = temp.split('\t');
splist.append(QString()); // so I don't need to test
QStandardItem *item = new QStandardItem(temp);
m_myList->setItem(r, 0, item);
QModelIndex idx = m_myList->index(r, 0);
QMap<int, QVariant> roles;
roles.insert(Qt::UserRole + 1, QVariant(splist.at(0)));
roles.insert(Qt::UserRole + 2, QVariant(splist.at(1)));
roles.insert(Qt::DisplayRole, QVariant(temp));
m_myList->setItemData(idx, roles);
++r;
}
This works - displays fine and gets the correct content on click - but seems to be unusable for the tableview.
(And seems I am doing twice the work, with setItem and setItemData - so technically storing the content 3 times).
How can I get my listview have a datasource with 2 string items, show both, be able to set it on a tableview, and be able to retrieve the first item on click ?
I figured out a way to share the data source between the listview and tableview:
I create 3 columns - column 0 with the combined components, and columns 1 and 2 with the separated components.
The listview will display only column 0. For tableview, I will hide column 0.
The data I require for processing will be stored in columns 1 and 2. user edit of the data in tableview will require, upon accepting changes, the edit of corresponding column 0.

Resources