www.mikrocontroller.net

Forum: PC-Programmierung Qt: Erste Schritte mit QGraphicsScene und QGraphicsView


Autor: Johnny B. (johnnyb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen

Wollte mal meine erste "App" für mein Symbian basiertes Handy von Nokia 
programmieren. Kenne mich zwar sehr gut in C für Mikrocontroller aus, 
aber C++ und Qt sind neu für mich. Jedenfalls läuft inzwischen schon 
einiges, aber komme mit QGraphicsScene und QGraphicsView überhaupt nicht 
klar.

Was ich machen will:
In einem balkenförmig angezeigten QGraphicsView soll als Hintergrund ein 
Farbverlauf rot...grün...rot erscheinen. Dann will ich darauf (im 
Vordergrund) einen Kreis einzeichnen um eine Stelle zu markieren.

Code:
Den Hintergrund habe ich folgendermassen hingekriegt und erscheint 
soweit wie ich es haben möchte:

Scene erstellen und zuweisen
QGraphicsScene *scene_color_bar;

scene_color_bar = new QGraphicsScene;
ui->graphicsView_color_bar->setScene(scene_color_bar);

Farbverlauf im Hintergrund
int width = ui->graphicsView_color_bar->width();

QLinearGradient gradient(-(width / 2), 0, (width / 2), 0);
gradient.setColorAt(0.000, Qt::red);
gradient.setColorAt(0.200, Qt::red);
gradient.setColorAt(0.383, Qt::green);
gradient.setColorAt(0.500, Qt::green);
gradient.setColorAt(0.833, Qt::red);
gradient.setColorAt(1.000, Qt::red);

QBrush Brush(gradient);
scene_color_bar->setBackgroundBrush(gradient);

Problem:
Wenn ich nun darauf den Kreis einzeichne, dann verschiebt sich der 
Hintergrund, bzw. wahrscheinlich der Bildausschnitt des Views.
QPen Pen;
Pen.setColor(Qt::blue);
Pen.setBrush(Qt::SolidPattern);

MarkerPos = 20; // Messwert
scene_color_bar->clear();
scene_color_bar->addEllipse(MarkerPos, 0, 10, 10, Pen, Qt::SolidPattern);

Eigentlich will ich, dass die "scene" genau so gross ist wie das "view" 
und wenn ich etwas zeichne, dass sich der Hintergrund nicht verschiebt.
In den Dokus steht zwar so einiges drin, aber ich verstehe den 
Zusammenhang und die verschiedenen Koordinatensysteme nicht.

Kann mir jemand einen Tipp geben, wie ich das hinbekomme?

Danke

Autor: Isch (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

es ist auf jeden Fall sinnvoll, wenn du zuerst einmal eine definierte 
Zeichenfläche erstellst. Also der "scene" eine für deine Anwendung 
sinnvolle Größe zuweist. Somit kannst du in einem festen 
Koordinatensystem zeichnen und die Darstellung in der "GrapphicsView" 
dann ggf. über die Transformationsmatrix anpassen.

Das Ganze sieht dann ungefähr so aus (Bild dazu im Anhang):
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QGraphicsView *view = new QGraphicsView(this);
    setCentralWidget(view);

    QGraphicsScene *scene_color_bar = new QGraphicsScene(0, 0, 500, 500);
    view->setScene(scene_color_bar);


    int width = scene_color_bar->width();

    QLinearGradient gradient(0, 0, width, 0);
    gradient.setColorAt(0.000, Qt::red);
    gradient.setColorAt(0.200, Qt::red);
    gradient.setColorAt(0.383, Qt::green);
    gradient.setColorAt(0.500, Qt::green);
    gradient.setColorAt(0.833, Qt::red);
    gradient.setColorAt(1.000, Qt::red);

    QBrush brush(gradient);
    scene_color_bar->setBackgroundBrush(brush);

    QPen Pen;
    Pen.setColor(Qt::blue);
    Pen.setBrush(Qt::SolidPattern);

    int MarkerPos = 250; // Messwert
    scene_color_bar->clear();
    scene_color_bar->addEllipse(MarkerPos, 250, 10, 10, Pen, Qt::SolidPattern);
}

Allerdings bin ich mir nicht wirklich sicher, was du genau erreichen 
möchtest.

Autor: Johnny B. (johnnyb)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hey vielen Dank, hast mir sehr geholfen!
Das Problem war wirklich, dass der "scene" nicht die gewünschte Grösse 
zugewiesen wurde.
Da es auch beim rotieren des Gerätes richtig angezeigt werden soll, habe 
ich es nun folgendermassen gelöst und wird im paintEvent abgehandelt:
int width = ui->graphicsView_color_bar->viewport()->geometry().width();
int height = ui->graphicsView_color_bar->viewport()->geometry().height();

scene_color_bar->setSceneRect(0, 0, width, height);

Um die Katze noch aus dem Sack zu lassen, habe ich noch ein Screenshot 
angefügt wo man sehen kann, was das ganze werden soll wenn es fertig 
ist...

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johnny B. schrieb:
> Um die Katze noch aus dem Sack zu lassen, habe ich noch ein Screenshot
> angefügt wo man sehen kann, was das ganze werden soll wenn es fertig
> ist...

Hmm, und für diesen kleinen Balken mit dem Klecks drin hast du extra 
eine QGraphicsView und eine QGraphicsScene verwendet? Das klingt aber 
auch nach dem berühmten mit-Kanonen-auf-Spatzen-Schuss.

Autor: Johnny B. (johnnyb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist mein erstes Qt Programm und QGraphicsView war das einzige aus 
der Toolbox von Qt Creator, was mir einigermassen angemessen schien um 
darin herumzuzeichnen.
Aber Du hast natürlich schon recht, um das Potential auch nur 
ansatzweise zu nutzen, sollte ich da schon noch was animieren und sich 
bewegen lassen.
Jedenfalls bin ich froh, dass es nun einigermassen so aussieht wie ich 
mir das gewünscht hatte und Geschwindigkeitsmässig kann ich auf dem 
Handy keine Performanceeinbussen feststellen.

Was könntest Du denn als einfachere Alternative empfehlen?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johnny B. schrieb:
> Das ist mein erstes Qt Programm und QGraphicsView war das einzige aus
> der Toolbox von Qt Creator, was mir einigermassen angemessen schien um
> darin herumzuzeichnen.
> Aber Du hast natürlich schon recht, um das Potential auch nur
> ansatzweise zu nutzen, sollte ich da schon noch was animieren und sich
> bewegen lassen.

QGraphicsScene ist vor allem gut geeignet, wenn du viele Objekte 
zeichnen und komfortabel in der Szene verwalten willst, mit Zoom und 
klickbaren Objekten u.s.w.

> Was könntest Du denn als einfachere Alternative empfehlen?

Von QWidget ableiten und den Kreis selber im paintEvent() malen. Das ist 
auch nicht schwierig.

Autor: Johnny B. (johnnyb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok danke, werde das beim nächsten Projekt mal genauer anschauen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.