Rysowanie po QGraphicsView



  • Witam!

    Chciałbym się was zapytać czy mój tok myślenia jest dobry i co mogę zrobić aby zrealizować zamierzony efekt. Mam QGraphicsView, do którego ładuje zdjęcie z dysku a następnie powinienem móc myszką na tym zdjęciu zaznaczać pewne kluczowe punkty - markery. W tym celu stworzyłem sobie nową klasę pt. Marker, w której tworze obszar (nową scenę) dla myszki i dodaje ją poleceniem addWidget do layoutu dla QGraphicsView, jednak nie potrafię sobie poradzić z tym aby do tej klasy przekazać już istniejącą scenę z obrazem, na którym będzie można zaznaczyć tylko i wyłącznie dwa punkty, i odczytać ich współrzędne.

    Moja klasa Marker.cpp zawierająca konstruktor domyślny który działa (bo nakłada nową scenę) i konstruktor który dostaje scenę ale nie potrafi jej użyć.
    @#include "mainwindow.h"
    #include "marker.h"
    #include <QPointF>
    #include <QMessageBox>
    #include <QGraphicsView>
    #include <QGraphicsScene>

    Marker::Marker(QWidget *parent) :
    QGraphicsView(parent)
    {
    scena = new QGraphicsScene();
    this->setSceneRect(50, 50, 320, 320);
    this->setScene(scena);
    }

    Marker::Marker(QGraphicsScene scenaDlaMyszy, QWidget *parent) :
    QGraphicsView(parent)
    {
    scena.update(scenaDlaMyszy);
    this->setSceneRect(0, 0, 421, 421);
    this->updateScene(scena);
    }

    Marker::~Marker()
    {

    }

    void Marker::mousePressEvent(QMouseEvent * e)
    {
    int i = 0;
    if(i <= 2)
    {
    double rad = 1;
    QPointF punkt = mapToScene(e->pos());
    scena->addEllipse(punkt.x()-rad, punkt.y()-rad, rad5.0, rad5.0, QPen(), QBrush(Qt::SolidPattern));
    i += 1;
    }
    }@
    W tej chwili wygląda to tak że po załadowaniu obrazu do tej kontrolki nakładany jest na niego kwadrat (nowa scena tworzona w klasie Marker) w którym można zaznaczać punkty.

    Kod w pliku okna głównego który wypełnia QGraphicsView:
    @nazwaZdjecia1 = QFileDialog::getOpenFileName(this, tr("Otwórz plik"), "C:/", tr("Obrazy (*.jpg *.png *.bmp)"));
    QFile ladowanyPlik(nazwaZdjecia1);
    sciezka1 = ladowanyPlik.fileName();
    if(!sciezka1.isEmpty()){
    QImage obraz(sciezka1);
    obraz.scaled(QSize(421,421),Qt::IgnoreAspectRatio,Qt::FastTransformation);
    update();
    resize(421, 421);
    QGraphicsScene *scena = new QGraphicsScene(ui->graphicsViewZdjecie1);
    QPixmap mapaPikseli(nazwaZdjecia1);
    scena->addPixmap(mapaPikseli);
    QGridLayout *oknoObrazu1 = new QGridLayout(ui->graphicsViewZdjecie1);
    oknoObrazu1->addWidget(new Marker()); //opcja działająca ale niewłaściwie
    //oknoObrazu1->addWidget(new Marker(scena)); //opcja niedziałająca z powodu braku sceny
    ui->graphicsViewZdjecie1->setScene(scena);
    ui->graphicsViewZdjecie1->fitInView(scena->itemsBoundingRect(),Qt::KeepAspectRatio);
    ui->graphicsViewZdjecie1->show();
    }@
    Kod pliku nagłówkowego klasy Marker:
    @#ifndef MARKER_H
    #define MARKER_H

    #include <QGraphicsView>
    #include <QGraphicsScene>
    #include <QGraphicsEllipseItem>
    #include <QMouseEvent>

    class Marker : public QGraphicsView
    {
    Q_OBJECT

    public:
    explicit Marker(QWidget *parent = 0);
    explicit Marker(QGraphicsScene scenaDlaMyszy, QWidget *parent = 0);
    ~Marker();

    private slots:
    void mousePressEvent(QMouseEvent * e);

    private:
    QGraphicsScene *scena;
    };

    #endif // MARKER_H@
    Czy idąc tym tokiem myślenia jest możliwość odczytania współrzędnych nanoszonych punktów względem obrazu i co muszę uczynić albo jak się doedukować aby osiągnąć takie założenia?



  • Trochę przebudowałem swój kod w oparciu o to aby sama koncepcja przekazywania sceny nie stwarzała późniejszych problemów stworzyłem nową klasę abstrakcyjną gdzie przekazuje pixmape a nie scene i tam oprogramowałem zdarzenia związane z przyciskami myszy a samą klase dodaje jako Item do komponentu QGraphicsView tak aby nie nakładać nowych scen na siebie jak to było w poprzednim przypadku, ale - no właśnie - ale nie chce mi to zadziałać poprawnie, mimo że kod wydaje się być ok.

    Kod w głównym formie:
    @QGraphicsScene *scena = new QGraphicsScene(ui->graphicsViewZdjecie1);
    MarkerEditor *marker = new MarkerEditor();
    QPixmap mapaPikseli(nazwaZdjecia1);
    marker->setPixmap(mapaPikseli);
    scena->addItem(marker);@

    Kod obsługujący zdarzenie zwolnienia klawisza myszy w obszarze QGraphicsView, który znajduje się na formie głównym i zawiera wyświetlone już zdjęcie - czyli chcemy stworzyć czerwona kropkę na zdjęciu:
    @QRectF pozycjaKropki(e->pos(), QSizeF(2,2));
    pozycjaKropki.translate(-1,-1);
    QGraphicsEllipseItem *kropka = new QGraphicsEllipseItem(pozycjaKropki, this);
    kropka->setBrush(QBrush(Qt::red));@

    Jakieś pomysły? co jest źle?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.