Qt: paintEvent wird scheinbar nicht ausgeführt
-
Hi,
der Code wird zwar fehlerlos kompeliert, allerdings bleibt das Fenster "leer", also kein Punkt wird gezeichnet. Vermutlich ist der Fehler schnell gefunden, aber bin halt Qt-mäßig ziemlicher Anfänger und muss dann halt bisschen improvisieren.//////MainWindow #include <QMainWindow> #include "Painter.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); void RepaintWin(); private: Ui::MainWindow *ui; Painter *painter; }; #endif // MAINWINDOW_H ////Painter.h #ifndef PAINTER_H #define PAINTER_H #include <QPainter> #include <QFrame> class Painter : public QWidget { Q_OBJECT public: explicit Painter(QWidget *parent=0); ~Painter(){}; protected: void paintEvent(QPaintEvent *e); }; #endif // PAINTER_H ////MainWindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); painter = new Painter(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::RepaintWin() { painter->repaint(); } /////Paint.cpp #include "Painter.h" Painter::Painter(QWidget *parent) : QWidget(parent) {} void Painter::paintEvent(QPaintEvent *e) { QPen pen(Qt::black,5,Qt::SolidLine); QPainter p; p.begin(this); p.setPen(pen); p.drawPoint(10,200); p.end(); } /////main.cpp #include <QtGui/QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.RepaintWin(); w.show(); return a.exec(); }
-
Dein Painter-Objekt liegt einfach "irgendwie" über dem MainWindow. Ich nehme an mit einer Größe von 0x0...
Verwende Layouts. Oder pack das Painter-Objekt gleich als centralWidget ins Fenster.
-
arghonaut schrieb:
Oder pack das Painter-Objekt gleich als centralWidget ins Fenster.
Bleibt nur die Frage, wie das geht? Hab da keinen Plan, kennt den irgendjemand ein Tutorial oder so dazu. Generell wäre en gutes Qt-Tutorial mal ganz nützlich...
-
Testris schrieb:
Generell wäre en gutes Qt-Tutorial mal ganz nützlich...
Schon mal einen Blick auf diese Seiten geworfen? Die sind sehr gut für Anfänger geeignet:
http://qt.nokia.com/learning/elearning/
http://developer.qt.nokia.com/doc/qt-4.8/tutorials.html
-
Hmm, da werden ja eher einzelne Beispiel erklärt, als richitg mit Qt zu programmieren. Eine Antwort würde mir aber schon mal helfen. Also, zB, angenommen man will eine Apllikation prog., mit der man eine Funktion plotten kann, allerdings so, dass sie "zeitlich" gezeichnet wird (->"Simulationshaft", hoofe ihr wisst was ich meine). Die App soll natürlich auch ein halbwegs gutes Interface haben, also Menuleiste, DockWidgets, vlt MDIs und in der Mitte dann die "Zeichenebene"(bei WinApi wars der Gerätekontext), wenn ichs jz soweit verstanden hab, als centralWidget. Lieg ich jetzt richtig mit der Annahme, dass diese "Zeichenebene" eine Instanz von QLayout ist, oder worauf "malt man am besten"?
-
Testris schrieb:
Hmm, da werden ja eher einzelne Beispiel erklärt, als richitg mit Qt zu programmieren.
Wie stellst du dir den so ein Tutorial vor? Ich finde damit hast du die perfekte Ausrüstung zum loslegen. Diese "einzelnen" Beispiele verwenden die wichtigsten Klassen die du öfters mal begegnen wirst, wenn du Qt verwendest.
Du musst deine Painter als zentrales Widget setzen ( setCentralWidget() )
Du kannst das aber auch über den Designer machen wenn du schon damit arbeitest.
In deinem QMainWindow in die Fläche wo du die Zeichnung später sehen willst ziehst du ein QWidget hinein, mit Rechtsklick kannst du dann dieses Widget als Platzhalter für eine andere, eigene Klasse festlegen ( im kommenden Dialog trägst du dann deine Painter-Klasse ein )Testris schrieb:
Lieg ich jetzt richtig mit der Annahme, dass diese "Zeichenebene" eine Instanz von QLayout ist, oder worauf "malt man am besten"?
Nein, es ist eine Instanz deiner Painter-Klasse und darauf wird auch gezeichnet, weil du den paintEvent()-Handler der Painter-Klasse bzw. der darüberliegenden QWidget-Klasse reimplementiert hast :
http://developer.qt.nokia.com/doc/qt-4.8/qwidget.html#paintEvent
http://www.youtube.com/watch?v=5JE5ek_oN_0
-
[quote="phcn.fraggle"]
Du musst deine Painter als zentrales Widget setzen ( setCentralWidget() )Du kannst das aber auch über den Designer machen wenn du schon damit arbeitest.
In deinem QMainWindow in die Fläche wo du die Zeichnung später sehen willst ziehst du ein QWidget hinein, mit Rechtsklick kannst du dann dieses Widget als Platzhalter für eine andere, eigene Klasse festlegen ( im kommenden Dialog trägst du dann deine Painter-Klasse ein )
[quote="phcn.fraggle"]Ok Danke :), das funktioniert schon mal. Hab aber noch eine Frage zu einem Beispiel : http://doc.qt.nokia.com/4.7-snapshot/painting-concentriccircles.html
Hier wird ja mittels connect() über das Timeout-Signal eines Timers indirekt paintEvent() ausgelöst. Liegt wohl sehr wahrscheinlich zum einen an der Abspielgeschwindigkeit-das die Animation überhaupt wahrnehmbar ist- und 2. dass sich das Prog. nicht "aufhängt". Ich finds aber sehr seltsam das die Zeile "timer->start(100)", die ja den Timer erst startet, sich im Konstruktor der Hauptklasse und zudem in keinem "Schleifen-Konstrukt" steckt! Die Zeile dürfte doch nur ein einziges mal im ganzen Programmdurchlauf aufgerufen werden,aber erst wegen ihr wird doch DAUERND paintEvent() aufgerufen??Testris
-
timer ist ein zeiger auf eine Adresse bei der dann die "echte" struktur QTimer hinterlegt ist.
Diese ist persistent(d.h. überlebt das verlassen des Konstruktors) da sie dynamisch alloziert worden ist.
Beim connect wird dann der inhalt von timer kopiert(d.h. die nachwievor legale adresse) und daher funktioniert das ganze.
-
Achso alles klar. Danke