PDA

View Full Version : QTableWidget subclassing, populating and scrolling problem



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?

high_flyer
7th December 2009, 16:37
The problem is, I can not get the scroll bar work independantly of the QTableWidget's contents.
Did you try to disable the scroll bar for the table, and add your own scroll bar?
This way, you can set any range you want to your scroll bar, and populate your table in a custom way with the data you want.

vizz
8th December 2009, 10:27
Well, I actualy tried that :/ The thing is, that if I add a custom scrollbar with its minimum and maximum set appropriately, it is somehow managed by the QTableWidget to disable scrolling if the number of shown elements is less than the "the view size" ( visible area ) :/ I suppose it is because populating the table causes emition of some sort of signal or updates some QTableWidget's properties.

I tried to do it like that:


vbar = new QScrollBar(this); // this = QTableWidget
vbar->setMinimum(0);
vbar->setMaximum(results.size()); // results is a vector of string*
vbar->setEnabled(true);
vbar->setValue(0);


this->setVerticalScrollBar(vbar);
this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);

vizz
8th December 2009, 10:49
Ok, I did some terrible mistake in my code, that is why it didn't work for me. Sorry for you trouble. :/