Anzeige:
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 16 bis 30 von 31

Thema: [Qt] Probleme mit QCanvas

  1. #16
    Registrierter Benutzer
    Registriert seit
    20.02.2004
    Beiträge
    15
    Moin nochmal.

    Ich bin gerade dabei mir das QCanvas-Feld selbst aufzubauen, da es ja etwas anders sein muss als das Beispiel.
    Nun komm ich an der Stelle nicht weiter, wo auf das Feld geklickt wird und ein Punkt gezeichnet werden soll. QCanvasEllipse braucht ja als Uebergabeparameter das QCanvas auf das es gezeichnet werden soll. Da komm ich jetzt aber nicht dran, weil sich das ja in einem protected mousePressEvent abspielt. Am Anfang hab ich noch versucht den ganzen Node in der mousePressEvent-Funktion zu erstellen, dann hab ich ne Node-Klasse erstellt, was mir aber null gebracht hat, wie ich dann festgestellt habe (haette ich _vorher_ nachdenken sollen). Jetzt hab ich mir weiter den Kopf zerbrochen, bin aber nicht auf die Loesung gekommen.
    Aber seht besser selbst, die Stelle habe ich gekennzeichnet.

    Die Header-Datei:
    Code:
    #ifndef CANVAS2_H
    #define CANVAS2_H
    
    #include <qapplication.h>
    #include <qcanvas.h>
    #include <stdlib.h>
    #include <time.h>
    #include <qlabel.h>
    #include <qpushbutton.h>
    #include <qfont.h>
    #include <qvbox.h>
    
    //////////////////////////////////////////////////////////////////////////////////////
    
    //============Node================
    class Node : QCanvasEllipse
    {
        public:
        Node(QCanvas *canvas);
        
    };
    
    //============GraphView===========
    class GraphView : public QCanvasView
    {
        public:
        GraphView(QCanvas *c, QWidget *parent=0, const char *name=0, WFlags f=0);    
        
        protected:
        void mousePressEvent(QMouseEvent *event);
        void mouseReleaseEvent(QMouseEvent *event);
        void mouseMoveEvent(QMouseEvent *event);
    };
    
    //////////////////////////////////////////////////////////////////////////////////////
    
    #endif //	CANVAS2_H
    Die CPP-Datei:
    Code:
    #include <qapplication.h>
    #include <qcanvas.h>
    #include <stdlib.h>
    #include <time.h>
    
    #include "canvas2.h"
    
    //////////////////////////////////////////////////////////////////////////////////////
    
    //============Node-Konstruktor===========
    Node::Node(QCanvas *canvas)
    	: QCanvasEllipse(5, 5, canvas)
    {
        QCanvasEllipse *node = new QCanvasEllipse();
        setBrush(QBrush(QColor(0, 0, 0)));
    }
    
    //============GraphView-Konstruktor========
    GraphView::GraphView(QCanvas *c, QWidget *parent, const char *name, WFlags f)
    	    : QCanvasView(c, parent, name, f)
    {
        resize(sizeHint());
    }
    
    //===========GraphView-mousePressEvent=======
    void GraphView::mousePressEvent(QMouseEvent *event)
    {
        
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // Hier kommt Node nicht an das Canvas und seine Methoden ran
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        Node *n = new Node(c);
    // !!!!!!!!!!!
        n->move(event->x(), event->y());
        n->show();
        n->setZ(5);
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    }
    //////////////////////////////////////////////////////////////////////////////////////

    P.S.: Erzaehlt mir bitte nicht, wo ich welche includes weglassen kann. Das mach ich zum Schluss und brings mir dann durch Trial&Error bei: So praegt sich mir das besser ein.

  2. #17
    Registrierter Benutzer Avatar von tuxipuxi
    Registriert seit
    30.08.2002
    Beiträge
    667
    Hi,

    Nun komm ich an der Stelle nicht weiter, wo auf das Feld geklickt wird und ein Punkt gezeichnet werden soll. QCanvasEllipse braucht ja als Uebergabeparameter das QCanvas auf das es gezeichnet werden soll. Da komm ich jetzt aber nicht dran, weil sich das ja in einem protected mousePressEvent abspielt.
    QCanvasView hat eine Methode canvas(), die dir einen Pointer auf das Canvasobjekt zurückliefert. Diesen Pointer kannst du als Canvasparent übergeben. (Siehe QCanvasView class reference.)

    Gruss,
    Michael.

  3. #18
    Registrierter Benutzer
    Registriert seit
    20.02.2004
    Beiträge
    15
    Mittlerweile habe ich es sogar geschafft, selber Nodes fuer den spaeteren Graphen zu zeichnen.
    Nu will ich deren Koordinaten in eine QTable schreiben, auf die kann ich aber vom Node-Konstruktor nicht zugreifen.
    Achja, die QTable namens werteTable habe ich mit dem Designer angefertigt.
    Hier die wichtigen Codeteile:

    aus graphform.ui.h:

    Code:
    void werteTable::addCoordinates(int xWert, int yWert)
    {
        setNumRows(numRows()+1);
        setText(numRows(), 0, xWert);
        setText(numRows(), 1, yWert);
        update();
    }
    aus canvas.cpp:

    Code:
    Node::Node(QCanvas *canvas, int x, int y)
    	: QCanvasEllipse(6, 6, canvas)
    {
        // Erstellung des Nodes
        setBrush(QBrush(QColor(109, 109, 250)));
        move((x-3), (y-3));    
        show();
        setZ(100);
        
        //Speichern der Node-Koordinaten
        werteTable.addCoordinates(x, y);
    }
    #include "graphform.h" ist in beiden canvas-Dateien (.cpp und .h) drin und die Fehlerausgabe ist:

    Code:
    canvas2.cpp: In member function `virtual void GraphView::mousePressEvent(QMouseEvent*)':
    canvas2.cpp:45: error: `werteTable' undeclared (first use this function)
    canvas2.cpp:45: error: (Each undeclared identifier is reported only once for each function it appears in.)

    //edit: Ich habs jetzt mal mit S&S probiert, aber da gibt er mir den gleichen Fehler (nur in ne anderen line) aus.... *weiter_rumbastel*...
    Dem Rechner scheinen ein paar Draehte durchgeglueht zu sein. Ich habe den String werteTable jetzt komplett aus meinem Code entfernt, aber es gibt immer noch die gleiche Fehlermeldung.
    Geändert von Flying_Eagle (26-02-2004 um 22:27 Uhr)

  4. #19
    Registrierter Benutzer
    Registriert seit
    20.02.2004
    Beiträge
    15
    So. Jetzt komm ich wirklich nicht mehr weiter. In den mainwindow-Dateien verursache ich entweder Speicherzugriffsfehler oder es funktioniert nicht.

    Mein Ziel ist es, die Koordinaten der Nodes in die Tabelle zu schreiben...

    Danke fuer eure Hilfe.

  5. #20
    Registrierter Benutzer Avatar von SumpfMonsterJun
    Registriert seit
    22.06.2003
    Ort
    Leipzig
    Beiträge
    14
    Hi Flying_Eagle,

    Dein Problem ist recht simpel, Du hast die Zeile, in der die QTable erstellt wird versehentlich
    auskommentiert.

    In mainwindow.cpp ungefähr in Zeile 18 muß folgendes stehen:

    xyTable = new QTable(0, 2, this, "xytable");

    anstatt

    // QTable *yTable = new QTable(0, 2, this, "xytable");

    Gruss, SMJ

  6. #21
    Registrierter Benutzer Avatar von SumpfMonsterJun
    Registriert seit
    22.06.2003
    Ort
    Leipzig
    Beiträge
    14

    Nachtrag

    Hi Flying_Eagle,

    im Anhang ist die funktionierende Fassung (mit Eintrag in die QTable) als Archiv.

    Beste Grüsse, SMJ

  7. #22
    Registrierter Benutzer
    Registriert seit
    20.02.2004
    Beiträge
    15
    Hmpf. Dann war das wahrscheinlich die einzige Moeglichkeit, die ich noch nicht ausprobiert hatte ;_^
    Danke, danke, danke.

    //edit: Auf die Sache mit dem dynamic_cast waere ich natuerlich selber gekommen ;P
    Gibt es in der Doku ueberhaupt eine Stelle, in der diese Funktion (oder was auch immer das ist) erwaehnt wird? Ich konnte nichts finden.


    Ein anderer aus meinem Kurs macht ein aehnliches Programm in DirectX -> Overkill?
    Das hat noch nicht mal halbwegs ne GUI...
    Geändert von Flying_Eagle (03-03-2004 um 18:26 Uhr)

  8. #23
    Registrierter Benutzer Avatar von tuxipuxi
    Registriert seit
    30.08.2002
    Beiträge
    667
    hi,

    dynamic_cast und co. sind c++ standard, nicht Qt spezifisch, also musst du dir dafür eine cpp reference suchen( vielleicht ist es ja auf cppreference.com ).

    das mit directx kann ich nicht bewerten, hab mich nie damit beschäftigt.

    gruss,
    michael.

  9. #24
    Registrierter Benutzer
    Registriert seit
    20.02.2004
    Beiträge
    15
    jo, google hats mir gegeben
    Und das "The Free On-line Dictionary of Computing" hat mir gesagt, dass ein cast eine "explicit type conversion" ist. Ich versteh aber nicht ganz was da nun konvertiert/transformiert oder was-auch-immer werden soll. Fuer mich sieht die Funktion des dynamic_casts eher so aus, dass er mir auch Objekte liefert auf die ich sonst nicht so einfach zugreifen koennte bzw. verglichen wird ob ein bestimmtes Objekt zu einem bestimmten Typ gehoert!?

  10. #25
    Registrierter Benutzer Avatar von SumpfMonsterJun
    Registriert seit
    22.06.2003
    Ort
    Leipzig
    Beiträge
    14
    Hi Flying Eagle,

    Zuallererst eine Anmerkung zum Code, besser ist es, Du ersetzt in canvas.cpp

    MainWindow * pmwParent = dynamic_cast< MainWindow* >( parent() );

    mit

    MainWindow * pmwParent = dynamic_cast< MainWindow* >( parentWidget() );

    habe ich im Code vergessen, gleich so zu schreiben.

    die zugrundeliegende Idee ist, die QWidget::parentWidget() Methode zu benutzen, mit der man einen Zeiger auf das Eltern-Widget erhält. Da GraphView von QWidget erbt, steht diese Funktion zur Verfügung. Das eigentliche Problem ist aber, daß das Elternobjekt von GraphView ein MainWindow-Objekt ist, welches zwar ebenfalls von QWidget erbt und damit eines ist, Du brauchst aber die Methode MainWindow::addCoordinates, an diese kommst Du über die von parentWidget() gelieferte QWidget-Schnittstelle nicht heran. Du könntest nun einen schmutzigen C-Cast machen wie folgt:

    MainWindow * pmwParent = ( MainWindow* ) parentWidget();

    das wäre aber sehr gefährlich, denn wenn das Elternobjekt nicht tatsächlich eine MainWindow Klasse ist, ist das Ergebnis undefiniert, was auf ein "Setzen, 6" hinausläuft (sprich Absturz des Programms). Auch wenn es in Deinem Fall funktionieren könnte, so wäre es doch möglich, daß GraphView mittels QWidget::reparent() an ein neues Elternobjekt zur Laufzeit zu übergeben wird und dann wäre der obige cast ungültig.

    dynamic_cast schafft all dem Abhilfe, denn es prüft, ob der übergebene Parameter ( in Deinem Fall parentWidget ) überhaupt in den in eckigen Klammern spezifizierten Typ umwandelbar ist. Falls das nicht geht, liefert dynamic_cast 0 zurück. Somit sind sichere Casts möglich. Letztendlich sind Casts aber immer nur Kompromisse die sich mittels abstrakter Klassen vermeiden lassen. Immerhin sind sie mit den C++ Mitteln (dymic_cast, static_cast ) leichter aufzuspüren.

    Viele Grüsse, SMJ
    Geändert von SumpfMonsterJun (04-03-2004 um 12:00 Uhr)

  11. #26
    Registrierter Benutzer Avatar von SumpfMonsterJun
    Registriert seit
    22.06.2003
    Ort
    Leipzig
    Beiträge
    14

    DirectX

    Noch ein Nachtrag zum DirectX:

    im Prinzip läßt sich mit einem aktuellen DirectX (ab Version7) vernünftig arbeiten, selbst die Win32-GUI-Elemente stehen zur Verfügung. Es hat aber mindestens drei eintscheidende Nachteile:

    1.) Nicht portabel
    2.) die Windows GUI über die Win32 Schnittstelle zu programmieren ist eine wahre Pein, mit der MFC ists nicht viel besser
    3.) umständlich zu debuggen

    QT löst alle diese Probleme auf die eleganteste Weise.

    Gruß, SMJ

  12. #27
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Original geschrieben von Flying_Eagle
    Und das "The Free On-line Dictionary of Computing" hat mir gesagt, dass ein cast eine "explicit type conversion" ist. Ich versteh aber nicht ganz was da nun konvertiert/transformiert oder was-auch-immer werden soll.
    Jede Datenstruktur in C++ hat einen Ty, zb int oder eine Klasse.

    Der Kompiler kennt die Eigenschaften der Typen, und kann daher prüfen, ob bestimmte Code Kontrukte möglich sind, als ob zum Beispiel ein Operator für einen Typ vorhanden ist.

    Der Cast verwandelt den Typ der Datenstruktur aus Sicht des Comilers, die Struktur im Speicher bleibt dabei unverändert, die Daten dort werden aber abhängig vom Zieltyp anders interpretiert.

    Bei einem Cast einer Klassen Instanz auf eine andere Klasse, kennt der Compiler nun die Funktionen der Zielklasse, d.h. er erlaubt diese aufzurufen.
    Wenn das ein ungültiger Cast war, dann kann alles mögliche passieren, darum sollte man nur casten, wenn man sicher ist, dass der Cast erlaubt ist, bzw eine Cast-Art benutzen, die das selbst prüft (eben zB dynamic_cast)

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  13. #28
    Registrierter Benutzer
    Registriert seit
    20.02.2004
    Beiträge
    15
    Danke nochmal fuer die Erklaerungen.
    Ich hab das Programm gestern noch stark erweitert.
    Falls es euch interessiert, koennt ihr euch die aktuelle Version unter www.mastas.de/graph_tool.tar.gz runterladen (die aktuelle lad ich hoch wenn ich gleich zuhause bin).

    Aber ich hab noch ne Frage:
    Warum laeuft das daemliche Programm nicht unter Window (W2k mit VC++)?
    Es gestaltet sich sehr unoeglich meinem Lehrer das Programm zu zeigen, wenn es nicht vernuenftig kompiliert
    Bei der Ausfuehrung kommt immer ein Runtime-Error, wenn ich in das Canvas klicke.
    Wenn ich einen Node manuell hinzufuege (neues Feature) funktioniert es.
    Geändert von Flying_Eagle (05-03-2004 um 11:36 Uhr)

  14. #29
    Registrierter Benutzer Avatar von tuxipuxi
    Registriert seit
    30.08.2002
    Beiträge
    667
    Original geschrieben von Flying_Eagle
    Danke nochmal fuer die Erklaerungen.
    Ich hab das Programm gestern noch stark erweitert.
    Falls es euch interessiert, koennt ihr euch die aktuelle Version unter www.mastas.de/graph_tool.tar.gz runterladen (die aktuelle lad ich hoch wenn ich gleich zuhause bin).

    Aber ich hab noch ne Frage:
    Warum laeuft das daemliche Programm nicht unter Window (W2k mit VC++)?
    Es gestaltet sich sehr unoeglich meinem Lehrer das Programm zu zeigen, wenn es nicht vernuenftig kompiliert
    Bei der Ausfuehrung kommt immer ein Runtime-Error, wenn ich in das Canvas klicke.
    Wenn ich einen Node manuell hinzufuege (neues Feature) funktioniert es.
    hi,

    ein bisschen debugger ausgabe wäre schon nett .

    gruss,
    michael.

  15. #30
    Registrierter Benutzer
    Registriert seit
    20.02.2004
    Beiträge
    15
    Original geschrieben von tuxipuxi
    ein bisschen debugger ausgabe wäre schon nett .
    Es kam nur "Runtime-Error" und dann noch das die Applikation irgendwie fruehzeitig terminiert wurde (ich glaub auch unexpected), aber windowstypisch nichts wirklich verwertbares.

    Achja ich hab am Anfang der mousePressEvent-Methode eine Messagebox eingefuegt, aber diese wird nicht angezeigt. Vermutlich liegt der Fehler deswegen im Aufruf der Methode.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •