By modifying Qt
's Diagram Scene sample, I want my window to display an overlay object when a user clicks on a region that's described by GraphicalScene
(original sample shows instead QPolygon
). In the following code I'm using QPixmap
. However nothing appears when the region is clicked. mousePressEvent
passes reasonable positions where clicked. Appreciate your help.
diagramScene.cpp:
#include <iostream>
#include <QtGui>
#include <QPixmap>
#include "pkg/diagramscene.h"
#include "pkg/arrow.h"
DiagramScene::DiagramScene(QMenu *itemMenu, QObject *parent)
: QGraphicsScene(parent)
{
myItemMenu = itemMenu;
myMode = MoveItem;
myItemType = DiagramOverlayPixmapItem::Overlay;
}
void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
if (mouseEvent->button() != Qt::LeftButton) return;
DiagramOverlayPixmapItem *item;
switch (this->myMode) {
case InsertItem: {
const std::string tmpImgPathBase = "~/images/";
std::string overlayObj = tmpImgPathBase + "overlayObj.png";
QPixmap *img = new QPixmap(QString(overlayObj.c_str()));
item = new DiagramOverlayPixmapItem(myItemType, myItemMenu, img);
item->setPos(mouseEvent->scenePos());
this->addPixmap(item->pixmap()); // QGraphicsScene::addPixmap.
this->update(); // Expecting these parts would do the work..
}
break;
default:
;
}
QGraphicsScene::mousePressEvent(mouseEvent);
}
diagramOverlayPixmapItem.cpp:
#include <iostream>
#include <QtGui>
#include "pkg/arrow.h"
#include "pkg/diagramOverlayPixmapItem.h"
DiagramOverlayPixmapItem::DiagramOverlayPixmapItem(DiagramType diagramType, QMenu *contextMenu, QPixmap *img, QGraphicsItem *parent, QGraphicsScene *scene)
: QGraphicsPixmapItem(*img, parent)
{
myDiagramType = diagramType;
myContextMenu = contextMenu;
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
}
void DiagramOverlayPixmapItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
scene()->clearSelection();
setSelected(true);
myContextMenu->exec(event->screenPos());
}
QVariant DiagramOverlayPixmapItem::itemChange(GraphicsItemChange change,
const QVariant &value)
{
if (change == QGraphicsItem::ItemPositionChange) {
foreach (Arrow *arrow, arrows) {
arrow->updatePosition();
}
}
return value;
}
This thread is similar (though it's in python
) but not giving me an idea.
"~"
isn't a valid path. This is a shell expansion. Replace it with:
QDir::homePath()
which returns a QString
of the current user's home directory. The documentation says:
Under non-Windows operating systems the HOME environment variable is used if it exists [...]
By the way, why are you using std::string
? You should use QString
in Qt applications.
You could also use the QDir
path building mechanism by saying:
QDir tmpImgPathBase = QDir::home(); //home() returns a QDir, homePath() a QString
tmoImgPathBase.cd("images"); //navigate to relative directory
QString overlayObj = tmoImgPathBase.filePath("overlayObj.png"); //file in direct.
QPixmap *img = new QPixmap(overlayObj);
Note that you also should not overuse pointers in C++. The pixmap doesn't need to be a pointer (which you never delete here, causing memory leaks!):
QPixmap img = QPixmap(overlayObj);
item = new DiagramOverlayPixmapItem(myItemType, myItemMenu, img);
and
// I removed the asterisk at both the argument img and the
// forwarding to the constructor of QGraphicsPixmapItem.
DiagramOverlayPixmapItem::DiagramOverlayPixmapItem(DiagramType diagramType, QMenu *contextMenu, QPixmap img, QGraphicsItem *parent, QGraphicsScene *scene)
: QGraphicsPixmapItem(img, parent)
{
...
}