QT 4.0 Problem
-
Hallo Leute,
ich lerne momentan QT - dies aber leider mit einem veralteten Programmierbuch, dass lediglich die QT-Versionen 1.4 bzw. 2.0 behandelt. Da ich auf meinem Computer aber QT 4 installiert habe sind nicht immer alle Codes aus meinem Buch auch compilierbar bzw. führen mich zum gewünschten Erfolg.
Gerade habe ich angefangen ein ScribbleProgramm in QT zu schreiben, dass zwar sogar compiliert, bei dem aber leider immer nur eine Linie Gezeichnet und gleichzeitig angezeigt werden kann.
Wie kann ich das Programm dazu bringen, auch die alten Linien weiterhin anzuzeigen?
Danke schon mal für eure Hilfe im Vorraus.
Angefügt übrigens noch der Quellcode:
#include <QApplication> #include <QWidget> #include <QPainter> #include <QPaintEvent> #include <QMouseEvent> #include <iostream> class ScribbleWindow : public QWidget { public: ScribbleWindow(); protected: virtual void mousePressEvent(QMouseEvent* event); virtual void mouseMoveEvent(QMouseEvent* event); virtual void paintEvent(QPaintEvent* event); private: QPainter windowpainter; QPoint _last; QPoint _current; }; ScribbleWindow::ScribbleWindow() { } void ScribbleWindow::mousePressEvent(QMouseEvent* event) { _last = event->pos(); } void ScribbleWindow::mouseMoveEvent(QMouseEvent* event) { _current = event->pos(); update(); } void ScribbleWindow::paintEvent(QPaintEvent* event) { windowpainter.begin(this); windowpainter.drawLine(_last, _current); windowpainter.end(); } int main(int argc, char* argv[]) { QApplication myapp(argc, argv); ScribbleWindow* mywidget=new ScribbleWindow(); mywidget->setGeometry(100, 100, 500, 500); mywidget->show(); return myapp.exec(); }
-
zum dem buch würd ich mal sagen gaaaaanz weit weg packen. und den assistenten von qt nutzen, der ist sehr hilfreich.
zum deinem problem:
wenn du update() aufrufst wird das gasammte widget neu gezeichnet. da du aber deine linien nicht speicherst, sind sie nunmal weg.
Lösung ein Array (oder eine QList) verwenden und alle einträge speichern, dann im qpaintevent alles in einer schleife durchgehen und neu zeichnen, geht übrigens viel schneller als man es vermutet, man sieht es uch bei mehreren hundert linien nicht flimmern (test pc: centrino 1,6 GHz; 512 MB Ram; Grafik onboard; BS:Suse Linux 10.0)Wenn du es noch optimieren willst , es gibt eine funktion, mit der man nur einen bereich neu zeichnet (name hab ich grad nicht zur hand).
mfg Emperor_L0ser
-
Hallo Emperor und danke für deine Hilfe,
im Buch, dass ich benutze werden die Linien in eine Zusätliche QPixmap gezeichnet. Diese wird immer dann ausgegeben, wenn eine neue Linie gezeichnet wurde. Leider scheint es in QT 4.0 die Funktion bitBlt nicht mehr zu geben, mit der die Pixmap in den sichtbaren Bereich geschrieben wird. Gibt es in QT 4.0 vielleicht dazu noch eine Alternative? Die wäre vllt. sogar noch ein bischen einfacher.
-
Zaphod (nicht angemeldet) schrieb:
Hallo Emperor und danke für deine Hilfe,
im Buch, dass ich benutze werden die Linien in eine Zusätliche QPixmap gezeichnet. Diese wird immer dann ausgegeben, wenn eine neue Linie gezeichnet wurde. Leider scheint es in QT 4.0 die Funktion bitBlt nicht mehr zu geben, mit der die Pixmap in den sichtbaren Bereich geschrieben wird. Gibt es in QT 4.0 vielleicht dazu noch eine Alternative? Die wäre vllt. sogar noch ein bischen einfacher.
In Qt4 wird das automatisch gemacht. Man muss nicht mehr manuell bitBlt machen.
-
Warum benutzt du nicht die Tutorials von Trolltech zum lernen?
Und spaeter dann einfach die gute Doku der API?
-
Hallo,
leider habe ich es immer noch nicht geschafft, mein Problem zu lösen - scheinbar habe ich wirklich Tomaten auf den Augen, denn auch das Tutorial von Trolltech zu QT 4.0 konnte mir eine Lösung anbieten, die funktioniert. Dabei irritiert mich vor allem, dass es die Leute von Trolltech schaffen ein Scribbleprogramm zu schreiben, dass auf meinem Rechner läuft - ich aber nicht (auch nicht mit den Codes aus den QT-Examples). Anscheinend habe ich auch darin etwas übersehen.
Der Quelltext sieht im Mom. übrigens wie folgt aus:
#include <QApplication> #include <QWidget> #include <QPainter> #include <QPaintEvent> #include <QMouseEvent> #include <iostream> class ScribbleWindow : public QWidget { public: ScribbleWindow(); protected: virtual void mousePressEvent(QMouseEvent* event); virtual void mouseMoveEvent(QMouseEvent* event); virtual void mouseReleaseEvent(QMouseEvent* event); virtual void paintEvent(QPaintEvent* event); private: QImage image; QPoint _last; QPoint _current; }; ScribbleWindow::ScribbleWindow() { } void ScribbleWindow::mousePressEvent(QMouseEvent* event) { _last = event->pos(); } void ScribbleWindow::mouseMoveEvent(QMouseEvent* event) { _current = event->pos(); update(); } void ScribbleWindow::mouseReleaseEvent(QMouseEvent* event) { QPainter bufferpainter(&image); bufferpainter.drawLine(_last, _current); std::cout << "Maus losgelassen\n"; update(); } void ScribbleWindow::paintEvent(QPaintEvent* event) { QPainter windowpainter(this); windowpainter.drawImage(QPoint(0,0), image); windowpainter.drawLine(_last, _current); windowpainter.end(); } int main(int argc, char* argv[]) { QApplication myapp(argc, argv); ScribbleWindow* mywidget=new ScribbleWindow(); mywidget->setGeometry(100, 100, 500, 500); mywidget->show(); return myapp.exec(); }
Normalerweise sollten jeweils eine Linie auf das Widget sowie eine Linie in das QImage-Objekt geschrieben werden, dass dann, wenn die Maus losgelassen wird in das Widget geschrieben wird.
--Soweit dir Theorie. In der Praxis sieht das aber leider so aus, dass mir übers Terminal die Fehlermeldung: "QPainter::begin(), paintdevice returned engine == 0, type: 3" zurückgegeben wird.
Der Fehler versteckt sich übrigens in der Zeile, indem das QPainter-Objekt (bufferpainter) erzeugt wird. Wenn ich &image aus dieser Zeile entferne wird kein Fehler ausgegeben. Allergings kann dann auch kein "volles" Image-Ojekt mehr in das Widget geschrieben werden.
-
geh mal auf www.lostemp.de und lade dir den quellcode zu LinienZeichner 2 herunter, das programm machst ziemlich genau das, was du suchst. als reinschauen anschauen nachmachen