PDA

View Full Version : How can i load/display csv file in QTableWidget?(long read, sorry)



msimurin
15th March 2010, 03:57
So what i am trying to do is make my app that has spreadsheet(qtablewidget) as mainwindows central widget open and display csv files in such a way that every word in csv file loaded by my app(all words in csv file are separated by comma) is displayed in QTableWidget cell in natural flow so on the end my spreadsheet would display each word from csv file in its own cell in spreadsheet by natural flow as it looks in csvreaders.


http://img707.imageshack.us/img707/2646/84961871.jpg (http://img707.imageshack.us/i/84961871.jpg/)


Currently i am studying QT Programming book (ver 2) and i must say i am having a rought time, i am rereading, memorizing, trying to figure this book and even its sometimes really a pain i am not giving up.

What did i learn so far following the spreadsheet example is how to write file from my spreadsheet(qtablewidget) and how to open that file.

The logic that program follows for doing this is simply - Iterate over each row and column, specify each column, get the data from it as text and give that text to Qstring for writting in a file and with row_colun iteration write row, column and its string to a file with QDataStream in a sequence so on the end file written ends like

row 1 - column 1 - string, row 1 -column 2 - string, row 1 - column 3 - string and so on... all the way to the end of last column in table


Now to read this and display it on widget book example is using while loop and puts (!in.atEnd()) as condition so if input streaming is not done it will display each cell that is written inside file on my spreadsheet widget.

It does so because each row and column is written as int number inside the file, it takes these numbers in order starting with(row 1 - column 1) passes these as arguments to a function in my class that accordingly writes all text(string) in row and column it gets and on the end bam every text is in every cell written and my table is written, phew this reminded me how much headaches i had before simply figuring how this works. Maybe i am dumb or this book is just not suited for starters but i am learning alot.

So, why am i writting this on the end. Because i cant figure the logic that QDataStream uses. I see how i can read my own Qtable spreadsheet files because each time i write data with QDataStream i will write inside it a row, column, text and use my function to display this data in table because it gets required parameters for it but HOW IN THE WORLD...

am i going to make my application load some .csv that lets say i download from the Web to open it and display it, how if i have no clue what is inside it? (the low level data) because i am assuming when some csv program saves csv file and some guy emails(example) that file to me it surely doesnt have same low level data(like my spreadsheet files do) that i can simply pass it to my app and its functions for displaying(loading), so what am i gonna do then, is it possible to somehow achieve this?

Sorry for long read but i tried to be specific so you can understand my situation better, thank you for reading

ChrisW67
15th March 2010, 06:59
A CSV file is basic text and the correct Qt tool to read or write it would be QTextStream with some parsing logic to split lines at the delimiters. QDataStream, as used by the book's Spreadsheet example, is a binary format reader/writer that's more suited to making program data structures persistent on disk in a portable fashion.

You might also like to look at Qxt (http://www.libqxt.org/), which has a CSV file model.

hollowhead
17th March 2010, 11:25
I'm having the same problem msimurin.

This code not for csv works but for ordinary txt files works slightly in that something is imported but not correctly



{


clear();
QTextStream in(&file);
QString txt;
const int TabSize =8;
int endlCount =0;
int spaceCount=0;
int column=0;

QApplication::setOverrideCursor(Qt::WaitCursor);
while (!in.atEnd())
{
in >> txt;
if (txt=='\n') // row
{
//++endlCount;
//spaceCount=0;
//column=0;
++row;
}
else if (txt=='\t') //column
{
//int size=TabSize-(column%TabSize);
//spaceCount+=size;
//column+=size;
++column;
}
else if (txt==' ') //column
{
//++spaceCount;
++column;
}
/*else
{


//row=endlCount;

}*/
// ++column;
in >> row >> column >> txt;
setFormula(row, column, txt); //spreadsheet specific code given in C++ GUI programming with QT4
}
}


The code given in the above book for importing txt files doesn't compile it doesn't like something about the join() function used.

I also found this code posting somewhere which imports CSV files as one row yuo might find useful



Note:
tbl_trades is my own subclassed QTableWidget.


void mywidget::read_line()
{
char* cfg_file = getenv("FILE");
QFile file( cfg_file );

if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) ) {
while ( !file.atEnd() ) {
QByteArray line = file.readLine();
QStringList vals = QStringList::split( ',', line, 0 );
if ( vals.size() == no_of_cols ) { // valid line of text
tbl_trades->insertRow( 0 ); // new row
tbl_trades->setRowHeight( 0, 20 ); // resize new row
for ( int i = 0; i < no_of_cols; i++ ) { //
QTableWidgetItem *temp = new QTableWidgetItem(
vals[i] );
tbl_trades->setItem( 0, i, temp );
}
}
}
}
}


I haven't given up on this I think the answer is to stream it in

count delimiters so for txt (how does csv give columns?)

1) count rows using split( '\n') and put this in stringlist
2) then count columns
3) then iterate over rows and column count and use split( '\t') into cells using the tab delimiter

however my attempt to do this has failed in that it seems to put something in the cell 0,0 but not anything visible and nothing in the other cells trying to import a txt file with

one three
two four



QTextStream in(&file);
QString txt;
QStringList rows;
QStringList columns;
QApplication::setOverrideCursor(Qt::WaitCursor);
while (!in.atEnd())
{

txt=in.readLine(); // read in file
rows=txt.split('\n'); // search for newlines
columns = txt.split('\t'); // search for tabs

}

int numRows=rows.count();
int numColumns=columns.count()+1;
//int numColumns=rows.first().count('\t')+1;
int row=0;
int column=0;

for (int i = 0; i < numRows; ++i) {

for (int j = 0; j < numColumns; ++j)
{
// columns=txt[i].split('\t');
// int row = range.topRow() + i;
// int column = range.leftColumn() + j;
if (row < RowCount && column < ColumnCount)
{
in >> row >> column >> txt;
setFormula(row, column, txt);
row++;
column++;
}

}
}
}



It really bugging me since it cannot be that difficult and I want to crack it myself.... When one of us has cracked it why don't we post it here....

wysota
17th March 2010, 11:31
A CSV file is basic text and the correct Qt tool to read or write it would be QTextStream with some parsing logic to split lines at the delimiters.

To add to that - there is a regular expression available that can parse csv files (or lines, actually). I found it on the Web some time ago, I'm sure it can be looked up again.