[Qt-interest] custom QGraphicsLineItem dragging and changing position problem

franki franki at franki.eu.org
Tue Oct 12 22:35:10 CEST 2010


Hi all,

Let me start with explaining what I want to achieve.
I have horizontal line drawn on QGraphicsScene, outside scene there is QDial. 
Horizontal line represents temperature and is connected with QDial in the way 
that when I move this horizontal line with mouse up or down (ONLY, not right 
or left) the QDial should display properly calculated value (temp), and the 
other way round: when item is selected and user changes value of QDial, the 
line should be moved accordingly.
The first step is working fine for me, but there is problem with the "other 
way round". When I move the item with mouse, some let's say 100pixels up, and 
then I pres QDial to continue move item by changing QDial value the item is 
suddenly drawn in wrong place, roughly misplaced about the same value I moved 
it previously with mouse. I have checked that my calculations from 
coordinates to temperature and from temperature (on QDial) to coordinates on 
scene are correct, but somehow when I set new line with item setLine() after 
I have moved this item with mouse, the line is drawn in wrong place.
Some code extracted from files:

custom_item.h
class myGraphicsLineItem : public QObject, public QGraphicsLineItem
{
        Q_OBJECT
public:
        myGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2);
        ~myGraphicsLineItem();
        QVariant itemChange(GraphicsItemChange change, const QVariant &value);
	void setAbort(bool a);    // I'm setting a=true when I'm starting to change 
value of QDial and thus move item by calling item's setLine
}

//constructor
myGraphicsLineItem::myGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal 
y2): QGraphicsLineItem(x1,y1,x2,y2)

//itemChange function
QVariant myGraphicsLineItem::itemChange( GraphicsItemChange change, const 
QVariant & value) {
        if(abort) return QVariant(QPointF(0,0));
        if (change == ItemPositionChange) {
                QPointF newPos=value.toPointF();
                newPos.setX(0);
                emit newPositionSignal(newPos.toPoint().y());
                return newPos;
        }
        if(change == ItemSelectedChange) {
                if(value.toInt()==1) {
                        //selected
                        emit itemSelected(true);
                }
                else {
                        emit itemSelected(false);
                }
        }
        return QGraphicsItem::itemChange(change, value);
}

scene.cpp
itemStruct *item;

item.x1 item.y1 item.x2 item.y2 /are calculated from current QDial value/
item.item=new myGraphicsLineItem(item.x1,item.y1,item.x2,item.y2);
item.item->setFlag(QGraphicsItem::ItemIsSelectable,true);
item.item->setFlag(QGraphicsItem::ItemIsMovable,true);
scn->addItem(item.item); 
connect(item.item,SIGNAL(newPositionSignal(int)),this,SLOT(graphItemChanged(int))); 
connect(item.item,SIGNAL(itemSelected(bool)),this,SLOT(graphItemSelected(bool)));

function called by signal from customItem when item is selected
graphItemSelected(bool s) {
        if(s) {
                //selected
                tempDial->blockSignals(true);
                tempDial->setValue(prog_item[num].temp*10-50);
                tempDial->blockSignals(false); 
connect(tempDial,SIGNAL(valueChanged(int)),this,SLOT(moveSelectedItem(int)));
        }
}
function called by signal from customItem when item is moved, it changes value 
of QDial accordingly to item's position
graphItemChanged(int y) {
        tempDial->blockSignals(true);
        tempDial->setValue(some calculation from y to temp);
        tempDial->blockSignals(false);
}
function which is called by QDial with valueChanged signal, and should move 
item up or down.

moveSelectedItem(int temp) {
	item.y1=item.y2=/calculated coordinates from temp/;
       	item.item->setFlag(QGraphicsItem::ItemIsMovable,false);
	item.item->setAbort(true); //this I set true because of itemChange function 
from myGraphicsLineItem 
	item.item->setLine(item.x1,item.y1,item.x2,item.y2);
	item.item->blockSignals(false);
        item.item->setAbort(false);
	item.item->setFlag(QGraphicsItem::ItemIsMovable,true);
}

so in the last function when I setLine (after moving item with mouse) the line 
is drawn in wrong place despite the fact that item.y is calculated correctly.

To be honest I don't even know if I'm doing all this in right way?
Maybe someone has some more experience and knows a better way?
I'm using Qt 4.4 on debian lenny.

Best Regards
Marek



More information about the Qt-interest-old mailing list