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_OBJECTpublic:
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?