Seite 1 von 1

QGraphicsView lässt sich nicht darstellen

Verfasst: 24. November 2009 12:49
von ZSchneidi
Hey, ich probiere gerade ein GraphicsView zum laufen zu bringen.

Zu Beginn, wie immer, was ganz simples um das System kennen zu lernen.

Ich arbeite mit dem QTCreator in der main.cpp

hab ich es mit :

Code: Alles auswählen

    QGraphicsScene scene;
    scene.addText("hallo welt!");

    QGraphicsView view;
    view.setScene(&scene);
    view.show();
das lief auch wie erwartet, ein kleines Fenster mit dem View öffnet sich.

Dann hab ich das wieder aus der main.cpp herausgenommen und in eine Klasse eingebunden. Der selbe code, aber es läuft nicht mehr.
Ich seh nur die zu programmstart, wieder das selbe Fenster aufgebaut wird, es verschwindet aber sofort wieder.
Ich will das ganz auch nicht im extra Fenster haben, sondern in meinem MainWindow. Dafür hab ich mir ein GraphicsView Widget angelegt, auf dass mein View verweisen sollte.

Code: Alles auswählen

    QGraphicsScene scene;
    scene.addText("hallo welt!");

    QGraphicsView view;
    view.setScene(&scene);
    view.setViewport(ui->graphview);
    view.show();
Statt des Fensters soll ja jetz, das bereits im UI enthaltene, GraphicsView verwendet werden. Aber ein ähnlicher fehler, das View verschwindet nach dem Aufbau direkt wieder.

Was kann es damit auf sich haben ?
Wieviel kann man da bei so kurzem Inhalt falsch machen ?

Wäre nett, wenn ihr mir da auf die Sprünge helfen könntet.

Verfasst: 24. November 2009 13:40
von upsala
Lebenszyklus von Variablen => C++-Grundlagen & Forumssuche

Verfasst: 24. November 2009 14:45
von ZSchneidi
? Ich glaube kaum, dass es auf den Lebenszyklus zurückzuführen ist, wenn allein der GraphicsView diese Probleme aufweist, alles andere bleibt ja wie es soll solange auf dem Schirm, bis ich auf Beenden klicke.

Wenn ich es in der main.cpp aufmache bliebt es ja auch solange, bis ich manuell beende. Nur in der Klasse nicht und ich wüsste nicht, dass ich die entsprechende objekte irgendwo wieder zerstöre, sont würde alles andere ja auch flöten gehen.

Also das sollte wohl eher weniger das Problem sein.

Verfasst: 24. November 2009 14:56
von upsala
Dann liefere mehr Code. Das was bis jetzt da ist, läßt nur eine Folgerung zu.

Verfasst: 24. November 2009 15:23
von ZSchneidi
Ok, wie gewünscht.

Code: Alles auswählen

#include <QApplication>
#include <QGraphicsEllipseItem>
#include <QGraphicsScene>
#include <QGraphicsView>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainGame w;

    QGraphicsScene scene;
    scene.addText("hallo welt!");

    QGraphicsView view;
    view.setScene(&scene);
    view.show();

    w.show();
    return a.exec();
}
Das ist die Variante in der main. Die läuft wie man es erwarten würde.

Und die zweite Variante, die nicht so läuft, wie ich es erwartet hatte.
Ich zweifle zwar etwas an mir selbst, aber ich denke nicht, dass ich hier irgendwo den abbruch des graphicview veranlasse.

main.cpp

Code: Alles auswählen

#include <QtGui/QApplication>
#include "maingame.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainGame w;

    w.show();
    return a.exec();
}
Klasse

Code: Alles auswählen

#include "maingame.h"
#include "ui_maingame.h"
#include <QApplication>
#include <QGraphicsEllipseItem>
#include <QGraphicsScene>
#include <QGraphicsView>

MainGame::MainGame(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainGame)
{
    ui->setupUi(this);

    QGraphicsScene scene;
    scene.addText("hallo welt!");

    QGraphicsView view;
    view.setScene(&scene);
    view.show();

}

MainGame::~MainGame()
{
    delete ui;
}
Beide Fenster scheinen sich aufzubauen. Einmal das UI selbst und das angeforderte View, aber das View geht halt sofort wieder zu.

Ich hoffe das ist einigermaßen nachvollziehbar.

Verfasst: 24. November 2009 15:38
von upsala
Sicher. Das bestätigt meine oben geäußerte Vermutung.

Verfasst: 24. November 2009 16:00
von AuE
Deine View is so schnell wieder weg das du sie gar net sehen kannst.... Entweder nimmst membervariablen oder legst dir Pointer für deine View an.

Im ersten Bsp funzt es nur da du quasi die mainloop nicht verlässt, ergo die variablen noch leben.
Im C'tor bist so schnell durch das du es nur nicht sehen kannst !

