然后我们写一下void TsfunGraphicsItem::itemsUpdate()函数,其实首先我们应该清空NodeGraItem列表:
for(int i = 0;i < NdGraItemlist.count();i++){
scene()->removeItem(NdGraItemlist[i]);
delete NdGraItemlist[i];
}
NdGraItemlist.clear();
然后重新把NodeXmlItemList里面的元素生成新的图形项(方法和构造函数中的完全一样,这里就不再列举了),然后再显示:
//把这些东西根据坐标都画出来。
for (int i = 0;i < NdGraItemlist.count();i++) {
int w = tfgraItemMargin.leftToBoundary() + NdGraItemlist[i]->currentPos*paintWidth;
int h = tfgraItemMargin.topToBoundary() + paintHeight*(1-NdGraItemlist[i]->opacity);
NdGraItemlist[i]->setPos(w,h);
NdGraItemlist[i]->setZValue(1000000);
scene()->addItem(NdGraItemlist[i]);
}
提一句,因为我们全都设置完以后View会自动调用一次resizeEvent,然后里面所有的函数都会进行调用,所以其实我们在构造函数中可以不进行任何添加操作,而是全都放在update里面,反正resizeEvent还要重新都调用一次~
这说明,存在某些一开始就一定会执行的事件的时候,我们可以把初始化和事件每次都要执行的程序变成一个程序,而不是分开。
画线函数同理,先删掉线列表里面原来的元素,然后新添加新的元素:
void TsfunGraphicsItem::ligatureUpdate() {
for (int i = 0;i < ligatureitemlist.count();i++) {
scene()->removeItem(ligatureitemlist[i]);
delete ligatureitemlist[i];
}
ligatureitemlist.clear();
for (int i = 0;i < NdGraItemlist.count() - 1;i++) {
int w1 = tfgraItemMargin.leftToBoundary() + NdGraItemlist[i]->currentPos*paintWidth;
int h1 = tfgraItemMargin.topToBoundary() + paintHeight*(1 - NdGraItemlist[i]->opacity);
int w2 = tfgraItemMargin.leftToBoundary() + NdGraItemlist[i + 1]->currentPos*paintWidth;
int h2 = tfgraItemMargin.topToBoundary() + paintHeight*(1 - NdGraItemlist[i + 1]->opacity);
ligatureitem = new LigatureForNodesGraItem;
ligatureitem->setLine(w1, h1, w2, h2);
ligatureitemlist.append(ligatureitem);
ligatureitemlist[i]->setZValue(100000);
scene()->addItem(ligatureitemlist[i]);
}
}
以及两个函数:
void TsfunGraphicsItem::setWidthHeight(int width, int height)
{
this->width = width;
this->height = height;
setRect(0,0,width,height);
}
void TsfunGraphicsItem::setPaintable(int width, int height)
{
paintWidth = width;
paintHeight = height;
}
这两个哈数,一个是设置矩形大小的,一个是设置可绘制区域的边界的。在View构造函数里面对其进行设置:
//设置小圆点显示控件
tsfungraItem = new TsfunGraphicsItem;
tsfungraItem->tfgraItemMargin = dataGrid->gridMargin;//设置区域
//不能在TsfunGraphicsItem构造函数里面直接使用scene()函数,因为这个时候还没有加入到场景中。
scene->addItem(tsfungraItem);
我们把之前在Grid里面设置的Margin赋值给 tsfungraItem ,因为它们的边界(可划线区域的左起点和上起点)都是一样的。注意宽度是计算以后再调整的。然后在View的resizeEvent函数里面继续添加
//因为这个计算的区域是圆点运动的区域(不包括坐标显示区),所以可以直接传递给图形项对象
tsfungraItem->setPaintable((dataGrid->lineWidthEnd-dataGrid->lineWidthStart),
(dataGrid->lineHeightEnd - dataGrid->lineHeightStart));
tsfungraItem->setWidthHeight(width(), height() - 2 - viewMargin.bottomToBoundary());
//最后进行更新,因为只是resize,所以不必更新渲染引擎了。
tsfungraItem->itemsUpdate();
tsfungraItem->ligatureUpdate();
我们把可绘制区域的宽度用grid生成的起点和终点差值来生成。现在,你编译完以后,可以看到初始小点已经可以显示在上面了,你移动它以后,松开鼠标的时候会保持在当前位置,这是因为每次更新都是根据原始的xml结构生成的,在itemChange里面你已经修改了原始数据。我们需要在接下来的程序中想办法能够实时传递小圆点运动的效果。