Файл изображения QPixmap не отображается в QGraphicsScene

Изменив образец сцены диаграммы Qt, я хочу, чтобы мое окно отображать объект наложения, когда пользователь щелкает область, описанную GraphicalScene (вместо этого в исходном образце отображается QPolygon). В следующем коде я использую QPixmap. Однако при нажатии на область ничего не появляется. mousePressEvent пропускает разумные позиции, где нажимали. Ценю твою помощь.

диаграммаScene.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);
}

диаграммаOverlayPixmapItem.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;
}

Эта тема похожа (хотя и в python), но не дает мне представления .


person IsaacS    schedule 17.07.2012    source источник
comment
Вы проверили, успешно ли открыт файл?   -  person Blood    schedule 18.07.2012
comment
@Blood, если вы имеете в виду «открыто» как «скомпилировать» или «запустить», то да. Он запускается, открывает окно, область, показанная QGraphicsScene, кликабельна и возвращает позицию щелчка.   -  person IsaacS    schedule 18.07.2012
comment
Нет, я упоминаю ваш QPixmap - QPixmap *img = new QPixmap(QString(overlayObj.c_str()));   -  person Blood    schedule 18.07.2012
comment
Путь @Blood к файлу правильный (я копирую и вставляю из другого кода .cpp, который работает), но я не уверен, что эта конкретная программа успешно открывает данный файл, поскольку я не вижу его в своем графическом интерфейсе (во всяком случае, чтобы убедиться, что QPixmap успешно открывает?).   -  person IsaacS    schedule 18.07.2012
comment
если img != NULL, то растровое изображение было успешно загружено   -  person Blood    schedule 18.07.2012
comment
Спасибо, и да, экземпляр QPixmap создан.   -  person IsaacS    schedule 18.07.2012
comment
@Blood Вы имеете в виду: !img->isNull(), потому что img не может быть NULL после новой операции.   -  person leemes    schedule 18.07.2012
comment
На самом деле, да, может, если он не получит место в памяти новым, он будет установлен на byll.   -  person Blood    schedule 18.07.2012


Ответы (1)


"~" недопустимый путь. Это расширение оболочки. Замените его на :

QDir::homePath()

который возвращает QString домашнего каталога текущего пользователя. В документация говорит:

В операционных системах, отличных от Windows, используется переменная среды HOME, если она существует [...]


Кстати, а почему вы используете std::string? Вы должны использовать QString в приложениях Qt.

Вы также можете использовать механизм построения пути QDir, сказав:

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);

Обратите внимание, что вы также не должны злоупотреблять указателями в C++. Пиксмап не обязательно должен быть указателем (который вы никогда не удаляете здесь, вызывая утечку памяти!):

QPixmap img = QPixmap(overlayObj);
item = new DiagramOverlayPixmapItem(myItemType, myItemMenu, img);

и

// 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)
{
    ...
}
person leemes    schedule 17.07.2012
comment
Применение всех ваших предложений (т.е. использование QDir, замена std::string на QString, удаление ненужного указателя) решено. Возможно, использование ~ в качестве пути было правонарушителем, как вы предложили. Спасибо! - person IsaacS; 18.07.2012
comment
Конечно, использование ~ было ошибкой, остальное - только стиль (но подобная утечка памяти может быть опасной в большинстве ситуаций) - person leemes; 18.07.2012