KDE Anwendungs Tutorials: Der KDE Anwendungs-Tutorial Leitfaden für die Integrierte Entwicklungsumgebung KDevelop | ||
---|---|---|
Zurück | Kapitel 11. Erweiterte Ansichten | Vor |
In diesem Abschnitt werden wir eine Funktionalität implementieren, die meistens zum Kreuz für die Entwickler wird - wenn Sie nicht auf bereits implementierte Widgets zurückgreifen können, die das Rollen schon mitbringen. Was bedeutet Rollen? In unserem Kontext beginnt das Problem damit, das wir ein Bild öffnen wollen, das viel größer als der darstellbare Bereich ist. Beginnend von der oberen, linken Ecke, wird der Rest des Bildes aus der Sicht des Benutzers ausgeschnitten. Eine Rollansicht ist ein Widget, das auf der rechten und unteren Seite Rollbalken zur Verfügung stellt, mit deren Hilfe der Benutzer den Inhalt des Fensters verschieben kann. Tatsächlich wird das Dokument in seiner ganzen Größe gezeigt, aber die Ansicht kann innerhalb des Dokuments bewegt werden, sodaß jeder Teil mit Hilfe der Scrollbars angezeigt werden kann. Glücklicherweise gibt es in Qt die Klasse QScrollView,die selber von QWidget abgeleitet ist und die gleiche Grundfunktionalität wie ein gewöhnliches Widget bietet, jedoch den Inhalt der Ansicht bei der Verwendung von Scrollbars verwaltet - mit der zusätzlichen Option, daß der Programmierer entweder einfach nur eine Instanz von QScrollView verwendet, die zu verwaltenden Kindfenster mit der Rollansicht als Eltern erstellt und sie mit addChild() der Rollansicht hinzufügt, oder eine Ansicht von QScrollView ableitet und dann, statt direkt in das Widget, in den Viewport zeichnet, der ein definierter Bereich innerhalb der Rollansicht ist. Der Unterschied hier ist, daß QScrollView einen Satz von Ereignisbehandlungsroutinen, ähnlich denen von QWidget, extra für den Viewport bereitstellt. Das was also vorher mousePressEvent() in unserer Ansicht war, ist jetzt ein viewportMousePressEvent, ein paintEvent() wird zu einem viewportPaintEvent usw. . Die zweite der genannten Möglichkeiten passt auf unsere Anforderungen, wir werden also folgendene Modifikationen vornehmen, um KScribbleView zu einem rollbaren Widget zu machen:
Zunächst müssen wir das Dokument der Größe seines Inhalts anpassen. Dies kann erreicht werden, indem wir uns die Größe des geöffneten Bildes holen, für ein neues Bild müssen wir eine Standardgröße definieren. In anderen Zeichenanwendungen kann diese Größe meistens durch ein Kommando des Benutzerinterfaces, z.B. in einem Dialog, der nach der neuen Höhe und Breite fragt, sowie einer Methode zur Anpassung des Bildes an diese Werte, geändert werden.
Ändern der Elternklasse für KScribbleView von QWidget nach QScrollView.
Umbenennen der virtuellen Methoden in die entsprechenden Viewportmethoden aus QScrollView.
Adaptieren der virtuellen Event Handler, sodaß sie die Geometrie des Viewports beeinflussen. Das bedeutet, daß die alte Implementation auf die Geometrie von QWidget vertraut, die in der linken, oberen Ecke eines Widgets beginnt. Wenn die Ansicht gerollt wird und diese Ecke ist nicht sichtbar, müssen wir dafür sorgen, daß die von QWidget gelieferten Positionen in Viewportkoordinaten übersetzt werden.
Wie bereits erwähnt, müssen wir sowohl die Größe eines Dokuments ändern, als auch diese Größe initialisieren, und wir müssen eine Methode bereitstellen, die diese Größe für die Ansichten holt. Dazu fügen wir die Variable QSize size sowie die Methode docSize() in KScribbleDoc ein:
1 kscribbledoc.h: 2 3 #include <qsize.h> 4 5 ... 6 public: 7 const QSize docSize(){ return size;}; 8 9 private: 10 QSize size; |
Jetzt müssen wir alle Methoden, die Dokumentinhalte öffnen oder initialisieren, modifizieren.Dies sind newDocument() und openDocument():
1 bool KScribbleDoc::newDocument() 2 { 3 ///////////////////////////////////////////////// 4 // TODO: Add your document initialization code here 5 -> size=QSize(300,200 ); 6 pen=QPen( Qt::black, 3 ); 7 -> buffer.resize(size); 8 -> buffer.fill( Qt::white ); 9 ///////////////////////////////////////////////// 10 modified=false; 11 return true; 12 } 13 14 bool KScribbleDoc::openDocument(const QString &&;filename, const char *format /*=0*/) 15 { 16 17 QFile f( filename ); 18 // if ( !f.open( IO_ReadOnly ) ) 19 // return false; 20 ///////////////////////////////////////////////// 21 // TODO: Add your document opening code here 22 if(!buffer.load( filename, format )) 23 return false; 24 -> size=buffer.size(); 25 ///////////////////////////////////////////////// 26 // f.close(); 27 28 modified=false; 29 m_filename=filename; 30 m_title=QFileInfo(f).fileName(); 31 return true; 32 } |
In newDocument() initialisieren wir die Größe mit Standardwerten von 300 Pixeln Breite und 200 Pixeln Höhe. Das ist genug für ein kleines Bild und wir könnten auch immer noch einen Dialog zur Größenänderung hinzufügen. Wenn es daran geht, das Bild zu öffnen, müssen wir die Größe auf die des Bildes setzen. Dies kann man erreichen, indem man QPixmap::size() aufruft, was wir bereits in openDocument() verwendet haben. Dann sind mit dem Setzen der Größen fertig, und wir können damit beginnen, KScribbleView zu reimplementieren und eine Rollansicht daraus zu machen.