QRectItem: klick



  • Lusches66667 schrieb:

    Wie funktioniert das denn bei einer QGraphicsScene?

    Lies den Absatz mit dem QGraphicsScene nochmal durch, und schau bitte auch in die Doku.

    Anscheinend gibt es ja auch

    rect_weiss[i]->mousePressEvent();
    

    . Kann ich das irgendwie nutzen ? 😃

    Hast du Zugriff auf QGraphicsRectItem::mousePressEvent()? Wie sieht die Signatur von QGraphcisRectItem::mousePressEvent() aus?



  • Hast du Zugriff auf QGraphicsRectItem::mousePressEvent()?

    Da im Programm ein QGraphicsRectItem-Objekt erstellt wurde, müsste ich doch eigentlich zugriff darauf haben, oder nicht ? Was du mit Signatur meinst, weiß ich leider nicht.

    In die Doku schaue ich schon die ganze Zeit mit mäßigem Erfolg...

    Es wäre wirklich nett, wenn mir jemand die paar Zeilen Quelltext posten könnte, weil ich irgendwie überhaupt nicht mehr weiterkomme.

    Danke 🙂



  • Lusches667 schrieb:

    Hast du Zugriff auf QGraphicsRectItem::mousePressEvent()?

    Da im Programm ein QGraphicsRectItem-Objekt erstellt wurde, müsste ich doch eigentlich zugriff darauf haben, oder nicht?

    mousePressEvent ist protected. Hat man als nicht-Kind-Klasse oder nicht-friend-Klasse/Funktion Zugriff auf protected-Member einer anderen Klasse?

    Was du mit Signatur meinst, weiß ich leider nicht.

    Sry, aber ein klein wenig Eigeninitiative wäre angebracht. So signalisierst du uns dein Desinteresse, und meine Zeit ist mir zu wertvoll, um hier Grundlagen beizubringen oder Komplettlösungen abzugeben. Vllt. hat ja jemand mehr Zeit/Geduld.
    Hier noch ein kurzer Link:
    http://lmgtfy.com/?q=Funktion+Signatur



  • Nicht so schnell aufgeben...

    mousePressEvent ist protected. Hat man als nicht-Kind-Klasse oder nicht-friend-Klasse/Funktion Zugriff auf protected-Member einer anderen Klasse?

    Wenn die Funktion protected ist nicht ...

    In meiner Doku steht:

    void QGraphicsItem::mouseMoveEvent ( QGraphicsSceneMouseEvent * event ) [virtual protected]
    

    Das ganze ist protected, also kann ich nicht drauf zugreifen.

    Wenn ich dich richtig verstanden habe, soll ich jetzt die Klasse QGraphicsItem an eine neue klasse vererben, damit ich kann zugriff auf die protected-funktionen habe...

    Das müsste ja dann irgendwie so aussehen :

    class klick: public QGraphicsItem
    {
    
    private:
    QGraphicsSceneMouseEvent *event;
       void mouse()
       {
         this->mouseMoveEvent(event);
       }
    };
    

    Geht das schon in die richtige Richtung ?



  • Lusches667 schrieb:

    Wenn ich dich richtig verstanden habe, soll ich jetzt die Klasse QGraphicsItem an eine neue klasse vererben, damit ich kann zugriff auf die protected-funktionen habe...

    Nein, hast du nicht (ganz).
    Ich zitier mich selbst:

    Wenn jedoch wirklich das Item selber das Signal auslösen soll, musst du eine eigene Klasse erstellen, die von QObject und QGraphicsRectItem abgeleitet ist. Wenn das Item selber wissen soll, welche Nummer es hat, brauchst du passenden Konstruktor/setter. Dann nur noch mousePress abfangen und das Signal mit der jeweiligen Nummer emitten -> fertig.

    Das müsste ja dann irgendwie so aussehen :

    class klick: public QGraphicsItem
    {
    
    private:
    QGraphicsSceneMouseEvent *event;
       void mouse()
       {
         this->mouseMoveEvent(event);
       }
    };
    

    Was du machst ist "von QGraphicsItem ableiten, dort eine private (!) Methode "mouse" definieren, die mouseMoveEvent mit einem unintialisierten Zeiger auf das event aufruft". Das passt nicht zusammen, oder?
    Qt fängt vom Windowsystem die Mouse-Events ab und verteilt sie an die Widgets, die es interessiert. Das QGraphicsView-Framework bietet dazu sowohl in der view als auch in der scene die entsprechenden mouse-Handler an, die dann aufgerufen werden. Diese werden dann (wenn gewünscht -> interactive) an die Items weitergereicht. Um an ein solches Event ranzukommen, musst du nun nur die entsprechende virtual protected Methode des Items implementieren und dort ein SIGNAL emitten -> fertig.



  • Mittlerweile habe ich mir ein gutes Buch ausgeliehen 🙂

    Folgendes ist dabei herausgekommen:

    #include <QMainWindow>
    #include <QGraphicsRectItem>
    #include <QGraphicsScene>
    
    class klick;
    
    namespace Ui {
        class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private slots:
        void on_pushButton_clicked();
        void pos(int x, int y);
    
    private:
        Ui::MainWindow *ui;
    
    klick *k;
    QGraphicsRectItem *rect;
    
    };
    
    class klick : public QGraphicsScene
    {
        Q_OBJECT
    
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    
    signals:
    
    void set(int, int);
    
    };
    

    und weiter:

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        QPen pen(Qt::blue);
    
        k = new klick();
        ui->graphicsView->setScene(k);
    
        rect = k->addRect(50, 50, 50, 50, pen);
    }
    
    void MainWindow::pos(int x, int y)
    {
        ui->x->setText(QString::number(x));
        ui->y->setText(QString::number(y));
    }
    
    klick::klick()
    {
        connect(this, SIGNAL(set(int,int)), <- hier ist im Moment mein Problem
    }
    
    void klick::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
        emit set(2, 3);
    }
    

    Also:

    Ich habe QGraphicScene abgeleitet will in der abgeleiteten klasse ein signal abschicken und dieses signal per connect mit einer funktion aus der MainWindow-klasse koppeln.

    connect(this, SIGNAL(set(int,int)),
    

    Wie muss der connect-aufruf lauten ? Als dritter Parameter wird ein Zeiger auf das Objekt erwartetm aber ich komme nicht an den Zeiger von "MainWindow w" aus der "main.cpp" ran.

    Wie kann ich denn das Signal und den Slot verbinden ?

    Danke,
    Lusches



  • Die scene interessiert doch gar nicht, wer das Signal fängt, sie wirft es nur. Wenn jemanden das Klick interessiert, soll er doch selber connecten.
    Hier: connect irgendwo im MainWindow, nicht in der scene.

    Außerdem: was hat mouseMoveEvent mit Klicks zu tun?



  • Das funktioniert schonmal.
    Ich wollte einfach zum Testen die X und Y-Werte aus dem Event auslesen und dann als Labeltext ausgeben.

    void klick::mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
        int x;
        int y;
    
        x = event->pos.x();
    
    }
    

    Das funktioniert nicht:

    C:\Users\Maik\test3-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\test3\mainwindow.cpp:71: Fehler:invalid use of incomplete type 'struct QGraphicsSceneMouseEvent'

    C:\Users\Maik\test3-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\..\..\QtSDK\Desktop\Qt\4.7.4\mingw\include\QtGui\qgraphicsitem.h:73: Fehler:forward declaration of 'struct QGraphicsSceneMouseEvent'

    Und wie kann dann bestimmt werden, ob es sich um ein QRect-Item handelt ?

    Danke!



  • Lusches6667 schrieb:

    Das funktioniert nicht:

    C:\Users\Maik\test3-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\test3\mainwindow.cpp:71: Fehler:invalid use of incomplete type 'struct QGraphicsSceneMouseEvent'

    C:\Users\Maik\test3-build-desktop-Qt_4_7_4_for_Desktop_-_MinGW_4_4__Qt_SDK__Debug\..\..\..\QtSDK\Desktop\Qt\4.7.4\mingw\include\QtGui\qgraphicsitem.h:73: Fehler:forward declaration of 'struct QGraphicsSceneMouseEvent'

    include vergessen.

    Und wie kann dann bestimmt werden, ob es sich um ein QRect-Item handelt ?

    Hab ich doch oben schon geschrieben (glaub war mein erster Post).
    QGraphicsItem::type() auswerten.



  • Das hier ist der neueste Stand:

    void klick::mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
        int x;
        int y;
    
        x = event->scenePos().x();
        y = event->scenePos().y();
    
        QGraphicsItem *find = this->itemAt(x, y);
    
        if(find != NULL)
        {
            int result = find->type();
    
            QMessageBox b;
            b.setText(QString::number(result));
            b.exec();
    
            QGraphicsRectItem *item = new QGraphicsRectItem;
            item = (QGraphicsRectItem*) find;
    
            QBrush red(Qt::red);
            item->setBrush(red);
        }
    
        emit set(x, y);
    }
    

    Das Programm findet das Item. Jetzt müsste nurnoch eine Nummer emittiert werden. Wie hast du dir das mit dem QMap vorgestellt ?


Anmelden zum Antworten