vizz
7th December 2009, 09:57
Hi,
I'm trying to subclass QTableWidget in order to alter its functionality/behavior. What I need is a function/method to populate the widget's table with data read from a text file but not all the data. The idea is to create a "fully-scrollable fake-view for the user", a range of rows, for example 10, while having thousands of rows in the data file, and give him a tool ( an independent* scrollbar; minimum 0, maximum results.size() ) to browse through all the data available.
Use case:
So for example, I read a hudge text file ( 15 MB! ; max case ) with a custom method, save the results in a "vector of strings" and populate only a subset of data rows ( like first 10 for the start ). "I scroll down the table" to see the rest of the data ( in fact, i want to scroll only the scrollbar and change the contents of the fake-table to present the appropriate/relevant data, like row names/indexes and row data ).
Why do I do it like that? Becase of my benchmark tests. When I tried to populate the table with all the data, the whole process was endless ( 1MB file presented in over 120 sec. ). The problem was on the Qt side. The data reading funtion worked pretty well ( 15 MB of raw text data saved to vector of strings in less then 4.5 sec ), so I figured out this idea of a "small table working like pixels in a TV".
The problem is, I can not get the scroll bar work independantly of the QTableWidget's contents. I mean, I can not set it free to be always enabled to scroll through <0; results.size()> range. Is there any way to make it possible? Or, if not, is there any efficient way of populating the QTableWidget's contents with some kind of a vector/list/something?
The file's structure is:
TITLE|VARIABLE1:NAME1:VALUE1|VARIABLE2:NAME2:VALUE 2|
(as you can see the looping pattern is: "VARIABLE(N):NAME(N):VALUE(N)|VARIABLE(N+1):NAME(N+ 1):VALUE(N+1)|" )
The function/method is:
class MyQTableWidget { //..// private: std::vector<std::string*> results; //...// };
int MyQTableWidget::getDataFromFile(const char* v_szText, const char v_szDelimiter)
{
std::ifstream inf(v_szText);
std::string buf;
std::string name;
std::string label;
std::string value;
QTableWidgetItem* iLabel;
QTableWidgetItem* iValue;
while(!std::getline(inf, buf, v_szDelimiter).eof()) {
std::stringstream str(buf, std::stringstream::in);
std::getline(str, name, ':');
std::getline(str, label, ':');
std::getline(str, value);
results.push_back(new std::string(name));
results.push_back(new std::string(label));
results.push_back(new std::string(value));
} // while
int range = results.size() < 20 ? results.size() : 20; // show only 20 items
for(int i = 0; i < range; i++) {
iLabel = new QTableWidgetItem(tr((*(results[2*i])).c_str()));
iValue = new QTableWidgetItem(tr((*(results[2*i+1])).c_str()));
this->setRowCount(i + 1);
this->setItem(i, 0, iLabel);
this->setItem(i, 1, iValue);
}
vbar = new QScrollBar(this);
vbar->setMinimum(0);
vbar->setMaximum(results.size());
vbar->setEnabled(true);
vbar->setValue(0);
this->setVerticalScrollBar(vbar);
this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
// ... //
} // getDataFromFile
Shall I use some type of lazy loading ( like in Ajax ) or perhaps use some type of special technics for populating large sets of data?
Any help please?
I'm trying to subclass QTableWidget in order to alter its functionality/behavior. What I need is a function/method to populate the widget's table with data read from a text file but not all the data. The idea is to create a "fully-scrollable fake-view for the user", a range of rows, for example 10, while having thousands of rows in the data file, and give him a tool ( an independent* scrollbar; minimum 0, maximum results.size() ) to browse through all the data available.
Use case:
So for example, I read a hudge text file ( 15 MB! ; max case ) with a custom method, save the results in a "vector of strings" and populate only a subset of data rows ( like first 10 for the start ). "I scroll down the table" to see the rest of the data ( in fact, i want to scroll only the scrollbar and change the contents of the fake-table to present the appropriate/relevant data, like row names/indexes and row data ).
Why do I do it like that? Becase of my benchmark tests. When I tried to populate the table with all the data, the whole process was endless ( 1MB file presented in over 120 sec. ). The problem was on the Qt side. The data reading funtion worked pretty well ( 15 MB of raw text data saved to vector of strings in less then 4.5 sec ), so I figured out this idea of a "small table working like pixels in a TV".
The problem is, I can not get the scroll bar work independantly of the QTableWidget's contents. I mean, I can not set it free to be always enabled to scroll through <0; results.size()> range. Is there any way to make it possible? Or, if not, is there any efficient way of populating the QTableWidget's contents with some kind of a vector/list/something?
The file's structure is:
TITLE|VARIABLE1:NAME1:VALUE1|VARIABLE2:NAME2:VALUE 2|
(as you can see the looping pattern is: "VARIABLE(N):NAME(N):VALUE(N)|VARIABLE(N+1):NAME(N+ 1):VALUE(N+1)|" )
The function/method is:
class MyQTableWidget { //..// private: std::vector<std::string*> results; //...// };
int MyQTableWidget::getDataFromFile(const char* v_szText, const char v_szDelimiter)
{
std::ifstream inf(v_szText);
std::string buf;
std::string name;
std::string label;
std::string value;
QTableWidgetItem* iLabel;
QTableWidgetItem* iValue;
while(!std::getline(inf, buf, v_szDelimiter).eof()) {
std::stringstream str(buf, std::stringstream::in);
std::getline(str, name, ':');
std::getline(str, label, ':');
std::getline(str, value);
results.push_back(new std::string(name));
results.push_back(new std::string(label));
results.push_back(new std::string(value));
} // while
int range = results.size() < 20 ? results.size() : 20; // show only 20 items
for(int i = 0; i < range; i++) {
iLabel = new QTableWidgetItem(tr((*(results[2*i])).c_str()));
iValue = new QTableWidgetItem(tr((*(results[2*i+1])).c_str()));
this->setRowCount(i + 1);
this->setItem(i, 0, iLabel);
this->setItem(i, 1, iValue);
}
vbar = new QScrollBar(this);
vbar->setMinimum(0);
vbar->setMaximum(results.size());
vbar->setEnabled(true);
vbar->setValue(0);
this->setVerticalScrollBar(vbar);
this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
// ... //
} // getDataFromFile
Shall I use some type of lazy loading ( like in Ajax ) or perhaps use some type of special technics for populating large sets of data?
Any help please?