Seite 1 von 1
Frage zum Scribble Example[gelöst]
Verfasst: 12. März 2008 13:19
von Qt-nator
Hi,
was ich versuche ist folgendes, dass wenn ich in einem Widget die Maus drücke und sie dann bewege soll der Mausbewegung nachgezeichnet werden. Des halb hab ich mich mal am Scribble Example probiert und so. Bei mir entsteht ist dann follgendes entstanden:
Code: Alles auswählen
void ParameterToolWidget::drawLineTo(const QPoint &endPoint)
{
QPainter painter(XXX);
painter.setPen(QPen(Qt::blue, 1, Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin));
painter.drawLine(m_LastPoint, endPoint);
m_LastPoint = endPoint;
}
void
ParameterToolWidget::mouseMoveEvent(QMouseEvent* event)
{
QString sMouseInteraction;
sMouseInteraction.sprintf(" Maus Position: X: %d, Y: %d ", event->pos().x(), event->pos().y());
emit si_mousePosition(sMouseInteraction);
if ((event->buttons() & Qt::LeftButton) && m_Scribbling) drawLineTo(event->pos());
}
void
ParameterToolWidget::mousePressEvent(QMouseEvent* event)
{
QString sMouseInteraction = "Maustaste wurde gedrückt.";
emit si_mousePosition(sMouseInteraction);
if (event->button() == Qt::LeftButton)
{
m_LastPoint = event->pos();
m_Scribbling = true;
}
}
void
ParameterToolWidget::mouseReleaseEvent(QMouseEvent* event)
{
QString sMouseInteraction = "Maustaste wurde gedrückt/losgelassen.";
emit si_mousePosition(sMouseInteraction);
if (event->button() == Qt::LeftButton && m_Scribbling)
{
drawLineTo(event->pos());
m_Scribbling = false;
}
}
Bei drawLineTo ist im Example folgendes:
Code: Alles auswählen
void ScribbleArea::drawLineTo(const QPoint &endPoint)
{
QPainter painter(&image);
painter.setPen(QPen(myPenColor, myPenWidth, Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin));
painter.drawLine(lastPoint, endPoint);
modified = true;
int rad = (myPenWidth / 2) + 2;
update(QRect(lastPoint, endPoint).normalized()
.adjusted(-rad, -rad, +rad, +rad));
lastPoint = endPoint;
}
Mein Problem stellt diese Zeile dar bei meiner Version mit XXX gekenzeichnet
// QPainter painter(&image); //
jedenfalls ist image ein erstelltes QImage... mein Problem ist jetzt ich muss mein Widget damit ansprechen das ich im Designer erstellt habe... nur wenn ich es so eintrage bekomme ich dann Meldung das ers nicht findet...
kann mir da jemand weiter helfen???
Re: Frage zum Scribble Example
Verfasst: 12. März 2008 14:28
von neuschi
Qt-nator hat geschrieben:
mein Problem ist jetzt ich muss mein Widget damit ansprechen das ich im Designer erstellt habe... nur wenn ich es so eintrage bekomme ich dann Meldung das ers nicht findet...
kann mir da jemand weiter helfen???
Dazu müsste man wissen, wie du den Dialog aufgebaut hast, d.h. welchen der Ansätze aus
http://doc.trolltech.com/4.3/designer-u ... processing
du verwendest.
Hast du im Konstruktor deines ParameterToolWidgets sowas wie
oder
stehen?
Angenommen dein Widget aus dem Designer heisst "zeichenflaeche", dann müsstest du entweder
oder
nehmen.
\Ralf
Re: Frage zum Scribble Example[gelöst]
Verfasst: 20. Juni 2012 18:10
von Saul
Ist es möglich mithilfe des scribble beispiels auf ein label zu zeichnen, anstatt auf das komplette widget?
Beispielsweise:
Mein Ziel ist es auf ein Bild zu zeichen, welches ich vorher aus einer datei im entsprechenden label geladen habe.
Re: Frage zum Scribble Example[gelöst]
Verfasst: 27. Juni 2012 08:20
von franzf
Zeichnen auf ein Widget geht nur im dessen paintEvent. Einen painter auf einem fremden Widget aufmachen geht nicht.
Um nur auf das Bild zu zeichnen:
Code: Alles auswählen
QPixmap pix = label->pixmap();
{
QPainter p(&pix);
// Mit dem painter malen
}
label->setPixmap(pix);
Re: Frage zum Scribble Example[gelöst]
Verfasst: 10. Juli 2012 16:31
von Saul
Hi franzf,
danke für deine Hilfe.
Ich hab nur ein kleines Problem, das ich nicht weiß, wie ich die const Pixmap von ui.label in die neue Pixmap pix convertiere. Da meckert nämlich der compiler =(
Code: Alles auswählen
QPixmap pix = ui.label->pixmap();
{
QPainter p(&pix);
// Mit dem painter malen
}
ui.label->setPixmap(pix);
Ansonsten sollte das zeichen dann mit folgender Funktion aus der Qt Reference Documentation funktionieren.
Code: Alles auswählen
void QPaintEngine::drawImage ( const QRectF & rectangle, const QImage & image, const QRectF & sr, Qt::ImageConversionFlags flags = Qt::AutoColor ) [virtual]
// Reimplement this function to draw the part of the image specified by the sr rectangle in
// the given rectangle using the given conversion flags flags, to convert it to a pixmap.
Re: Frage zum Scribble Example[gelöst]
Verfasst: 10. Juli 2012 17:07
von franzf
Sry, QLabel::pixmap() gibt natürlich einen Zeiger zurück.
Re: Frage zum Scribble Example[gelöst]
Verfasst: 11. Juli 2012 10:54
von Saul
Jap, das mit dem Zeiger hatte ich gestern schon ausprobiert.
Aber leider ohne erfolg, denn dann bekomm ich eine Zugriffsverletzung =(
Re: Frage zum Scribble Example[gelöst]
Verfasst: 11. Juli 2012 11:46
von franzf
Ich hatte angenommen, das Label hat unter allen Umständen bereits ein Pixmap gesetzt. Wenn dem nicht so ist, musst du halt mit einem Zeiger arbeiten:
Code: Alles auswählen
QPixmap const *pix = ui.label->pixmap();
if(pix) {
QPixmap painterPix(*p);
QPainter p(&painterPix);
// malen
ui.label->setPixmap(painterPix);
}
Re: Frage zum Scribble Example[gelöst]
Verfasst: 11. Juli 2012 16:07
von Saul
Hi franzf
Wenn ich es jetzt wie folgt löse, kann ich gar nicht malen
Code: Alles auswählen
void FoSe::paintEvent(QPaintEvent *event)
{
//QPainter painter(this);
//QRect dirtyRect = event->rect();
//painter.drawImage(dirtyRect, image, dirtyRect);
QRectF target(0.0, 0.0, 800.0, 600.0);
QRectF source(0.0, 0.0, 800.0, 600.0);
QImage image("bild.png");
ui.label->setPixmap(QPixmap::fromImage(image));
QPixmap pix = *ui.label->pixmap();
{
QPainter p(&pix);
p.drawImage(target, image, source);
}
ui.label->setPixmap(pix);
}
Wenn ich die Kommentare beim painter wegnehme, malt man wieder aufs komplette widget und nicht aufs bild =(
(siehe Anhang)
Re: Frage zum Scribble Example[gelöst]
Verfasst: 11. Juli 2012 18:02
von franzf
Warum bist du jetzt plötzlich im paintEvent? Wenn du auf ein Pixmap drauf zeichnen willst, leg dir eine eigene Funktion an (ein SLOT bietet sich an), in der du das tust und das neue Bild ins Label setzt.
Willst du direkt auf ein Widget malen, geht das nur in dessen paintEvent, du müsstest also Ableiten.
Und wenn du den painter da so auf this aufmachst, malt der auch auf "this" (also FoSe-Instanz) und nicht ins Label. Das Label ist ein child und liegt über dem FoSe-Objekt, malt seine Inhalte (das Bild) also auch darüber.
Und was bitte bringt es, ein Bild nochmal auf sich selbst zu zeichnen? Natürlich sieht man dann nichts.
Re: Frage zum Scribble Example[gelöst]
Verfasst: 12. Juli 2012 11:40
von Saul
Hi franzf,
also irgendwie versteh ich die ganze Sache noch nicht =(
Ich erhalte jetzt mittels mousePressEvent() und mouseMoveEvent() die entsprechenden Koordinaten für die zu zeichnende Linie.
Die Funktion drawLineTo() zeichnet dann die Linie zwischen den von der Maus erhaltenen Koordinaten auf das Bild, welches mittels bildLaden() geöffnet wird.
Code: Alles auswählen
void ProgNeu::bildLaden()
{
QImage image("bild.png");
ui.label->setPixmap(QPixmap::fromImage(image));
}
Code: Alles auswählen
void ProgNeu::drawLineTo(const QPoint &endPoint)
{
//QPainter painter(&image);
QPixmap pix = *ui.label->pixmap();
{
QPainter painter(&pix);
painter.setPen(QPen(myPenColor, myPenWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
painter.drawLine(lastPoint, endPoint);
modified = true;
int rad = (myPenWidth / 2) + 2;
update(QRect(lastPoint, endPoint).normalized().adjusted(-rad, -rad, +rad, +rad));
lastPoint = endPoint;
}
ui.label->setPixmap(pix);
}
void ProgNeu::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
lastPoint = event->pos();
scribbling = true;
}
}
void ProgNeu::mouseMoveEvent(QMouseEvent *event)
{
if ((event->buttons() & Qt::LeftButton) && scribbling)
drawLineTo(event->pos());
}
Jetzt habe ich noch zwei Probleme:
Zum einen erhalte ich die Maus-Koordinaten vom Widget und nicht vom Label. D.h. das ich mit einem Versatz zum Mauszeiger male (siehe rotes Rechteck im Anhang) und auch gemalt wird, wenn sich der Mauszeiger außerhalb des Labels befindet.
Und zum anderen versucht mein Prog von Anfang an auf das Label zu zeichnen, anstatt wie gewollt erst zu zeichnen wenn das Bild mittel Button geladen wurde ( connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(bildLaden())); ). Logischerweise stürtzt das Programm ab, wenn das Bild noch nicht geladen wurde.
Es muss doch auch möglich sein, den MouseEvent erst in meiner bildLaden() Funktion aufzurufen oder?
Re: Frage zum Scribble Example[gelöst]
Verfasst: 13. Juli 2012 17:47
von franzf
Saul hat geschrieben:Zum einen erhalte ich die Maus-Koordinaten vom Widget und nicht vom Label. D.h. das ich mit einem Versatz zum Mauszeiger male (siehe rotes Rechteck im Anhang) und auch gemalt wird, wenn sich der Mauszeiger außerhalb des Labels befindet.
Die QWidget::map...-Funktionen anschauen und raten (oder verstehen

) welche du brauchst.
Und zum anderen versucht mein Prog von Anfang an auf das Label zu zeichnen,
Klar - es empfängt halt paintEvents
anstatt wie gewollt erst zu zeichnen wenn das Bild mittel Button geladen wurde ( connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(bildLaden())); ). Logischerweise stürtzt das Programm ab, wenn das Bild noch nicht geladen wurde.
Hast du denn noch immer irgendwo ein eigenes paintEvent stehen?
Da ich wenig Lust auf Raten habe bitte mal den kompletten Code in ein zip packen und anhängen (Code sagt mehr als tausend Bildchen).
Es muss doch auch möglich sein, den MouseEvent erst in meiner bildLaden() Funktion aufzurufen oder?
Nö - wie denn? Die MausEvents werden VERTEILT - irgend jemand (nicht du!) schickt dem Widget ein Event. Dahinter steht in den allermeisten Fällen das Windowing System, das dir dankenswerterweise Qt einfach wegkapselt.
Deine Aufgabe besteht jetzt eigentlich nur darin, dafür zu sorgen dass nichts doofes/unvorhergesehenes passiert und die Corner-Cases (oops, noch kein Bild geladen) abgefangen werden bzw. erst gar nicht auftreten.
Re: Frage zum Scribble Example[gelöst]
Verfasst: 24. Juli 2012 14:01
von Saul
Hi franzf,
hm also eine QWidget::map...-Funktionen besitze ich nicht =(
Du gibts mir Rätels auf, die ich leider nicht verstehe =)
Also in meinem Projekt ist kein paintEvent mehr vorhanden. Nur noch die mouseEvents um die Aktionen der Mouse abzufangen. Der oben gepostete Code entspricht eigentlich dem gesamten Code meines Projekts, aber ich hänge meine Projektdateien mal als Anhang dazu.
Wäre wirklich sehr nett wenn du mal reinschnuppern könntest.
Re: Frage zum Scribble Example[gelöst]
Verfasst: 24. Juli 2012 14:50
von franzf
Assistant aufmachen, Doku zu QWidget öffnen und einfach mal nach "map" suchen lassen. Es gibt DREI Funktionen die mit map anfangen, eine davon wird dir helfen...