hi,
sorry for opening a second thread in one day, i'm really stumbling from one pitfall into another here
the situation is like this:
i got a QStandardItemModel subclass presenting a tree of data.
this includes a list of EVENTs, who have about 4-5 sub-elements each.
onto this model, i want to set a proxy model, subclassed from QAbstractProxyModel, to map the EVENTs into a table-like model.
eg. an EVENT has an NOTE attribute (sub-item in the tree) with value 10, so some of it's information should be used in row 10 in the proxy.
as you can imagine, danymic mapping in the mapToSource function is rather expensive because every time i have to search through all the EVENTs and try to find one that fits the current row.
but i underastimated HOW expansive it really is.
so, the proxy displays a 4 * 128 table, there is only one EVENT in the source model.
but nevertheless it takes several seconds to build up the proxy (on an 5200 dual core!), making scrolling etc. just impossible. adding more scenes should have linear complexity, making it event more unusable.
i really can't see the performance drain here. initially displaying the proxy results in ~800 calls of mapToSource - how can that take so long? are the model - functions like data(), index etc. such performance hogs?
code:
QModelIndex NewScriptModelEventTableProxy
::mapToSource( {
// is lightning fast, so rest rest of the function is the cause
//return QModelIndex();
static int p_iCalls = 0;
++p_iCalls;
// about 800 calls for initial display
qDebug() << "calls : " << p_iCalls;
int p_iNote = i_ProxyIndex.row();
int p_iColumn = i_ProxyIndex.column();
if(p_iColumn == this->ColOnAction || p_iColumn == this->ColOnCondition)
p_State = "on";
else
p_State = "off";
QModelIndex p_EventTable
= this
->sourceModel
()->index
(0,
0);
// will only be 1 in my test case
int p_iNumEvents = this->sourceModel()->rowCount(p_EventTable);
for(
int i = 0;
i < p_iNumEvents;
++i)
{
QModelIndex p_Event
= this
->sourceModel
()->index
(i,
0, p_EventTable
);
// about 4
int p_iNumAttributes = this->sourceModel()->rowCount(p_Event);
int p_EventNote;
int p_EventTrack;
for(
int j = 0;
j < p_iNumAttributes;
++j)
{
QString p_AttributeName
= p_AttributeIndex.
data().
toString();
if(p_AttributeName == "note")
p_EventNote = p_ValueIndex.data().toString().toInt();
else if(p_AttributeName == "track")
p_EventTrack = p_ValueIndex.data().toString().toInt();
else if(p_AttributeName == "state")
p_EventState = p_ValueIndex.data().toString();
else if(p_AttributeName == "action")
p_Action = p_ValueIndex;
else if(p_AttributeName == "condition")
p_Condition = p_ValueIndex;
}
if(
p_EventNote == p_iNote &&
p_EventTrack == this->m_iTrack &&
p_EventState == p_State)
{
switch(p_iColumn)
{
case this->ColOnAction:
case this->ColOffAction:
return p_Action;
default:
return p_Condition;
}
}
}
}
QModelIndex NewScriptModelEventTableProxy::mapToSource(
const QModelIndex &i_ProxyIndex) const
{
// is lightning fast, so rest rest of the function is the cause
//return QModelIndex();
static int p_iCalls = 0;
++p_iCalls;
// about 800 calls for initial display
qDebug() << "calls : " << p_iCalls;
int p_iNote = i_ProxyIndex.row();
int p_iColumn = i_ProxyIndex.column();
QString p_State;
if(p_iColumn == this->ColOnAction || p_iColumn == this->ColOnCondition)
p_State = "on";
else
p_State = "off";
QModelIndex p_EventTable = this->sourceModel()->index(0, 0);
// will only be 1 in my test case
int p_iNumEvents = this->sourceModel()->rowCount(p_EventTable);
for(
int i = 0;
i < p_iNumEvents;
++i)
{
QModelIndex p_Event = this->sourceModel()->index(i, 0, p_EventTable);
// about 4
int p_iNumAttributes = this->sourceModel()->rowCount(p_Event);
int p_EventNote;
int p_EventTrack;
QString p_EventState;
QModelIndex p_Action;
QModelIndex p_Condition;
for(
int j = 0;
j < p_iNumAttributes;
++j)
{
QModelIndex p_AttributeIndex = p_Event.child(j, 0);
QModelIndex p_ValueIndex = p_Event.child(j, 1);
QString p_AttributeName = p_AttributeIndex.data().toString();
if(p_AttributeName == "note")
p_EventNote = p_ValueIndex.data().toString().toInt();
else if(p_AttributeName == "track")
p_EventTrack = p_ValueIndex.data().toString().toInt();
else if(p_AttributeName == "state")
p_EventState = p_ValueIndex.data().toString();
else if(p_AttributeName == "action")
p_Action = p_ValueIndex;
else if(p_AttributeName == "condition")
p_Condition = p_ValueIndex;
}
if(
p_EventNote == p_iNote &&
p_EventTrack == this->m_iTrack &&
p_EventState == p_State)
{
switch(p_iColumn)
{
case this->ColOnAction:
case this->ColOffAction:
return p_Action;
default:
return p_Condition;
}
}
}
return QModelIndex();
}
To copy to clipboard, switch view to plain text mode
Bookmarks