最近一直在使用QGIS在绘制方面的工作,而且需要在地图上大量绘制图形要素并且这些图形要素全部存在MySQL数据库中。
最初设计的方案是:
在绘制的时候实时从数据库中读取数据然后绘制出来,刚开始的时候绘制效率还是可以接受的。
void War2DDraw::draw(QPainter *painter){
const QVector<Entity*>& entitys = entityMgr().entitys();
int sum = entitys.size();
for (int loop = 0; loop < sum; loop++){
Entity* entity = entitys[loop];
Data* data = getDataFromMySQL();//从数据库中获取数据
entity->Draw(data);
}
}
通过以上代码可以看到,在实体绘制之前把所需要的数据提前从数据库中查找出来,然后放置到实体中进行绘制。如果实体的数量不是很多的时候,绘制效率可以满足条件的。
但是如果需要绘制的实体达到100及其以上的时候,整个程序处于卡机“假死”状态。真的是让人无法接受。而且这也不是应该呈现的状态。
下一步思考:
如何把数据获取和数据展示分步进行,首先想到的是采用线程。绘制的时候肯定是在主线程中进行的,那么读取数据操作只能在另外一个线程中了。
1.首先定义一个回调接口类:
class IRunData {
public:
IRunData();
~IRunData();
public:
virtual void runData(TimePlay tp) = 0;
};
2.主窗口继承当前的接口回调类,并且实现回调函数
class MyMainWindow : public QMainWindow, public IRunData {
public:
void runData(TimePlay tp) override;
}
//数据回放接口实现
void MyMainWindow::runData(TimePlay time) {
//实现从数据库中读取数据,并且把数据放置到具体的实体中进行绘制
}
3.绘制数据,绘制各种战场要素
void MainCanvas::paintEvent(QPaintEvent *event) {
QgsMapCanvas::paintEvent(event);
DrawManager::getInstance()->paintEvent(event);
}
以上设计的关键步骤主要是,各个实体的中数据设置都是采用指针的形式实现,这样才能保证数据和显示的分离。
绘制的时候,通过指针获取到对应的内存中的数据,设置数据的时候,也是通过指针的形式在相应的内存中设置具体的内容。也就是说设置数据和显示数据都是通过同一块内存的,这样就可以了。
通过修改发现的确也是实现了,而且效率也是不错的。