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


von Johnny B. (johnnyb)


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
1
QGraphicsScene *scene_color_bar;
2
3
scene_color_bar = new QGraphicsScene;
4
ui->graphicsView_color_bar->setScene(scene_color_bar);

Farbverlauf im Hintergrund
1
int width = ui->graphicsView_color_bar->width();
2
3
QLinearGradient gradient(-(width / 2), 0, (width / 2), 0);
4
gradient.setColorAt(0.000, Qt::red);
5
gradient.setColorAt(0.200, Qt::red);
6
gradient.setColorAt(0.383, Qt::green);
7
gradient.setColorAt(0.500, Qt::green);
8
gradient.setColorAt(0.833, Qt::red);
9
gradient.setColorAt(1.000, Qt::red);
10
11
QBrush Brush(gradient);
12
scene_color_bar->setBackgroundBrush(gradient);

Problem:
Wenn ich nun darauf den Kreis einzeichne, dann verschiebt sich der 
Hintergrund, bzw. wahrscheinlich der Bildausschnitt des Views.
1
QPen Pen;
2
Pen.setColor(Qt::blue);
3
Pen.setBrush(Qt::SolidPattern);
4
5
MarkerPos = 20; // Messwert
6
scene_color_bar->clear();
7
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

von Isch (Gast)


Angehängte Dateien:

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):
1
MainWindow::MainWindow(QWidget *parent)
2
    : QMainWindow(parent)
3
{
4
    QGraphicsView *view = new QGraphicsView(this);
5
    setCentralWidget(view);
6
7
    QGraphicsScene *scene_color_bar = new QGraphicsScene(0, 0, 500, 500);
8
    view->setScene(scene_color_bar);
9
10
11
    int width = scene_color_bar->width();
12
13
    QLinearGradient gradient(0, 0, width, 0);
14
    gradient.setColorAt(0.000, Qt::red);
15
    gradient.setColorAt(0.200, Qt::red);
16
    gradient.setColorAt(0.383, Qt::green);
17
    gradient.setColorAt(0.500, Qt::green);
18
    gradient.setColorAt(0.833, Qt::red);
19
    gradient.setColorAt(1.000, Qt::red);
20
21
    QBrush brush(gradient);
22
    scene_color_bar->setBackgroundBrush(brush);
23
24
    QPen Pen;
25
    Pen.setColor(Qt::blue);
26
    Pen.setBrush(Qt::SolidPattern);
27
28
    int MarkerPos = 250; // Messwert
29
    scene_color_bar->clear();
30
    scene_color_bar->addEllipse(MarkerPos, 250, 10, 10, Pen, Qt::SolidPattern);
31
}

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

von Johnny B. (johnnyb)


Angehängte Dateien:

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:
1
int width = ui->graphicsView_color_bar->viewport()->geometry().width();
2
int height = ui->graphicsView_color_bar->viewport()->geometry().height();
3
4
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...

von Rolf Magnus (Gast)


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.

von Johnny B. (johnnyb)


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?

von Rolf Magnus (Gast)


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.

von Johnny B. (johnnyb)


Lesenswert?

Ok danke, werde das beim nächsten Projekt mal genauer anschauen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.