QRectItem: klick
-
Hi,
Ich habe einige QRectItems auf meinem Formular:
QGraphicsRectItem *rect_weiss[17];
Wenn ein QRectItem angeklickt wird, soll eine Funktion mit der Nummer es angeklickten QRectItem aufgerufen werden.
Wie bekomme ich das hin ? Mit connect() scheint es nicht zu funktionieren, weil QRectItem kein Signal(clicked()) kennt.
Hat jemand eine Idee ?
Danke,
Lusches :xmas1: :xmas2:
-
for(int i = 0;i <17; i++) connect(rect_weiss[i], SIGNAL(GEKLICKT(), SLOT(MEINSLOT(int i));
Etwa so habe ich mir das ganze vorgestellt, aber leider klappt es so nicht
-
Bitte zurück auf Start...- QGraphicsItems sind keine QObjects, weshalb sie auch keine SIGNALS und SLOTS haben können.
- Dein connect würde auch sonst nicht gehen: Der SLOT kann weniger Argumente haben als das SIGNAL, nicht aber umgekehrt. Außerdem wird die Signatur ohne Parameternamen erwartet, "int i" wird fehlschlagen.
Am einfachsten wäre es, du würdest von QGraphicsScene ableiten, dort den mousePress abfangen, schauen ob ein Item unter der Maus ist und ob dieses Item ein QGraphicsRectItem ist (item->type()), dann kannst du ein Signal auslösen. Falls da ne Nummer mitgehen soll, musst du halt in der Scene eine QMap<QGraphicsRectItem*, int> anlegen, vor dem emit dort die Nummer für das Item rausholen.
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.
Ich würde den ersten Weg gehen!
-
Danke schonmal...
Jeder fängt halt mal klein an
Wie ich Klicks abfange weiß ich ...
void MainWindow::mousePressEvent(QMouseEvent *) { QMessageBox b; b.setText("blah"); b.exec(); }
Wie funktioniert das denn bei einer QGraphicsScene ?
Anscheinend gibt es ja auch
rect_weiss[i]->mousePressEvent();
. Kann ich das irgendwie nutzen ?
Frohe Weihnachten... :xmas1:
-
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 ?