PDA

View Full Version : QGraphicsTextItem subclass & QGraphicsScene



ttvo
29th August 2009, 00:06
Hi all,

So I want to create a text item with bounding box and a few rectangular ports representing inputs/outputs to my text item. Then I also need the ability to connecting the port from one node to another.

I subclass QGraphicsTextItem so that it also contains some QGraphicsRectItem to be able to create nodes as in this picture
3628

I added


Node *item = new Node(m_selectedJFIName.c_str(), 2);
addItem(item);


in my QGraphicsScene. There are 2 problems
1) when I drag the Node within the scene, there seems to an issue with refresh, that is, the rectangles didn't move to the new position nicely, there are some blur lines until the scene refresh
2) I followed the Diagram scene example to implement mouseReleaseEvent event to draw a QGraphicsLineItem from a rectangle of node # 1 to a rectangle in node # 2, but the call of
QList<QGraphicsItem *> startItems = items(m_line->line().p1());

within the scene mouseReleaseEvent didn't contain the rectangle from noe # 1, same thing with the
QList<QGraphicsItem *> endItems = items(m_line->line().p2()); call

I guess it's due to the fact that I never call addItem on the rectangles? Please help as I have tried various things, but nothing seems to work thus far. thanks.



class Node : public QGraphicsTextItem
{
public:
Node(std::string text, int nports=2, QGraphicsItem *parent = 0);
virtual ~Node();

QRectF boundingRect() const;
QPainterPath shape() const;

void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);

private:
QGraphicsTextItem *m_text;
QList<QGraphicsRectItem *> m_inports;
QGraphicsRectItem *m_outport;
};



Node::Node(std::string text, int nports, QGraphicsItem *parent)
: QGraphicsTextItem(text.c_str(), parent)
{
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
int tick = boundingRect().width()/(nports+1);
for (int i=0; i<nports; ++i) {
QGraphicsRectItem *iport = new QGraphicsRectItem(QRectF((i+1)*tick, -10, 10, 10));
iport->setZValue(1);
m_inports.push_back(iport);
}
m_outport = new QGraphicsRectItem(QRectF(40, 27, 10, 10));
m_outport->setZValue(1);
}

Node::~Node()
{
while (!m_inports.isEmpty())
delete m_inports.takeFirst();
if (m_outport) {
delete m_outport;
m_outport = 0;
}
if (m_text) {
delete m_text;
m_text = 0;
}
}

QRectF Node::boundingRect() const
{
const QRectF t = QGraphicsTextItem::boundingRect();
QRectF t2;
t2.setHeight(t.height()+10);
t2.setWidth(t.width()+10);
return t2;
}

QPainterPath Node::shape() const
{
const QRectF t = QGraphicsTextItem::boundingRect();
QRectF t2;
t2.setHeight(t.height()+10);
t2.setWidth(t.width()+10);
QPainterPath path;
path.addEllipse(t2);
return path;
}

void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->setPen(QPen(Qt::black, 1));
painter->drawRoundedRect(0, 0, boundingRect().width(),
boundingRect().height(), 5, 5);
QGraphicsTextItem::paint(painter, option, widget);
int count = m_inports.count();
for (int i=0; i<count; ++i) {
m_inports.at(i)->paint(painter, option, widget);
}
m_outport->paint(painter, option, widget);
}

Lykurg
29th August 2009, 06:28
1) when I drag the Node within the scene, there seems to an issue with refresh, that is, the rectangles didn't move to the new position nicely, there are some blur lines until the scene refresh
It's because the items you create in Node aren't children of Node. And blur lines occurs when the bounding rect is not correct.

ttvo
30th August 2009, 15:46
I made the QGraphicsRectItem to be children of the text item and modified the paint method according, i now can draw and move the node fine. Thanks, Lykurg.

Then I tried to follow the Diagram Scene example to draw a QGraphicsLineItem between ports, not nodes, I passed the start and end nodes to the arrow. But the arrow's paint method somehow ends up drawing the arrow connecting the topleft of the 2 nodes, not at the ports.

1) Any suggestions on how to get the right position and to draw the arrow connecting the ports, NOT nodes
2) I also need to have code ignoring clicks between two nodes

Thanks in advance