onclick Ereignis bei "normalen" Widgets!!!
onclick Ereignis bei "normalen" Widgets!!!
habe da ein kleines Problem.
Teste noch ein wenig in QT herum! Ich brauche später ein Polygon, was mit einer Farbe gefüllt ist und was man wenn man es anklickt dann seine Farbe ändert!
Dachte mir, dass ich das dann mit QObject::connect mache!
nur brauch ich dann ja das SIGNAL(clicked()) welches aber nur bei Buttons existiert und nicht bei einem Polygon oder ähnlichem!
Jetzt sie Frage: Wie kann ich so ein clicked() SIGNAL schreiben???? Also wie erkennt man denn das auf das Objekt geklickt wurde?
Teste noch ein wenig in QT herum! Ich brauche später ein Polygon, was mit einer Farbe gefüllt ist und was man wenn man es anklickt dann seine Farbe ändert!
Dachte mir, dass ich das dann mit QObject::connect mache!
nur brauch ich dann ja das SIGNAL(clicked()) welches aber nur bei Buttons existiert und nicht bei einem Polygon oder ähnlichem!
Jetzt sie Frage: Wie kann ich so ein clicked() SIGNAL schreiben???? Also wie erkennt man denn das auf das Objekt geklickt wurde?
-
ArneStocker
- Beiträge: 300
- Registriert: 3. November 2004 16:15
- Wohnort: Berlin
in einer eigenen abgeleisteten Klasse (z.B. MyPolygonClass)
um das signal zu senden rufst Du innerhalb von MyPolygonClass
auf. Das connect natürlich nicht vergessen.
Gruss Arne
Code: Alles auswählen
class MyPolygonClass : public QObject
{
Q_OBJECT
...
signals:
void clicked();
...
}
Code: Alles auswählen
emit clicked();
Gruss Arne
Danke!
Das oben ist klar!
Aber: Das mit dem
versteh ich irgendwie nicht so ganz! Wenn ich das richtig verstehe muss ich genau das ja schreiben nachdem ich festgestellt habe, das auf das Polygon geklickt wurde! Jetzt ist nur die Sache dass ich das genau ja nicht weiß!
Oder versteh ich hier gerade etwas total falsch?
Hier der aktuelle Code von meinem Programm! Arbeite da zur Zeit zwar nicth mit einem Polygon, aber das dürfte ja keinen Unterschied machen.
fedderle!!!
Das oben ist klar!
Aber: Das mit dem
Code: Alles auswählen
emit clicked()Oder versteh ich hier gerade etwas total falsch?
Hier der aktuelle Code von meinem Programm! Arbeite da zur Zeit zwar nicth mit einem Polygon, aber das dürfte ja keinen Unterschied machen.
Code: Alles auswählen
#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QLinearGradient>
#include <QObject>
#include <QPushButton>
class MyWidget : public QWidget
{
Q_OBJECT
public:
// Funktion PaintEvent muss ueberladen werden
MyWidget(QWidget *parent = 0);
void paintEvent(QPaintEvent *);
signals:
void clicked();
};
MyWidget::MyWidget(QWidget *parent):QWidget(parent)
{}
void MyWidget::paintEvent(QPaintEvent *)
{
// Zeichenstift auf dieses Widget
QPainter painter(this);
QLinearGradient gradient(0, 0, 150, 150);
gradient.setColorAt(0, Qt::red);
gradient.setColorAt(0.5, Qt::green);
gradient.setColorAt(1, Qt::blue);
painter.setBrush(gradient);
painter.drawRect(0, 0, 150, 150);
}
int main(int argc, char* * argv)
{
// Anwendung
QApplication app(argc, argv);
MyWidget zeichenbrett;
zeichenbrett.resize(150,300);
QPushButton button("quit", &zeichenbrett);
button.setGeometry(0, 150, 100, 30);
QObject::connect(&button, SIGNAL(clicked()), &app, SLOT(quit()));
// wenn man auf das Brett klcikt schliesst sich das Programm
QObject::connect(&zeichenbrett, SIGNAL(clicked()), &app, SLOT(quit()));
QPainter painter;
zeichenbrett.show();
button.show();
return app.exec();
}
Jetzt bin ich irgendwie total verwirrt!
Also! Was brauche ich denn jetzt alles um erkennen zu koennen, ob auf das Objekt geklickt wurde!
nur dieses ...
und dann irgendwo dieses emit!
Wobei ich hier nicht ganz verstehe wie dass dann gehen soll, weil egal wo ich dieses
innnerhalb der Klasse hinschreibe kommt folgende compiler fehlermeldung
feddderle
Also! Was brauche ich denn jetzt alles um erkennen zu koennen, ob auf das Objekt geklickt wurde!
nur dieses ...
Code: Alles auswählen
class MyPolygon : public QPolygonF, public QObject
{
Q_OBJECT
...
signals:
void clicked();
};
Wobei ich hier nicht ganz verstehe wie dass dann gehen soll, weil egal wo ich dieses
Code: Alles auswählen
emit clicked()Oder muss ich beides machen also diese QMouseEvent ebenfalls mit reinmachen?????undefined reference to 'MyPolygon::clicked()'
feddderle
-
ArneStocker
- Beiträge: 300
- Registriert: 3. November 2004 16:15
- Wohnort: Berlin
Innerhalb Deiner Polygonklasse musst Du schon die events auslesen. SIGNAL und SLOT ist eigentlich als Kommunikation zwischen verschiedenen Objekten gedacht (also z.B. einem QButton Objekt und dem QDialog Objekt).
In der Standard - Implementation von QButton wird z.B. auf ein Klick reagiert (wie die das machen kann ich nur vermuten, nämlich über event) und dann das Signal clicked() gesendet.
Wenn Du innerhalb Deiner Polygonklasse auf ein Klickevent reagieren willst, musst Du die events abfangen. Um von Deiner Polygonklasse eine Nachricht an z.B. die Dialogklasse zu versenden nimmst du das emit clicked().
Nur zur Klarstellung : Polygon (Deine Klasse) versendet nicht automatisch ein clicked() event, wenn Du draufklickst (das macht aber z.B. QButton). Das Mausereigniss über deinem Objekt führt von sich aus nicht zum Versenden der Nachricht clicked. Umgekehrt kannst ein clicked() SIGNAL auch versenden, wenn gar nichts geklickt wurde. Das emit clicked() rufst Du also in der eventmethode der Polygon - Klasse auf (nämlich dann wenn auf Dein Objekt geklickt wurde).
Anschliessend werden alle Objekte, die Du mit connect verbunden hast, über ihren SLOT von dem SIGNAL benachrichtigt.
Alle Klarheiten beseitigt ?
Gruss Arne
PS.: wegen des Compiler - Fehlers könnte es sein, dass Du (falls das nicht automatisch von qmake gemacht wird) den moc(Meta - objekt Compiler über Deine Klassendeklaration laufen lassen musst). Wenn Du nachträglich ein Q_OBJECT eingefügt hast, ist m.E. ein erneuter Aufruf von qmake fällig.
In der Standard - Implementation von QButton wird z.B. auf ein Klick reagiert (wie die das machen kann ich nur vermuten, nämlich über event) und dann das Signal clicked() gesendet.
Wenn Du innerhalb Deiner Polygonklasse auf ein Klickevent reagieren willst, musst Du die events abfangen. Um von Deiner Polygonklasse eine Nachricht an z.B. die Dialogklasse zu versenden nimmst du das emit clicked().
Nur zur Klarstellung : Polygon (Deine Klasse) versendet nicht automatisch ein clicked() event, wenn Du draufklickst (das macht aber z.B. QButton). Das Mausereigniss über deinem Objekt führt von sich aus nicht zum Versenden der Nachricht clicked. Umgekehrt kannst ein clicked() SIGNAL auch versenden, wenn gar nichts geklickt wurde. Das emit clicked() rufst Du also in der eventmethode der Polygon - Klasse auf (nämlich dann wenn auf Dein Objekt geklickt wurde).
Anschliessend werden alle Objekte, die Du mit connect verbunden hast, über ihren SLOT von dem SIGNAL benachrichtigt.
Alle Klarheiten beseitigt ?
Gruss Arne
PS.: wegen des Compiler - Fehlers könnte es sein, dass Du (falls das nicht automatisch von qmake gemacht wird) den moc(Meta - objekt Compiler über Deine Klassendeklaration laufen lassen musst). Wenn Du nachträglich ein Q_OBJECT eingefügt hast, ist m.E. ein erneuter Aufruf von qmake fällig.
So weit in der theorie klar!
Also ich hab noch mal von vorne angefangen! Ich versuche das ganze Vorhaben jetzt mal genau zu erklären! Insgesammt soll das ganze später ne Landkarte werden, wo man die einzelnen Länder anklicken kann und das aktuell angeklickte Land dann die Farbe ändert!
Ich hab mir dazu gedacht erstellt ein Widget, wo die ganzen einzelnen Länder (Polygone) drauf dargestellt werden! Klingt eigentlich in der Theorie verdammt einfach!
Ich probier jetzt nur schon seit Tagen hier rum! Dachte erst,das kann ja nicht so schwer sein, mach einfach mal ne neue Klasse und schreib die Methode woid paintEvent() um!
Und jetzt kommen wir wieder zu meinem alten Problem!
Habe folgenden Quelltext aktuell mit dem ich herumhantiere:
Wie gesagt habe noch einmal von vorne angefangen! Treffe aber jetzt hier schon auf erste Probleme beim kompililieren!
Sobald ich oben in der eigenen Klasse das Stichwort Q_OBJECT eingebe und irgendwo ein Objekt der Klasse erzeugen (oben geschieht dies in der int main()) möchte, kommt diese Fehlermeldung:
Dazu noch! Ja ich nutze vor dem kompielieren das qmake!
Also meine eingaben sind da dann immer:
1. qmake -project
2. qmake
3. make
ist doch richtig so!!!!? Oder hab ich was vergessen?
Wäre echt dankbar, wenn mir da irgendjemand helfen könnte!
fedderle
Also ich hab noch mal von vorne angefangen! Ich versuche das ganze Vorhaben jetzt mal genau zu erklären! Insgesammt soll das ganze später ne Landkarte werden, wo man die einzelnen Länder anklicken kann und das aktuell angeklickte Land dann die Farbe ändert!
Ich hab mir dazu gedacht erstellt ein Widget, wo die ganzen einzelnen Länder (Polygone) drauf dargestellt werden! Klingt eigentlich in der Theorie verdammt einfach!
Ich probier jetzt nur schon seit Tagen hier rum! Dachte erst,das kann ja nicht so schwer sein, mach einfach mal ne neue Klasse und schreib die Methode woid paintEvent() um!
Und jetzt kommen wir wieder zu meinem alten Problem!
Habe folgenden Quelltext aktuell mit dem ich herumhantiere:
Code: Alles auswählen
#include <QApplication>
#include <QPushButton>
#include <QWidget>
#include <QPolygonF>
#include <QPainter>
#include <QObject>
#include <QPaintEvent>
class MyQWidget : public QWidget
{
Q_OBJECT
public:
void paintEvent(QPaintEvent *);
signals:
void clicked();
};
void MyQWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPolygonF polygon;
polygon << QPointF(20,50) << QPointF (40, 40) << QPointF(120, 100) << QPointF(55, 230);
painter.setBrush(Qt::blue);
painter.drawPolygon(polygon, Qt::OddEvenFill);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyQWidget widget;
widget.show();
return app.exec();
}
Sobald ich oben in der eigenen Klasse das Stichwort Q_OBJECT eingebe und irgendwo ein Objekt der Klasse erzeugen (oben geschieht dies in der int main()) möchte, kommt diese Fehlermeldung:
Wenn ich kein Obejekt erstelle kommt die Meldung nicht! Wenn ich ein Obejkt erstelle aber das Q_OBJECT nicht hinschreibe kommt auch keine fehlermeldung! Aber ich brauch das Q_OBJECT ja!src/testpolygone1.cpp:29: undefined reference to `vtable for MyQWidget'
Dazu noch! Ja ich nutze vor dem kompielieren das qmake!
Also meine eingaben sind da dann immer:
1. qmake -project
2. qmake
3. make
ist doch richtig so!!!!? Oder hab ich was vergessen?
Wäre echt dankbar, wenn mir da irgendjemand helfen könnte!
fedderle
Es heisst :
Code: Alles auswählen
protected:
void paintEvent(QPaintEvent *);-
ArneStocker
- Beiträge: 300
- Registriert: 3. November 2004 16:15
- Wohnort: Berlin
das protected ist m.E. nicht schuld. Es muss zulässig sein, eine Methode in einer anderen
Klasse mit anderen Berechtigungen zu implementieren
Aber paintEvent ist eine virtuelle Methode und wird zur Laufzeit gebunden. Es sollte daher heissen
Gruss Arne
Klasse mit anderen Berechtigungen zu implementieren
Aber paintEvent ist eine virtuelle Methode und wird zur Laufzeit gebunden. Es sollte daher heissen
Nur zum Verständnis: Dein Programm lässt sich doch übersetzen (sonst könntest Du kein Objekt erzeugen). Erhälst Du die Meldung während des Debuggens in der Konsole ?virtual void paintEvent(QPaintEvent *pEvent);
Gruss Arne
Nein, mein Lieber, genau das ist falsch. Eine Funktion bleibt in allen abgeleiteten Klassen virtuell. Also muss es nicht vitual void ... heissen. Dagegen ist es wichtig, dass die Funktion, die ich überlade, in der gleichen Access-Klasse bleibt. Das ist auch irgendwo der Sinn der objekt-orientierten Herangehensweise.
-
ArneStocker
- Beiträge: 300
- Registriert: 3. November 2004 16:15
- Wohnort: Berlin
Ok Leute hatte ein wenig gedauert!
Hatte immer noch Probleme, das ich nicht kompilieren konnte wenn ich Q_OBJECT in den Code einfüge! Bis ich irgendwann herausgefunden habe, dass das ja nur in headerdateien stehen darf nicht in cpp dateien!
Habe es jetzt folgendermaßen gemacht:
habe eine MyQwidget Klasse von QWidget abgeleitet!
Dort habe ich das siganl void clicked() definiert!
Jetzt nur noch mal um Nummer sicher zu gehen, damit iches auch wirklich richtig verstanden habe!
Jetzt muss ich ne Funktion schreiben/finden, die ermittlet, wann aufd den Button geklickt wurde! und dort das emit clicked() einbinden!!!!??
seh ich das richtig???
Gruß fedderle!
Hatte immer noch Probleme, das ich nicht kompilieren konnte wenn ich Q_OBJECT in den Code einfüge! Bis ich irgendwann herausgefunden habe, dass das ja nur in headerdateien stehen darf nicht in cpp dateien!
Habe es jetzt folgendermaßen gemacht:
habe eine MyQwidget Klasse von QWidget abgeleitet!
Dort habe ich das siganl void clicked() definiert!
Jetzt nur noch mal um Nummer sicher zu gehen, damit iches auch wirklich richtig verstanden habe!
Jetzt muss ich ne Funktion schreiben/finden, die ermittlet, wann aufd den Button geklickt wurde! und dort das emit clicked() einbinden!!!!??
seh ich das richtig???
Gruß fedderle!
-
FlorianBecker
- Beiträge: 1213
- Registriert: 2. Dezember 2004 10:54
- Kontaktdaten:
Hi! Ich habe so ziemlich das selbe Problem, habe das auch so gemacht wie ihr es beschrieben hattet, nur irgendwie will es nicht funktionieren. 
und in der main:
Also es soll diese Karte angeklickt werden, und dann z.b. ein anderes Bild oder ähnliches geladen werden.
Dies ist auch fast der selbe Code den federle benutzt, nur das es bei ihm funktioniert und bei mir nicht.
Kann mir jemand sagen warum??
Gruß, AngelDust
Code: Alles auswählen
class HPKarte : public QWidget
{
Q_OBJECT
protected:
void mousePressEvent(QMouseEvent *event);
signals:
void clicked(HPKarte *); // Signal das auf das Widget geklickt wurde
public slots:
void cardClicked(HPKarte *);
}
void HPKarte::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
emit clicked(this);
}
Code: Alles auswählen
HPKarte *muh = new HPKarte(HPKarte::Figur(1));
QObject::connect(muh, SIGNAL(clicked(HPKarte *)), muh, SLOT(cardClicked(HPPolygon *)));
muh->show();
Dies ist auch fast der selbe Code den federle benutzt, nur das es bei ihm funktioniert und bei mir nicht.
Kann mir jemand sagen warum??
Gruß, AngelDust