Seite 1 von 2
Ein SVG Bild innerhalb eines GraphicsView per maus bewegen
Verfasst: 14. Mai 2007 15:31
von nibbel
Hallo,
ich habe ein SVG Bild mit qpaint erstellt, das in ein qpicture gehauen und das dann wiederrum in ein qlabel gelegt um das dann auf dem qwidget anzeigen zu lassen.
(Es geht bestimmt einfacher aber das ist mein erstes Qt Projekt und somit hoffe ich das jemand mir sagt wie es einfacher geht.)
Nun hab ich noch ein GraphicsView in meinem Qwidget liegen.
Das Qlabel lasse ich genau da drüber anzeigen. (Gibts ne möglichkeit das wirklich ins QGraphicsView zu legen?)
Also ich will nun das ich das label mit maus anklicken kann und dieses dann innerhalb des QGrahpicsView einfach fröhlich herum zu schieben ist.
Ne art drag and drop in einem fenster^^.
wer noch den code sehen will hier:
Code: Alles auswählen
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget window;
QGraphicsView *graphicsview = new QGraphicsView(&window);
graphicsview->setGeometry(QRect(10, 10, 620, 460));
QPicture picture;
QPainter painter;
painter.begin(&picture); // paint in picture
painter.drawEllipse(300,200, 80,70); // draw an ellipse
painter.end(); // painting done
picture.save("drawing.pic"); // save picture
QPicture picture2;
picture2.load("drawing.pic"); // load picture
QPainter painter2;
painter2.begin(&window); // paint in myWidget
painter2.drawPicture(300, 200, picture2); // draw the picture at (0,0)
painter2.end(); // painting done
QLabel *label=new QLabel(0, &window);
label->setGeometry(220,140, 101, 101);
label->setPicture(picture2);
window.setFixedSize(640,480);
window.show();
return app.exec();
}
Verfasst: 14. Mai 2007 19:40
von upsala
Code: Alles auswählen
void QGraphicsItem::setFlags ( GraphicsItemFlags flags )
Verfasst: 15. Mai 2007 10:34
von nibbel
Es wäre echt nett, wenn du mit ein Paar mehr informationen rausrückst.
Ich denke (ich hab das in qt noch nie gemacht), das dies der Kopf einer Funktion ist (eventuell auch methode).
Nur leider habe ich nicht den ansatz einer Idee wie ich das genau verstehen soll.
Auch nicht wie ich mit dem eigendlichen Code "des bewegens" anfangen kann.
Verfasst: 15. Mai 2007 12:23
von upsala
Hast du die Dokumentation zu dieser Funktion durchgelesen?
Verfasst: 15. Mai 2007 12:28
von upsala
Jetzt seh ich es erst, warum verwendest du QGraphicsView, aber kein QGraphicsScene und keine QGraphicsItems?
Verfasst: 15. Mai 2007 16:36
von nibbel
ich bekomme es einfach nicht hin in das graphicsitem eine svg datei zu binden.
Bzw ein svg bildchen in dem graphicsitem zu erstellen. (bessere variante)
Ich weiß auch nicht. Scheine heute auf dem schlauch zu stehen.
In Java mit swing hatte ich nie solche probs..
Vieleicht kannst du mir ja weiter helfen.
Verfasst: 15. Mai 2007 16:50
von upsala
Code: Alles auswählen
int main(int argc, const char *argv[]) {
QApplication app(argc, argv);
QGraphicsScene *scene=new QGraphicsScene();
QGraphicsView *view=new QGraphicsView();
view->show();
view->setScene(scene);
QGraphicsSvgItem *item=new QGraphicsSvgItem("/mein/item.svg");
scene->addItem(item);
item->setFlags(QGraphicsItem::ItemIsMovable);
return app.exec();
}
Verfasst: 15. Mai 2007 16:58
von franzf
QGraphicsSvgItem
GraphicsFramework ->
drag and drop
Lies es bitte GENAU, da steht alles drinnen was du wissen solltest...
// edit:
zu spät, upsala war schneller und netter

