PDA

View Full Version : Create QGrapchisObject in sub QThread, but not Efficiency promotion



cybfly
6th July 2015, 15:51
Hi, Everyone.
I am using QGraphicsView system to show a layout in chip design system.(EDA tools like Virtuso、Thunder、ICC)
And the max amount of QGraphicsObject/QGraphicsItem can be 500,000+, or even more.
Thus i have problem making items easy and quick to be drawn or view in the scene.
I followed the Chips demo, and query the solutions from Google, also read lots of topics in QtCentre.
But still i did not find a viable solution, Also Text item impact enormous.
Out group use the tree structure to organize the objects, which use a root item as the top level item, and then level 2, level 3...
But the users always need to flat all the items. And Then i use QTransform()::m11() to control the shape the item is paint.
But with so many items inside even this methods does not work.

There are two difficult parts on this case:
1)how to reduce the loading time for creating QGraphicsItem.
2)how to make it smoother while zoom in/zoom out, with so many items.

Codes below are the sample i tried to use QThread to save loading time. But it does not work, or the program works
bad than no sub thread is used to load the items. I am very curious why the program has no response when i used sub thread,
and the program runs smoother with no sub thread.

Thanks all.




// Used to as Root item
class CRoot: public QGraphicsObject
{
public:
CRoot(QGraphicsObject *opParent = NULL) : QGraphicsObject(opParent)
{}

QRectF boundingRect() { return QRectF(); }
...
};

// Leaf Item
class Chip : public QGraphicsObject
{
...
void paint(QPainter *opPainter, const QStyleOptionGraphicsItem *opOPtion, QWidget *opWidget)
{
Q_UNUSED(opOPtion);
Q_UNUSED(opWidget);
opPainter->save();
double d_value = mdWidth * transform().m11();
if (d_value >= 7)
{
opPainter->drawShape(moShape);
}
else
{
opPainter->drawPoint(0, 0);
}

opPainter->restore();
}

private:
QPainterPath moShape; // used to store the path of Chip
QGraphicsTextItem *mopLabel; // Label item of this cell.
};

class CLayout : public QGraphicsObject
{
Q_OBJECT
public:
CLayout(QGraphicsObject *opParent = NULL) : QGraphicsObject(opParent)
{

}

CRoot *mopGetRoot()
{
QReadLocker o_locker(&moLock);
return mopRoot;
}
signals:
void msigLoadDone();

public slots:
void mslotLoadItems()
{
QWriteLocker o_locker(&moLock);
mopRoot = new CRoot;

const int I_COUNT = 500000;
for (int i_cnt = 0; i_cnt < I_COUNT; ++i_cnt)
{
Chip *op_chip = new chip(CRoot);
op_chip->setPos(i_cnt / 10000, i_cnt / 10000);
mlstopItems.push_back(op_chip);
}

// move items from curThread to GUI thread.
moveToThread(QApplication::instance()->thread());
mopRoot->moveToThread(QApplication::instance()->thread());
foreach(Chip *op_item, mlstopItems)
{
op_item->moveToThread(QApplication::instance()->thread());
}

emit msigLoadDone();
}

private:
CRoot *mopRoot;
QList<Chip *> mlstopItems;
QReadWriteLock moLock;
};

class CMainWindow: public QMainWindow
{
Q_OBJECT
public:
...
void mvInitScene()
{
mopScene = new QGraphicsScene();
}

signals:
void msigGoToLoad();

public slots:
void mslotSetRootItem()
{
std::call_once(meFlag, &CMainWindow::mvInitScene, this);
mopScene()->addItem(mopLayout->mopGetRoot());
}

void mslotBtnClicked()
{
mopThread = new QThread();
mopLayout = new Layout();

#ifdef USED_THREAD
connect(this, SIGNAL(msigGoToLoad()), mopLayout, SLOT(mslotLoadItems()));
connect(mopLayout, SIGNAL(msigLoadDone()), this, SLOT(mslotSetRootItem()));
connect(mopThread, SIGNAL(finished()), mopThread, SLOT(deleteLater()));
mopLayout->moveToThread(mopThread);
mopThread->start();
#else
mopLayout->mslotLOadItems();
mslotSetRootItem();
#endif
emit msigGoToLoad();
}
private:
QThread *mopThread;
CLayout *mopLayout;
QGraphicsScene *mopScene;
std::once_flag meFlag;
};