Verfasst: 24. November 2009 16:39
von ZSchneidi
Ok, jetz bin ich ein wenig verwirrt.
Was den Lebenszyklus angeht, war ich eigentlich der meinung, dass ich das verstanden hätte.

Ich habe jetzt noch ne kleine änderung vorgenommen.

Ich habe die instaziierung der zwei objekte in den Header ausgelagert.
Jetzt bleibt das fenster auch auf, da verstehe ich momentan den zusammenhang noch nicht ganz. Warum bleibt das Fenster jetzt plötzlich auf, nur weil ich die Objekte im Header erzeuge ?

Das zeigt mir an sich nur, dass ich doch nicht so falsch lag.
Ich hab bisher noch nicht gelesen, dass der lebenszyklus davon abhängt ob ich ein objekt im Header oder direkt in der Source erzeuge.
Falls dem so ist, bitte ich um einen kurzen Tipp zu dem thema, aus meiner Lektüre hier ging das nicht hervor.

Neues Problem:

Code: Alles auswählen

MainGame::MainGame(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainGame)
{
    ui->setupUi(this);

    scene.addText("hallo welt!");

    view.setScene(&scene);
    view.setViewport(ui->gameview);
    view.show();

}
Wie gesagt, die objekte erzeuge ich jetzt im Header. Zusätzlich möchte ich das View in einem definierten Viewport laufen lassen. Das widget verschwindet aber im UI, stattdessen bekomme ich wieder ein externes Fenster aufgebaut, dass allerdings etwas unerwartet gestalltet ist.

Hey, AuE das mit der mainloop hatte ich schon im verdacht.
Aber ich war der Meinung, dass ich die mainloop der qt-app erst verlasse, wenn ich dem Programm den Befehl zum schließen gebe.

Ich bin mir eigentlich sicher gewesen, dass die instaziierung von view, mir eine entsprechende membervariable anlegt. Du darfst mir gern berichtigen

Ich hab es jetzt auch mal mit einem Pointer versucht, greife jetzt also über den Pointer auf die membermethode von view zu. Das absurde is dabei, dass das sogar fast schon funktioniert, der viewport wird mir zwar ganz klein in ne Ecke gequetscht, aber das is nen anderes Thema.

Wo liegt da jetzt bitte der Unterschied zwischen dem Zugriff auf die Methoden von view direkt über die instanz und den zugriff über einen Pointer ?
Das kann doch nich an mir liegen ? Ich mein ich hab das in anderen Programmen bischer ähnlich gemacht und das lief immer, nur die Views machen mir grad so ne Probleme.

Verfasst: 24. November 2009 17:02
von AuE
Wenn wir uns dein altes Programm ansehen:

Code: Alles auswählen

    : QMainWindow(parent), ui(new Ui::MainGame) 
{ 
    ui->setupUi(this); 

    QGraphicsScene scene; 
    scene.addText("hallo welt!"); 

    QGraphicsView view; 
    view.setScene(&scene); 
    view.show(); 

}
Verlässt du den Ctor nach show. Die Variablen view und scene gibt es nach der geschweiften Klammer zu nicht mehr!
Anders wäre es wenn du Variablen hier als Pointer mit new anlegst!
Die würden länger Leben-nämlich bis du Sie löschst! (das geschieht in dem alten Code bei "}")

Objekte im Header leben klar länger!!! Es sind Membervariablen die mit der Klasse Ihre Lebensdauer gemeinsam haben. In deinen neuen Code leben scene und view eben genauso lang wie auch dein UI lebt (also so wie du es haben magst)

Pointer sind in dem Fall die besser Lösung. Ich empfehle mal lektüre zu den Themen Lebensdauer von Variablen und Stack/Heap und wo welche variablen gespeichert/erzeugt werden!

Verfasst: 24. November 2009 17:43
von ZSchneidi
Ok, das war schon hilfreich. Geb dir auch recht, das hätte ich selbst wissen müssen. Thema Lebensdauer ist mir klar, auch wenns jetz nicht so aussieht.
Hatte nur nen Denkfehler beim Konstruktor, da hab ichs einfach nicht gesehen. Aber deine erläuterung war ganz gut, irgendwie ist meine Lektüre hier bei dem Thema sehr sparsam, mit erläuterungen.

Rein logisch hätte ich es aber wissen müssen, mal wieder so nen Aussetzer.

Stack/Heap guck ich mir mal an.

Oh man das war jetz keine glanzleistung von mir ^^
Ich werd das mal überschlafen und morgen nochmal druchdenken.

Danke erstmal

Verfasst: 9. März 2010 20:30
von TeaAge
Huhu,

ich hatte gerade das gleiche Problem und wollte mich einfach mal für die Lösung bedanken ;)

Das Probleme hatte ich sogar richtig erkannt bzw. hab es vermutet aber auf die Idee, die Deklaration in den Header zu schieben, bin ich nicht gekommen ;)

Gruß,
TeaAge