Verfasst: 16. Mai 2007 10:21
von nibbel
^^
Das ist mal ein luxus, bekomm ich gleich die ganze antwort.
Ich danke erstmal dafür.
Aber ich habe mir trotzdem die ganzen Sachen dazu (doku von trolltech) angeschaut.
Ein Problem hab ich aber noch.
Zum Verständnis, ich arbeite mit Eclipse unter Windows (gibt es was besseres?)
Also mir wird gesagt das QGraphicsSvgItem nicht definiert ist, aber ich habe ein include dafür gesetzt (sogar mal wegen rechtschreibfehler aus der Doku kopiert).
Auch habe ich nochmal in den Optionen meines Projektordners einen externen include Ordner aus dem QT verzeichnis gesetzt (Qt/include/QSVG Ordner)
In diesem Ordner gibt es auch eine 1Kb große QGraphicsSvgItem Datei
*edit:
Oder kann es sein das ich einen fehler beim erstellen meiner SVG habe?
Code: Alles auswählen
QPicture picture;
QPainter painter;
painter.begin(&picture); // paint in picture
painter.drawEllipse(0,0, 80,70); // draw an ellipse
painter.end(); // painting done
picture.save("drawing.svg"); // save picture
QGraphicsSvgItem *item=new QGraphicsSvgItem("drawing.svg");
Verfasst: 16. Mai 2007 10:46
von franzf
nibbel hat geschrieben:*edit:
Oder kann es sein das ich einen fehler beim erstellen meiner SVG habe?
Code: Alles auswählen
QPicture picture;
QPainter painter;
painter.begin(&picture); // paint in picture
painter.drawEllipse(0,0, 80,70); // draw an ellipse
painter.end(); // painting done
picture.save("drawing.svg"); // save picture
QGraphicsSvgItem *item=new QGraphicsSvgItem("drawing.svg");
Das stellt durchaus ein Problem dar, denn das Format, in dem ein QPicture abgespeichert wird, ist proprietär binär:
Doku hat geschrieben:A picture serializes painter commands to an IO device in a platform-independent format. They are sometimes referred to as meta-files.
Qt pictures use a proprietary binary format. Unlike native picture (meta-file) formats on many window systems, Qt pictures have no limitations regarding their contents. Everything that can be painted on a widget or pixmap (e.g., fonts, pixmaps, regions, transformed graphics, etc.) can also be stored in a picture.
SVGs generieren (also das xml-basierte Format) ist (wenn ich das recht verstehe) ein neues Feature von Qt-4.3. Auf die Schnelle bin ich da noch nicht so durchgestiegen, aber mal schaun
Ja, hier:
QSvgGenerator ist das was du suchst. Ist ein QPaintDevice, auf welches du QPainter los lassen kannst. Same as QPicture, mit setFileName() kannst du den Dateinamen angeben.
Grüße
Franz
// edit
JAAA
Code: Alles auswählen
#include <QGraphicsScene>
#include <QApplication>
#include <QGraphicsView>
#include <QSvgGenerator>
#include <QPainter>
#include <QGraphicsSvgItem>
int main(int argc, char **argv) {
QApplication app(argc, argv);
QGraphicsScene *scene=new QGraphicsScene();
QGraphicsView *view=new QGraphicsView();
view->show();
view->setScene(scene);
QSvgGenerator picture;
picture.setFileName( "drawing.svg" );
QPainter painter;
painter.begin(&picture); // paint in picture
painter.drawEllipse(0,0, 80,70); // draw an ellipse
painter.end(); // painting done
QGraphicsSvgItem *item=new QGraphicsSvgItem("drawing.svg");
scene->addItem(item);
item->setFlags(QGraphicsItem::ItemIsMovable);
return app.exec();
}
Und nicht vergessen, in deinem *.pro-file den Eintrag
QT += svg hinzuzufügen.
Verfasst: 16. Mai 2007 11:07
von franzf
Aber jetzt noch was anderes:
Für was brauchst du denn überhaupt ein QGraphicsSvgItem, wenn du das SVG-File erst im Programm erstellst? Schreib dir doch eine eigene Klasse, die du von
QGraphicsItem ableitest. Dann nur noch schnell
Code: Alles auswählen
QRectF QGraphicsItem::boundingRect () const;
void QGraphicsItem::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 );
überschreiben, und schon hast du ein für deine Zwecke passendes QGraphicsItem.
Oder war das nur zu Demo/Test-Zwecken? Dann kannst du das oben wieder vergessen (oder für spätere Anwendungen merken

)
Verfasst: 16. Mai 2007 11:17
von nibbel
Danke für die Hilfe.
Und jaein es ist schon zu testzwecken, ich brauche es aber später auch effektiv. Wie du das mit dem Überschreiben meinst, weis ich auch noch nicht genau.
Und zu meinem Prob, ich galube dir das es damit geht.
Nur leider hänge ich noch einen Fehlerpunkt dahinter fest.
Mein Eclpise findet anscheinend die Klasse #include <QGraphicsSvgItem>
nicht.
Denn das wird mir rot unterstrichen (QSvgGenerator auch).
Obwohl ich den path für die externen includes eingerichtet habe.
Weist du vieleicht woran das liegen kann?
*edit:
Auch wenn ich deinen Code direkt übernehme wird mir:
Code: Alles auswählen
#include <QSvgGenerator>
#include <QGraphicsSvgItem>
QSvgGenerator picture;
picture.setFileName( "drawing.svg" );
QGraphicsSvgItem *item=new QGraphicsSvgItem("drawing.svg");
item->setFlags(QGraphicsItem::ItemIsMovable);
Rot unterstrichen.
Ich bin mir sicher er findet die klassen einfach nicht.
Nur weis ich nicht wie ich das beheben kann.
Verfasst: 16. Mai 2007 11:28
von franzf
Eclipse arbeitet doch auch mit
qmake resp. dem qt-pro(ject)-file. In diesem solltest du eintragen
QT += svg.
Da ich selbst unter Linux mit kdevelop (für kleine Sachen auch gerne kate) arbeite, und eclipse in frühen Tagen zur Java-Programmierung angetestet habe (und sofort wieder verworfen

), kann ich da aber leider nicht mehr sagen.
Ansonsten gibt es (plattformübergreifend) noch:
Ich denke bei den links findest du sicher etwas, was dir zusagt.
Grüße
Franz
Verfasst: 16. Mai 2007 12:14
von nibbel
Danke dir, aber leider muss ich den Eclispe verwenden, da ich im voranlaufenden auch cvs und svn benutzen muss und das unterstützen die anderen alle nicht.
Eine möglichkeit wäre noch visual studio, aber das kostet nunmal geld...
Ich werde wohl solange suchen müssen, bis das problem gelöst ist.
Aber sobald ich es gefunden habe, werde ich es hier nochmal angeben.
Verfasst: 16. Mai 2007 12:24
von franzf
Wegen dem QGraphicsItem ableten, hier ein kleines Beispiel:
staritem.h
Code: Alles auswählen
#ifndef _STAR_ITEM_
#define _STAR_ITEM_
#include <QGraphicsItem>
class QRectF;
class StarItem : public QGraphicsItem
{
public:
StarItem( QGraphicsItem *parent = 0 ) : QGraphicsItem(parent) {}
// die beiden hier musst du implementieren
// um ein "gültiges" QGraphicsItem zu erhalten
void paint( QPainter *, const QStyleOptionGraphicsItem *, QWidget *widget=0 );
QRectF boundingRect() const;
};
#endif // _STAR_ITEM_
staritem.cpp
Code: Alles auswählen
#include "staritem.h"
#include <QPainterPath>
#include <QPainter>
#include <QLinearGradient>
#include <QRectF>
#include <math.h>
const float Pi = 3.14159f;
void StarItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
{
Q_UNUSED( option );
Q_UNUSED( widget );
QPainterPath starPath;
starPath.moveTo( 100, 50 );
for (int i = 1; i < 5; ++i) {
starPath.lineTo( 50 + 50 * cos(0.8 * i * Pi),
50 + 50 * sin(0.8 * i * Pi) );
}
starPath.closeSubpath();
QLinearGradient gradient(0, 0, 0, 100);
gradient.setColorAt(0.0, Qt::red);
gradient.setColorAt(1.0, Qt::yellow);
painter->setBrush(gradient);
painter->setRenderHint( QPainter::Antialiasing, true );
painter->drawPath( starPath );
}
QRectF StarItem::boundingRect() const
{
return QRectF( 0, 0, 100, 100 );
}
main.cpp
Code: Alles auswählen
#include "staritem.h"
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QApplication>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QGraphicsScene *scene=new QGraphicsScene();
QGraphicsView *view=new QGraphicsView();
view->setScene(scene);
StarItem *item = new StarItem;
item->setFlags(QGraphicsItem::ItemIsMovable);
scene->addItem(item);
view->show();
return app.exec();
}
Viel Spaß damit
Grüße
Franz