Das K Desktop Environment

11.2. Rollbare Ansichten

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:

11.2.1. Größe des Dokumentinhalts verändern

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.