diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-23 09:34:13 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-03-23 09:34:13 (GMT) |
commit | 67ad0519fd165acee4a4d2a94fa502e9e4847bd0 (patch) | |
tree | 1dbf50b3dff8d5ca7e9344733968c72704eb15ff /doc/src/examples | |
download | Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.zip Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.gz Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.bz2 |
Long live Qt!
Diffstat (limited to 'doc/src/examples')
198 files changed, 35528 insertions, 0 deletions
diff --git a/doc/src/examples/2dpainting.qdoc b/doc/src/examples/2dpainting.qdoc new file mode 100644 index 0000000..31aea59 --- /dev/null +++ b/doc/src/examples/2dpainting.qdoc @@ -0,0 +1,224 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example opengl/2dpainting + \title 2D Painting Example + + The 2D Painting example shows how QPainter and QGLWidget can be used + together to display accelerated 2D graphics on supported hardware. + + \image 2dpainting-example.png + + The QPainter class is used to draw 2D graphics primitives onto + paint devices provided by QPaintDevice subclasses, such as QWidget + and QImage. + + Since QGLWidget is a subclass of QWidget, it is possible + to reimplement its \l{QWidget::paintEvent()}{paintEvent()} and use + QPainter to draw on the device, just as you would with a QWidget. + The only difference is that the painting operations will be accelerated + in hardware if it is supported by your system's OpenGL drivers. + + In this example, we perform the same painting operations on a + QWidget and a QGLWidget. The QWidget is shown with anti-aliasing + enabled, and the QGLWidget will also use anti-aliasing if the + required extensions are supported by your system's OpenGL driver. + + \section1 Overview + + To be able to compare the results of painting onto a QGLWidget subclass + with native drawing in a QWidget subclass, we want to show both kinds + of widget side by side. To do this, we derive subclasses of QWidget and + QGLWidget, using a separate \c Helper class to perform the same painting + operations for each, and lay them out in a top-level widget, itself + provided a the \c Window class. + + \section1 Helper Class Definition + + In this example, the painting operations are performed by a helper class. + We do this because we want the same painting operations to be performed + for both our QWidget subclass and the QGLWidget subclass. + + The \c Helper class is minimal: + + \snippet examples/opengl/2dpainting/helper.h 0 + + Apart from the constructor, it only provides a \c paint() function to paint + using a painter supplied by one of our widget subclasses. + + \section1 Helper Class Implementation + + The constructor of the class sets up the resources it needs to paint + content onto a widget: + + \snippet examples/opengl/2dpainting/helper.cpp 0 + + The actual painting is performed in the \c paint() function. This takes + a QPainter that has already been set up to paint onto a paint device + (either a QWidget or a QGLWidget), a QPaintEvent that provides information + about the region to be painted, and a measure of the elapsed time (in + milliseconds) since the paint device was last updated. + + \snippet examples/opengl/2dpainting/helper.cpp 1 + + We begin painting by filling in the region contained in the paint event + before translating the origin of the coordinate system so that the rest + of the painting operations will be displaced towards the center of the + paint device. + + We draw a spiral pattern of circles, using the elapsed time specified to + animate them so that they appear to move outward and around the coordinate + system's origin: + + \snippet examples/opengl/2dpainting/helper.cpp 2 + + Since the coordinate system is rotated many times during + this process, we \l{QPainter::save()}{save()} the QPainter's state + beforehand and \l{QPainter::restore()}{restore()} it afterwards. + + \snippet examples/opengl/2dpainting/helper.cpp 3 + + We draw some text at the origin to complete the effect. + + \section1 Widget Class Definition + + The \c Widget class provides a basic custom widget that we use to + display the simple animation painted by the \c Helper class. + + \snippet examples/opengl/2dpainting/widget.h 0 + + Apart from the constructor, it only contains a + \l{QWidget::paintEvent()}{paintEvent()} function, that lets us draw + customized content, and a slot that is used to animate its contents. + One member variable keeps track of the \c Helper that the widget uses + to paint its contents, and the other records the elapsed time since + it was last updated. + + \section1 Widget Class Implementation + + The constructor only initializes the member variables, storing the + \c Helper object supplied and calling the base class's constructor, + and enforces a fixed size for the widget: + + \snippet examples/opengl/2dpainting/widget.cpp 0 + + The \c animate() slot is called whenever a timer, which we define later, times + out: + + \snippet examples/opengl/2dpainting/widget.cpp 1 + + Here, we determine the interval that has elapsed since the timer last + timed out, and we add it to any existing value before repainting the + widget. Since the animation used in the \c Helper class loops every second, + we can use the modulo operator to ensure that the \c elapsed variable is + always less than 1000. + + Since the \c Helper class does all of the actual painting, we only have + to implement a paint event that sets up a QPainter for the widget and calls + the helper's \c paint() function: + + \snippet examples/opengl/2dpainting/widget.cpp 2 + + \section1 GLWidget Class Definition + + The \c GLWidget class definition is basically the same as the \c Widget + class except that it is derived from QGLWidget. + + \snippet examples/opengl/2dpainting/glwidget.h 0 + + Again, the member variables record the \c Helper used to paint the + widget and the elapsed time since the previous update. + + \section1 GLWidget Class Implementation + + The constructor differs a little from the \c Widget class's constructor: + + \snippet examples/opengl/2dpainting/glwidget.cpp 0 + + As well as initializing the \c elapsed member variable and storing the + \c Helper object used to paint the widget, the base class's constructor + is called with the format that specifies the \l QGL::SampleBuffers flag. + This enables anti-aliasing if it is supported by your system's OpenGL + driver. + + The \c animate() slot is exactly the same as that provided by the \c Widget + class: + + \snippet examples/opengl/2dpainting/glwidget.cpp 1 + + The \c paintEvent() is almost the same as that found in the \c Widget class: + + \snippet examples/opengl/2dpainting/glwidget.cpp 2 + + Since anti-aliasing will be enabled if available, we only need to set up + a QPainter on the widget and call the helper's \c paint() function to display + the widget's contents. + + \section1 Window Class Definition + + The \c Window class has a basic, minimal definition: + + \snippet examples/opengl/2dpainting/window.h 0 + + It contains a single \c Helper object that will be shared between all + widgets. + + \section1 Window Class Implementation + + The constructor does all the work, creating a widget of each type and + inserting them with labels into a layout: + + \snippet examples/opengl/2dpainting/window.cpp 0 + + A timer with a 50 millisecond time out is constructed for animation purposes, + and connected to the \c animate() slots of the \c Widget and \c GLWidget objects. + Once started, the widgets should be updated at around 20 frames per second. + + \section1 Running the Example + + The example shows the same painting operations performed at the same time + in a \c Widget and a \c GLWidget. The quality and speed of rendering in the + \c GLWidget depends on the level of support for multisampling and hardware + acceleration that your system's OpenGL driver provides. If support for either + of these is lacking, the driver may fall back on a software renderer that + may trade quality for speed. +*/ diff --git a/doc/src/examples/activeqt/comapp.qdoc b/doc/src/examples/activeqt/comapp.qdoc new file mode 100644 index 0000000..05f3fb5 --- /dev/null +++ b/doc/src/examples/activeqt/comapp.qdoc @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example activeqt/comapp + \title COM App Example (ActiveQt) + + The COM App example shows how to use ActiveQt to develop a Qt + application that can be automated via COM. Different QObject + based classes are exposed as COM objects that communicate with the + GUI of the running Qt application. The APIs of those COM objects + has been designed to resemble the APIs of standard COM + applications; i.e. those from Microsoft Office. + + \snippet examples/activeqt/comapp/main.cpp 2 + The first class \c Application represents the application object. It + exposes read-only properties \c documents and \c id to get access to the + list of documents, and an identifier. A read/write property \c visible + controls whether the QTabWidget-based user interface of the application + should be visible, and a slot \c quit() terminates the application. + + The \e RegisterObject attribute is set to make sure that instances of this + class are registered in COM's running object table (ROT) - this allows COM + clients to connect to an already instantiated COM object. + + \snippet examples/activeqt/comapp/main.cpp 1 + The \c DocumentList class stores a list of documents. It provides an API + to read the number of documents, to access each document by index and to + create a new document. The \c application property returns the root object. + + \snippet examples/activeqt/comapp/main.cpp 0 + + The \c Document class finally represents a document in the application. + Each document is represented by a page in the application's tab widget, and + has a title that is readable and writable through the document's API. + The \c application property again returns the root object. + + \snippet examples/activeqt/comapp/main.cpp 3 + The implementation of the \c Document class creates a new page for the tab + widget, and uses the title of that page for the title property. The page + is deleted when the document is deleted. + + \snippet examples/activeqt/comapp/main.cpp 4 + The \c DocumentList implementation is straightforward. + + \snippet examples/activeqt/comapp/main.cpp 5 + The \c Application class initializes the user interface in the constructor, + and shows and hides it in the implementation of \c setVisible(). The object + name (accessible through the \c id property) is set to \c "From QAxFactory" + to indicate that this COM object has been created by COM. Note that there is + no destructor that would delete the QTabWidget - this is instead done in the + \c quit() slot, before calling QApplication::quit() through a single-shot-timer, + which is necessary ensure that the COM call to the slot is complete. + + \snippet examples/activeqt/comapp/main.cpp 6 + The classes are exported from the server using the QAxFactory macros. Only + \c Application objects can be instantiated from outside - the other APIs can + only be used after accessing the respective objects throught the \c Application + API. + + \snippet examples/activeqt/comapp/main.cpp 7 + The main() entry point function creates a QApplication, and just enters the + event loop if the application has been started by COM. If the application + has been started by the user, then the \c Application object is created and + the object name is set to "From Application". Then the COM server is started, + and the application object is registered with COM. It is now accessible to + COM clients through the client-specific APIs. + + Application exiting is controlled explicitly - if COM started the application, + then the client code has to call quit(); if the user started the application, + then the application terminates when the last window has been closed. + + Finally, the user interface is made visible, and the event loop is started. + + A simple Visual Basic application could now access this Qt application. In VB, + start a new "Standard Exe" project and add a project reference to the comappLib + type library. Create a form with a listbox "DocumentList", a static label + "DocumentsCount" and a command button "NewDocument". Finally, implement the code + for the form like this: + + \snippet doc/src/snippets/code/doc_src_examples_activeqt_comapp.qdoc 0 + + To build the example you must first build the QAxServer library. + Then run \c qmake and your make tool in + \c{examples\activeqt\comapp}. +*/ diff --git a/doc/src/examples/activeqt/dotnet.qdoc b/doc/src/examples/activeqt/dotnet.qdoc new file mode 100644 index 0000000..afe7034 --- /dev/null +++ b/doc/src/examples/activeqt/dotnet.qdoc @@ -0,0 +1,355 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page activeqt-dotnet.html + \title Dot Net Example (ActiveQt) + + The Dot Net example demonstrates how Qt objects can be used in a + .NET environment, and how .NET objects can be used in a Qt + environment. + + If you need to combine Qt and Win Forms widgets in the same + application, you might want to use the higher-level + \l{QtWinForms Solution} instead. + + Contents: + + \tableofcontents + + \section1 Qt vs. .NET + + Qt is a C++ library and is compiled into traditional, native + binaries that make full use of the performance provided by the + runtime environment. + + One of the key concepts of .NET is the idea of "intermediate language + code" - the source code is compiled into a bytecode format, and at + runtime, that bytecode is executed in a virtual machine - the \e + {Common Language Runtime} (CLR). + + Another key concept is that of \e {managed code}. This is essentially + intermediate language code written in such a way that the CLR can take + care of the memory management, i.e. the CLR will do automatic garbage + collection, so the application code does not need to explicitly free + the memory for unused objects. + + The MS compilers for C# and VB.NET will only produce managed + code. Such programs cannot directly call normal, native functions + or classes. \footnote The .NET framework provides Platform Invocation + Services - P/Invoke - that enable managed code to call native C (not + C++) functions located in DLLs directly. The resulting application + then becomes partially unmanaged.\endfootnote + + The MS C++ compiler for .NET on the other hand, can produce both + normal and managed code. To write a C++ class that can be compiled + into managed code, the developer must flag the class as managed using + the \c __gc keyword, and restrict the code to only use the subset of + C++ known as "Managed Extensions for C++", or MC++ for short. The + advantage is that MC++ code can freely call and use normal C++ + functions and classes. And it also works the other way around: normal + C++ code can call managed functions and use managed classes (e.g. the + entire .NET framework class library), including managed functions and + classes implemented in C# or VB.NET. This feature of mixing managed + and normal C++ code immensely eases the interoperability with .NET, + and is by Microsoft referred to as the "It Just Works" (IJW) feature. + + This document demonstrates two different ways of integrating normal + C++ code (that uses Qt) with managed .NET code. First, the manual way + is presented, which includes using a thin MC++ wrapper class around + the normal Qt/C++ class. Then, the automated way is presented, which + utilizes the ActiveQt framework as a generic bridge. The advantage of + the first method is that it gives the application developer full + control, while the second method requires less coding and relieves the + developer of dealing with the conversion between managed and normal + data objects. + + The impatient reader, who right away wants to see a QPushButton + and a custom Qt widget (\l{activeqt/multiple}{QAxWidget2}) run in + a .NET GUI application is referred to the example directory of + ActiveQt. It contains the result of this walkthrough using both + C# and VB.NET, created with Visual Studio .NET (not 2003). + Load \c {examples/dotnet/walkthrough/csharp.csproj}, + \c {examples/dotnet/walkthrough/vb.vbproj} + or \c {examples/dotnet/wrapper/wrapper.sln} into the IDE and run + the solution. + + \bold{Remark:} You will notice that in the generated code the following line is + commented out: + + \snippet doc/src/snippets/code/doc_src_examples_activeqt_dotnet.qdoc 0 + + This line is regenerated without comment whenever you change the + dialog, in which case you have to comment it out again to be able + to run the project. This is a bug in the original version of + Visual Studio.NET, and is fixed in the 2003 edition. + + \section1 Walkthrough: .NET interop with MC++ and IJW + + Normal C++ classes and functions can be used from managed .NET code by + providing thin wrapper classes written in MC++. The wrapper class will + take care of forwarding the calls to the normal C++ functions or + methods, and converting parameter data as necessary. Since the wrapper + class is a managed class, it can be used without further ado in any + managed .NET application, whether written in C#, VB.NET, MC++ or other + managed programming language. + + \snippet examples/activeqt/dotnet/wrapper/lib/worker.h 0 + + The Qt class has nothing unusual for Qt users, and as even the Qt + specialities like \c Q_PROPERTY, \c slots and \c signals are + implemented with straight C++ they don't cause any trouble when + compiling this class with any C++ compiler. + + \snippet examples/activeqt/dotnet/wrapper/lib/networker.h 0 + + The .NET wrapper class uses keywords that are part of MC++ to indicate + that the class is managed/garbage collected (\c {__gc}), and that \c + StatusString should be accessible as a property in languages that + support this concept (\c {__property}). We also declare an event + function \c statusStringChanged(String*) (\c {__event}), the + equivalent of the respective signal in the Qt class. + + Before we can start implementing the wrapper class we need a way to + convert Qt's datatypes (and potentionally your own) into .NET + datatypes, e.g. \c QString objects need to be converted into objects + of type \c {String*}. + + When operating on managed objects in normal C++ code, a little extra + care must be taken because of the CLR's garbage collection. A normal + pointer variable should not \footnote Indeed, the compiler will in + many cases disallow it. \endfootnote be used to refer to a managed + object. The reason is that the garbage collection can kick in at any + time and move the object to another place on the heap, leaving you + with an invalid pointer. + + However, two methods are provided that solves this problem easily. The + first is to use a \e pinned pointer, i.e. declare the pointer variable + with the \c __pin keyword. This guarantees that the object pointed to + will not be moved by the garbage collector. It is recommended that + this method not be used to keep a references to managed objects for a + long time, since it will decrease the efficiency of the garbage + collector. The second way is to use the \c gcroot smartpointer + template type. This lets you create safe pointers to managed + objects. E.g. a variable of type \c gcroot<String> will always point + to the String object, even if it has been moved by the garbage + collector, and it can be used just like a normal pointer. + + \snippet examples/activeqt/dotnet/wrapper/lib/tools.cpp 0 + \codeline + \snippet examples/activeqt/dotnet/wrapper/lib/tools.cpp 1 + + The convertor functions can then be used in the wrapper class + implementation to call the functions in the native C++ class. + + \snippet examples/activeqt/dotnet/wrapper/lib/networker.cpp 0 + \codeline + \snippet examples/activeqt/dotnet/wrapper/lib/networker.cpp 1 + + The constructor and destructor simply create and destroy the Qt + object wrapped using the C++ operators \c new and \c delete. + + \snippet examples/activeqt/dotnet/wrapper/lib/networker.cpp 2 + + The netWorker class delegates calls from the .NET code to the native + code. Although the transition between those two worlds implies a small + performance hit for each function call, and for the type conversion, + this should be negligible since we are anyway going to run within the + CLR. + + \snippet examples/activeqt/dotnet/wrapper/lib/networker.cpp 3 + + The property setter calls the native Qt class before firing the + event using the \c __raise keyword. + + This wrapper class can now be used in .NET code, e.g. using C++, C#, + Visual Basic or any other programming language available for .NET. + + \snippet examples/activeqt/dotnet/wrapper/main.cs 0 + \snippet examples/activeqt/dotnet/wrapper/main.cs 1 + \snippet examples/activeqt/dotnet/wrapper/main.cs 2 + \snippet examples/activeqt/dotnet/wrapper/main.cs 3 + + \section1 Walkthrough: .NET/COM Interop with ActiveQt + + Fortunately .NET provides a generic wrapper for COM objects, the + \e {Runtime Callable Wrapper} (RCW). This RCW is a proxy for the + COM object and is generated by the CLR when a .NET Framework client + activates a COM object. This provides a generic way to reuse COM + objects in a .NET Framework project. + + Making a QObject class into a COM object is easily achieved with + ActiveQt and demonstrated in the QAxServer examples (e.g., the + \l{activeqt/simple}{Simple} example). The walkthrough will use + the Qt classes implemented in those examples, so the first thing + to do is to make sure that those examples have been built + correctly, e.g. by opening the + \l{qaxserver-demo-multiple.html}{demonstration pages} in Internet + Explorer to verify that the controls are functional. + + \section2 Starting a Project + + Start Visual Studio.NET, and create a new C# project for writing a + Windows application. This will present you with an empty form in + Visual Studio's dialog editor. You should see the toolbox, which + presents you with a number of available controls and objects in + different categories. If you right-click on the toolbox it allows + you to add new tabs. We will add the tab "Qt". + + \section2 Importing Qt Widgets + + The category only has a pointer tool by default, and we have to add + the Qt objects we want to use in our form. Right-click on the empty + space, and select "Customize". This opens a dialog that has two + tabs, "COM Components" and ".NET Framework Components". We used + ActiveQt to wrap QWidgets into COM objects, so we select the "COM + Components" page, and look for the classes we want to use, e.g. + "QPushButton" and "QAxWidget2". + + When we select those widgets and close the dialog the two widgets + will now be available from the toolbox as grey squares with their + name next to it \footnote Icons could be added by modifying the + way the controls register themselves. \endfootnote. + + \section2 Using Qt Widgets + + We can now add an instance of QAxWidget2 and a QPushButton to + the form. Visual Studio will automatically generate the RCW for the + object servers. The QAxWidget2 instance takes most of the upper + part of the form, with the QPushButton in the lower right corner. + + In the property editor of Visual Studio we can modify the properties + of our controls - QPushButton exposes the \c QWidget API and has many + properties, while QAxWidget2 has only the Visual Studio standard + properties in addition to its own property "lineWidth" in the + "Miscellaneous" category. The objects are named "axQPushButton1" and + "axQAxWidget21", and since especially the last name is a bit + confusing we rename the objects to "resetButton" and "circleWidget". + + We can also change the Qt properties, e.g. set the "text" property + of the \c resetButton to "Reset", and the "lineWidth" property of the + \c circleWidget to 5. We can also put those objects into the layout + system that Visual Studio's dialog editor provides, e.g. by setting + the anchors of the \c circleWidget to "Left, Top, Right, Bottom", and + the anchors of the \c resetButton to "Bottom, Right". + + Now we can compile and start the project, which will open a user + interface with our two Qt widgets. If we can resize the dialog, + the widgets will resize appropriately. + + \section2 Handling Qt Signals + + We will now implement event handlers for the widgets. Select the + \c circleWidget and select the "Events" page in the property + editor. The widget exposes events because the QAxWidget2 class has + the "StockEvents" attribute set in its class definition. We implement + the event handler \c circleClicked for the \c ClickEvent to increase + the line width by one for every click: + + \snippet examples/activeqt/dotnet/walkthrough/Form1.cs 0 + + In general we can implement a default event handler by double + clicking on the widget in the form, but the default events for + our widgets are right now not defined. + + We will also implement an event handler for the \c clicked signal + emitted by QPushButton. Add the event handler \c resetLineWidth to + the \c clicked event, and implement the generated function: + + \snippet examples/activeqt/dotnet/walkthrough/Form1.cs 1 + + We reset the property to 1, and also call the \c setFocus() slot + to simulate the user style on Windows, where a button grabs focus + when you click it (so that you can click it again with the spacebar). + + If we now compile and run the project we can click on the circle + widget to increase its line width, and press the reset button to + set the line width back to 1. + + \section1 Summary + + Using ActiveQt as a universal interoperability bridge between the + .NET world and the native world of Qt is very easy, and makes it + often unnecessary to implement a lot of handwritten wrapper classes. + Instead, the QAxFactory implementation in the otherwise completely + cross-platform Qt project provides the glue that .NET needs to to + generate the RCW. + + If this is not sufficient we can implement our own wrapper classes + thanks to the C++ extensions provided by Microsoft. + + \section2 Limitations + + All the limitations when using ActiveQt are implied when using this + technique to interoperate with .NET, e.g. the datatypes we can use + in the APIs can only be those supported by ActiveQt and COM. However, + since this includes subclasses of QObject and QWidget we can wrap + any of our datatypes into a QObject subclass to make its API + available to .NET. This has the positive side effect that the same + API is automatically available in + \l{http://qtsoftware.com/products/qsa/}{QSA}, the cross platform + scripting solution for Qt applications, and to COM clients in general. + + When using the "IJW" method, in priciple the only limitation is the + time required to write the wrapper classes and data type conversion + functions. + + \section2 Performance Considerations + + Every call from CLR bytecode to native code implies a small + performance hit, and necessary type conversions introduce an + additional delay with every layer that exists between the two + frameworks. Consequently every approach to mix .NET and native + code should try to minimize the communication necessary between + the different worlds. + + As ActiveQt introduces three layers at once - the RCW, COM and finally + ActiveQt itself - the performance penalty when using the generic + Qt/ActiveQt/COM/RCW/.NET bridge is larger than when using a + hand-crafted IJW-wrapper class. The execution speed however is still + sufficient for connecting to and modifying interactive elements in a + user interface, and as soon as the benefit of using Qt and C++ to + implement and compile performance critical algorithms into native code + kicks in, ActiveQt becomes a valid choice for making even non-visual + parts of your application accessible to .NET. + + \sa {QtWinForms Solution} +*/ diff --git a/doc/src/examples/activeqt/hierarchy-demo.qdocinc b/doc/src/examples/activeqt/hierarchy-demo.qdocinc new file mode 100644 index 0000000..9d0cb5e --- /dev/null +++ b/doc/src/examples/activeqt/hierarchy-demo.qdocinc @@ -0,0 +1,43 @@ +\raw HTML +//! [0] +<script language="javascript"> +function createSubWidget( form ) +{ + ParentWidget.createSubWidget( form.nameEdit.value ); +} + +function renameSubWidget( form ) +{ + var SubWidget = ParentWidget.subWidget( form.nameEdit.value ); + if ( !SubWidget ) { + alert( "No such widget " + form.nameEdit.value + "!" ); + return; + } + SubWidget.label = form.labelEdit.value; + form.nameEdit.value = SubWidget.label; +} + +function setFont( form ) +{ + ParentWidget.font = form.fontEdit.value; +} +</script> + +<p> +This widget can have many children! +</p> +<object ID="ParentWidget" CLASSID="CLSID:d574a747-8016-46db-a07c-b2b4854ee75c" +CODEBASE="http://qtsoftware.com/demos/hierarchy.cab"> +[Object not available! Did you forget to build and register the server?] +</object><br /> +<form> +<input type="edit" ID="nameEdit" value="<enter object name>" /> +<input type="button" value="Create" onClick="createSubWidget(this.form)" /> +<input type="edit" ID="labelEdit" /> +<input type="button" value="Rename" onClick="renameSubWidget(this.form)" /> +<br /> +<input type="edit" ID="fontEdit" value="MS Sans Serif" /> +<input type="button" value = "Set Font" onClick="setFont(this.form)" /> +</form> +//! [0] +\endraw diff --git a/doc/src/examples/activeqt/hierarchy.qdoc b/doc/src/examples/activeqt/hierarchy.qdoc new file mode 100644 index 0000000..868d0ce --- /dev/null +++ b/doc/src/examples/activeqt/hierarchy.qdoc @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qaxserver-demo-hierarchy.html + \title Qt Widget Hierarchy + + \input examples/activeqt/hierarchy-demo.qdocinc +*/ + +/*! + \example activeqt/hierarchy + \title Hierarchy Example (ActiveQt) + + The Hierarchy example is shows how to write an in-process ActiveX + control. The control is a QWidget subclass with child widgets + that are accessible as sub-types. + + \snippet examples/activeqt/hierarchy/objects.h 0 + The \c QParentWidget class provides slots to create a widget + with a name, and to return a pointer to a named widget. The class + declaration uses \c Q_CLASSINFO() to provide the COM identifiers for + this class. + + \snippet examples/activeqt/hierarchy/objects.cpp 0 + The constructor of QParentWidget creates a vertical box layout. + New child widgets are automatically added to the layout. + + \snippet examples/activeqt/hierarchy/objects.cpp 1 + The \c createSubWidget slot creates a new \c QSubWidget with + the name provided in the parameter, and sets the label to that + name. The widget is also shown explicitly. + + \snippet examples/activeqt/hierarchy/objects.cpp 2 + The \c subWidget slot uses the \c QObject::child() function and + returns the first child of type \c QSubWidget that has the requested + name. + + \snippet examples/activeqt/hierarchy/objects.h 1 + The \c QSubWidget class has a single string-property \c label, + and implements the paintEvent to draw the label. The class uses + again \c Q_CLASSINFO to provide the COM identifiers, and also sets + the \e ToSuperClass attribute to \e QSubWidget, to ensure that only + no slots of any superclasses (i.e. QWidget) are exposed. + + \snippet examples/activeqt/hierarchy/objects.cpp 3 + \snippet examples/activeqt/hierarchy/objects.cpp 4 + The implementation of the QSubWidget class is self-explanatory. + + \snippet examples/activeqt/hierarchy/main.cpp 0 + The classes are then exported using a QAxFactory. \c QParentWidget is + exported as a full class (which can be created ), while \c QSubWidget is + only exported as a type, which can only be created indirectly through + APIs of \c QParentWidget. + + To build the example you must first build the QAxServer library. + Then run qmake and your make tool in \c examples/activeqt/hierarchy. + + The \l{qaxserver-demo-hierarchy.html}{demonstration} requires + your WebBrowser to support ActiveX controls, and scripting to be + enabled. + + \snippet examples/activeqt/hierarchy-demo.qdocinc 0 +*/ diff --git a/doc/src/examples/activeqt/menus.qdoc b/doc/src/examples/activeqt/menus.qdoc new file mode 100644 index 0000000..6ce1625 --- /dev/null +++ b/doc/src/examples/activeqt/menus.qdoc @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qaxserver-demo-menus.html + \preliminary + + \title Menubar Merging + + This example is not full functional at the moment. + + \raw HTML + <object ID="QMenus" CLASSID="CLSID:4dc3f340-a6f7-44e4-a79b-3e9217695fbd" + CODEBASE="http://qtsoftware.com/demos/menusax.cab"> + [Object not available! Did you forget to build and register the server?] + </object> + \endraw +*/ + +/*! + \example activeqt/menus + \title Menus Example (ActiveQt) + + The Menus example demonstrates the use of QMenuBar and QStatusBar + in a QMainWindow to implement an in-place active control. + + To build the example you must first build the QAxServer library. + Then run \c qmake and your make tool in \c + examples/activeqt/menus. + + The \l{qaxserver-demo-menus.html}{demonstration} requires your + WebBrowser to support ActiveX controls, and scripting to be + enabled. + + \snippet doc/src/snippets/code/doc_src_examples_activeqt_menus.qdoc 0 +*/ diff --git a/doc/src/examples/activeqt/multiple-demo.qdocinc b/doc/src/examples/activeqt/multiple-demo.qdocinc new file mode 100644 index 0000000..ee174bf --- /dev/null +++ b/doc/src/examples/activeqt/multiple-demo.qdocinc @@ -0,0 +1,39 @@ +\raw HTML +//! [0] +<script language="javascript"> +function setColor( form ) +{ + Ax1.fillColor = form.colorEdit.value; +} + +function setWidth( form ) +{ + Ax2.lineWidth = form.widthEdit.value; +} +</script> + +<p /> +This is one QWidget subclass:<br /> +<object ID="Ax1" CLASSID="CLSID:1D9928BD-4453-4bdd-903D-E525ED17FDE5" +CODEBASE="http://qtsoftware.com/demos/multipleax.cab"> +[Object not available! Did you forget to build and register the server?] +</object><br /> +<form> +Fill Color: <input type="edit" ID="colorEdit" value = "red" /> +<input type="button" value = "Set" onClick="setColor(this.form)" /> +<input type="button" value = "Hide" onClick="Ax1.hide()" /> +<input type="button" value = "Show" onClick="Ax1.show()" /> +</form> + +<p /> +This is another QWidget subclass:<br /> +<object ID="Ax2" CLASSID="CLSID:58139D56-6BE9-4b17-937D-1B1EDEDD5B71" +CODEBASE="http://qtsoftware.com/demos/multipleax.cab"> +[Object not available! Did you forget to build and register the server?] +</object><br /> +<form> +Line width: <input type="edit" ID="widthEdit" value = "1" /> +<input type="button" value = "Set" onClick="setWidth(this.form)" /> +</form> +//! [0] +\endraw diff --git a/doc/src/examples/activeqt/multiple.qdoc b/doc/src/examples/activeqt/multiple.qdoc new file mode 100644 index 0000000..d15371b --- /dev/null +++ b/doc/src/examples/activeqt/multiple.qdoc @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qaxserver-demo-multiple.html + \title Two Simple Qt Widgets + + \input examples/activeqt/multiple-demo.qdocinc +*/ + +/*! + \example activeqt/multiple + \title Multiple Example (ActiveQt) + + The Multiple example demonstrates the implementation of a + QAxFactory to provide multiple ActiveX controls in a single in + process ActiveX server using the \c QAXFACTORY_EXPORT() macro. + The ActiveX controls in this example are simple QWidget + subclasses that reimplement QWidget::paintEvent(). + + \snippet examples/activeqt/multiple/ax1.h 0 + + The first control draws a filled rectangle. The fill color is exposed + as a property. \c Q_CLASSINFO() is used to specify the COM identifiers. + + \snippet examples/activeqt/multiple/ax2.h 0 + + The second control draws a circle. The linewith is exposed as a property. + \c Q_CLASSINFO() is used to specify the COM identifiers, and to set the + attributes \e ToSuperClass and \e StockEvents to expose only the API of + the class itself, and to add COM stock events to the ActiveX control. + + \snippet examples/activeqt/multiple/main.cpp 0 + + The classes are exported from the server using the QAxFactory macros. + + To build the example you must first build the QAxServer library. + Then run \c qmake and your make tool in \c + examples/activeqt/multiple. + + The \l{qaxserver-demo-multiple.html}{demonstration} requires your + WebBrowser to support ActiveX controls, and scripting to be + enabled. + + \snippet examples/activeqt/multiple-demo.qdocinc 0 +*/ diff --git a/doc/src/examples/activeqt/opengl-demo.qdocinc b/doc/src/examples/activeqt/opengl-demo.qdocinc new file mode 100644 index 0000000..44df0c4 --- /dev/null +++ b/doc/src/examples/activeqt/opengl-demo.qdocinc @@ -0,0 +1,27 @@ +\raw HTML +//! [0] +<SCRIPT LANGUAGE="JavaScript"> +function setRot( form ) +{ + GLBox.setXRotation( form.XEdit.value ); + GLBox.setYRotation( form.YEdit.value ); + GLBox.setZRotation( form.ZEdit.value ); +} +</SCRIPT> + +<p /> +An OpenGL scene:<br /> +<object ID="GLBox" CLASSID="CLSID:5fd9c22e-ed45-43fa-ba13-1530bb6b03e0" +CODEBASE="http://qtsoftware.com/demos/openglax.cab"> +[Object not available! Did you forget to build and register the server?] +</object><br /> + +<form> +Rotate the scene:<br /> +X:<input type="edit" ID="XEdit" value="0" /><br /> +Y:<input type="edit" name="YEdit" value="0" /><br /> +Z:<input type="edit" name="ZEdit" value="0" /><br /> +<input type="button" value="Set" onClick="setRot(this.form)" /> +</form> +//! [0] +\endraw diff --git a/doc/src/examples/activeqt/opengl.qdoc b/doc/src/examples/activeqt/opengl.qdoc new file mode 100644 index 0000000..05c9d08 --- /dev/null +++ b/doc/src/examples/activeqt/opengl.qdoc @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qaxserver-demo-opengl.html + + \title OpenGL in an HTML page + + \raw HTML + <SCRIPT LANGUAGE="JavaScript"> + function setRot( form ) + { + GLBox.setXRotation( form.XEdit.value ); + GLBox.setYRotation( form.YEdit.value ); + GLBox.setZRotation( form.ZEdit.value ); + } + </SCRIPT> + + <p /> + An OpenGL scene:<br /> + <object ID="GLBox" CLASSID="CLSID:5fd9c22e-ed45-43fa-ba13-1530bb6b03e0" + CODEBASE="http://qtsoftware.com/demos/openglax.cab"> + [Object not available! Did you forget to build and register the server?] + </object><br /> + + <form> + Rotate the scene:<br /> + X:<input type="edit" ID="XEdit" value="0" /><br /> + Y:<input type="edit" name="YEdit" value="0" /><br /> + Z:<input type="edit" name="ZEdit" value="0" /><br /> + <input type="button" value="Set" onClick="setRot(this.form)" /> + </form> + \endraw +*/ + +/*! + \example activeqt/opengl + \title OpenGL Example (ActiveQt) + + The OpenGL example demonstrates the use of the default factory + and QAxFactory::isServer(), and the implementation of an + additional COM interface using QAxBindable and QAxAggregated. + The server executable can run both as an ActiveX server and as a + stand-alone application. + + The ActiveX control in this example uses the QGlWidget class in + Qt to render an OpenGL scene in an ActiveX. The control exposes a few + methods to change the scene. + + The application uses the default factory as provided by the + QAXFACTORY_DEFAULT macro to expose the \c GLBox widget as an ActiveX + control. + \snippet examples/activeqt/opengl/main.cpp 0 + The implementation of \c main initializes the QApplication object, + and uses \c QAxFactory::isServer() to determine whether or not it is + appropriate to create and show the application interface. + \snippet examples/activeqt/opengl/main.cpp 1 + \snippet examples/activeqt/opengl/main.cpp 2 + \snippet examples/activeqt/opengl/main.cpp 3 + + The \c GLBox class inherits from both the \l QGLWidget class to be able + to render OpenGL, and from \l QAxBindable. + \snippet examples/activeqt/opengl/glbox.h 0 + The class reimplements the \l QAxBindable::createAggregate() function from QAxBindable + to return the pointer to a \l QAxAggregated object. + \snippet examples/activeqt/opengl/glbox.h 1 + The rest of the class declaration and the implementation of the OpenGL + rendering is identical to the original "box" example. + + The implementation file of the \c GLBox class includes the \c objsafe.h + system header, in which the \c IObjectSafety COM interface is defined. + \snippet examples/activeqt/opengl/glbox.cpp 0 + A class \c ObjectSafetyImpl is declared using multiple inheritance + to subclass the QAxAggregated class, and to implement the IObjectSafety + interface. + \snippet examples/activeqt/opengl/glbox.cpp 1 + The class declares a default constructor, and implements the queryInterface + function to support the IObjectSafety interface. + \snippet examples/activeqt/opengl/glbox.cpp 2 + Since every COM interface inherits \c IUnknown the \c QAXAGG_IUNKNOWN macro + is used to provide the default implementation of the \c IUnknown interface. + The macro is defined to delegate all calls to \c QueryInterface, \c AddRef + and \c Release to the interface returned by the controllingUnknown() function. + \snippet examples/activeqt/opengl/glbox.cpp 3 + The implementation of the \c IObjectSafety interface provides the caller + with information about supported and enabled safety options, and returns + \c S_OK for all calls to indicate that the ActiveX control is safe. + \snippet examples/activeqt/opengl/glbox.cpp 4 + The implementation of the \c createAggregate() function just returns a new + \c ObjectSafetyImpl object. + \snippet examples/activeqt/opengl/glbox.cpp 5 + + To build the example you must first build the QAxServer library. + Then run \c qmake and your make tool in \c + examples/activeqt/wrapper. + + The \l{qaxserver-demo-opengl.html}{demonstration} requires your + WebBrowser to support ActiveX controls, and scripting to be + enabled. + + In contrast to the other QAxServer examples Internet Explorer will not + open a dialog box to ask the user whether or not the scripting of the GLBox + control should be allowed (the exact browser behaviour depends on the security + settings in the Internet Options dialog). + + \snippet doc/src/examples/activeqt/opengl-demo.qdocinc 0 +*/ diff --git a/doc/src/examples/activeqt/qutlook.qdoc b/doc/src/examples/activeqt/qutlook.qdoc new file mode 100644 index 0000000..c29feeb --- /dev/null +++ b/doc/src/examples/activeqt/qutlook.qdoc @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example activeqt/qutlook + \title Qutlook Example (ActiveQt) + + The Qutlook example demonstrates the use of ActiveQt to automate + Outlook. The example makes use of the \l dumpcpp tool to generate + a C++ namespace for the type library describing the Outlook + Object Model. + + The project file for the example looks like this: + + \snippet examples/activeqt/qutlook/qutlook.pro 1 + \snippet examples/activeqt/qutlook/qutlook.pro 2 + + The project file uses the \c dumpcpp tool to add an MS Outlook type library to the project. + If this fails, then the generated makefile will just print an error message, otherwise + the build step will now run the \e dumpcpp tool on the type library, and + generate a header and a cpp file (in this case, \c msoutl.h and \c msoutl.cpp) that + declares and implement an easy to use API to the Outlook objects. + + \snippet examples/activeqt/qutlook/addressview.h 0 + + The AddressView class is a QWidget subclass for the user interface. The QTreeView widget + will display the contents of Outlook's Contact folder as provided by the \c{model}. + + \snippet examples/activeqt/qutlook/addressview.cpp 0 + The AddressBookModel class is a QAbstractListModel subclass that communicates directly with + Outlook, using a QHash for caching. + + \snippet examples/activeqt/qutlook/addressview.cpp 1 + The constructor initializes Outlook. The various signals Outlook provides to notify about + contents changes are connected to the \c updateOutlook() slot. + + \snippet examples/activeqt/qutlook/addressview.cpp 2 + The destructor logs off from the session. + + \snippet examples/activeqt/qutlook/addressview.cpp 3 + The \c rowCount() implementation returns the number of entries as reported by Outlook. \c columnCount + and \c headerData are implemented to show four columns in the tree view. + + \snippet examples/activeqt/qutlook/addressview.cpp 4 + The \c headerData() implementation returns hardcoded strings. + + \snippet examples/activeqt/qutlook/addressview.cpp 5 + The \c data() implementation is the core of the model. If the requested data is in the cache the + cached value is used, otherwise the data is acquired from Outlook. + + \snippet examples/activeqt/qutlook/addressview.cpp 6 + The \c changeItem() slot is called when the user changes the current entry using the user interface. + The Outlook item is accessed using the Outlook API, and is modified using the property setters. + Finally, the item is saved to Outlook, and removed from the cache. Note that the model does not + signal the view of the data change, as Outlook will emit a signal on its own. + + \snippet examples/activeqt/qutlook/addressview.cpp 7 + The \c addItem() slot calls the CreateItem method of Outlook to create a new contact item, + sets the properties of the new item to the values entered by the user and saves the item. + + \snippet examples/activeqt/qutlook/addressview.cpp 8 + The \c update() slot clears the cache, and emits the reset() signal to notify the view about the + data change requiring a redraw of the contents. + + \snippet examples/activeqt/qutlook/addressview.cpp 9 + \snippet examples/activeqt/qutlook/addressview.cpp 10 + The rest of the file implements the user interface using only Qt APIs, i.e. without communicating + with Outlook directly. + + \snippet examples/activeqt/qutlook/main.cpp 0 + + The \c main() entry point function finally instantiates the user interface and enters the + event loop. + + To build the example you must first build the QAxContainer + library. Then run your make tool in \c examples/activeqt/qutlook + and run the resulting \c qutlook.exe. +*/ diff --git a/doc/src/examples/activeqt/simple-demo.qdocinc b/doc/src/examples/activeqt/simple-demo.qdocinc new file mode 100644 index 0000000..45a346c --- /dev/null +++ b/doc/src/examples/activeqt/simple-demo.qdocinc @@ -0,0 +1,45 @@ +\raw HTML +//! [0] +<object ID="QSimpleAX" CLASSID="CLSID:DF16845C-92CD-4AAB-A982-EB9840E74669" +CODEBASE="http://qtsoftware.com/demos/simpleax.cab"> + <PARAM NAME="text" VALUE="A simple control" /> + <PARAM NAME="value" VALUE="1" /> +[Object not available! Did you forget to build and register the server?] +</object> +//! [0] //! [1] + +<FORM> + <INPUT TYPE="BUTTON" VALUE="About..." onClick="QSimpleAX.about()" /> +</FORM> +//! [1] + +//! [2] +<object ID="Calendar" CLASSID="CLSID:8E27C92B-1264-101C-8A2F-040224009C02"> +[Standard Calendar control not available!] + <PARAM NAME="day" VALUE="1" /> +</object> +//! [2] + +<FORM> + <INPUT TYPE="BUTTON" VALUE="Today" onClick="Calendar.Today()" /> +</FORM> + +//! [3] +<SCRIPT LANGUAGE="VBScript"> +Sub Calendar_Click() + MsgBox( "Calendar Clicked!" ) +End Sub + +Sub QSimpleAX_TextChanged( str ) + document.title = str +End Sub +</SCRIPT> + +<SCRIPT LANGUAGE="JavaScript"> +function QSimpleAX::ValueChanged( Newvalue ) +{ + Calendar.Day = Newvalue; +} +</SCRIPT> +//! [3] +\endraw diff --git a/doc/src/examples/activeqt/simple.qdoc b/doc/src/examples/activeqt/simple.qdoc new file mode 100644 index 0000000..e79e542 --- /dev/null +++ b/doc/src/examples/activeqt/simple.qdoc @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qaxserver-demo-simple.html + + \title A standard ActiveX and the "simple" ActiveQt widget + + \raw HTML + <object ID="QSimpleAX" CLASSID="CLSID:DF16845C-92CD-4AAB-A982-EB9840E74669" + CODEBASE="http://qtsoftware.com/demos/simpleax.cab"> + <PARAM NAME="text" VALUE="A simple control" /> + <PARAM NAME="value" VALUE="1" /> + [Object not available! Did you forget to build and register the server?] + </object> + + <FORM> + <INPUT TYPE="BUTTON" VALUE="About..." onClick="QSimpleAX.about()" /> + </FORM> + + <object ID="Calendar" CLASSID="CLSID:8E27C92B-1264-101C-8A2F-040224009C02"> + [Standard Calendar control not available!] + <PARAM NAME="day" VALUE="1" /> + </object> + + <FORM> + <INPUT TYPE="BUTTON" VALUE="Today" onClick="Calendar.Today()" /> + </FORM> + + <SCRIPT LANGUAGE="VBScript"> + Sub Calendar_Click() + MsgBox( "Calendar Clicked!" ) + End Sub + + Sub QSimpleAX_TextChanged( str ) + document.title = str + End Sub + </SCRIPT> + + <SCRIPT LANGUAGE="JavaScript"> + function QSimpleAX::ValueChanged( Newvalue ) + { + Calendar.Day = Newvalue; + } + </SCRIPT> + \endraw +*/ + +/*! + \example activeqt/simple + \title Simple Example (ActiveQt) + + The Simple example demonstrates the use of + QAxBindable::requestPropertyChange() and + QAxBindable::propertyChanged(), and the use of the default + QAxFactory through the \c QAXFACTORY_DEFAULT() macro. + + The ActiveX control in this example is a laid out QWidget with a + QSlider, a QLCDNumber and a QLineEdit. It provides a + signal/slot/property interface to change the values of the slider + and the line edit, and to get notified of any property changes. + + + The Qt implementation of the ActiveX for this example is + \snippet examples/activeqt/simple/main.cpp 0 + + The control is exported using the default QAxFactory + \snippet examples/activeqt/simple/main.cpp 1 + + To build the example you must first build the QAxServer library. + Then run qmake and your make tool in \c examples/activeqt/simple. + + The \l{qaxserver-demo-simple.html}{demonstration} requires your + WebBrowser to support ActiveX controls, and scripting to be enabled. + + The simple ActiveX control is embedded using the \c <object> tag. + + \snippet doc/src/examples/activeqt/simple-demo.qdocinc 0 + + A simple HTML button is connected to the ActiveQt's about() slot. + + \snippet doc/src/examples/activeqt/simple-demo.qdocinc 1 + + A second ActiveX control - the standard Calendar Control - is instantiated + + \snippet doc/src/examples/activeqt/simple-demo.qdocinc 2 + + Events from the ActiveX controls are handled using both Visual Basic Script + and JavaScript. + + \snippet doc/src/examples/activeqt/simple-demo.qdocinc 3 +*/ diff --git a/doc/src/examples/activeqt/webbrowser.qdoc b/doc/src/examples/activeqt/webbrowser.qdoc new file mode 100644 index 0000000..46b83f9 --- /dev/null +++ b/doc/src/examples/activeqt/webbrowser.qdoc @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example activeqt/webbrowser + \title Web Browser Example (ActiveQt) + + The Web Browser example uses the Microsoft Web Browser + ActiveX control to implement a fully functional Web Browser + application. The user interface has been developed using the Qt + Designer integration of the QAxWidget class. + + The code demonstrates how the Qt application can communicate + with the embedded ActiveX controls using signals, slots and the + dynamicCall() function. + + \snippet examples/activeqt/webbrowser/main.cpp 0 + + The \c MainWindow class declares a \c QMainWindow based user interface, + using the \c Ui::MainWindow class generated by Qt Designer. A number + of slots are implemented to handle events from the various user + interface elements, including the \c WebBrowser object, which is a + QAxWidget hosting the Microsoft Web Browser control. + + \snippet examples/activeqt/webbrowser/main.cpp 1 + + The constructor initializes the user interface, installs a + progress bar on the status bar, and uses QAxBase::dynamicCall() + to invoke the \c GoHome() method of Internet Explorer to + navigate to the user's home page. + + \snippet examples/activeqt/webbrowser/main.cpp 2 + Different slots handle the signals emitted by the WebBrowser object. + + Connections that don't require any coding, i.e. connecting the \c back + action to the \c GoBack() slot, have already been made in Qt Designer. + + \snippet examples/activeqt/webbrowser/main.cpp 3 + \snippet examples/activeqt/webbrowser/main.cpp 4 + + The rest of the implementation is not related to ActiveQt - the actions + are handled by different slots, and the entry point function starts the + application using standard Qt APIs. + + To build the example you must first build the QAxContainer + library. Then run your make tool in \c + examples/activeqt/webbrowser and run the resulting \c + webbrowser.exe. +*/ diff --git a/doc/src/examples/activeqt/wrapper-demo.qdocinc b/doc/src/examples/activeqt/wrapper-demo.qdocinc new file mode 100644 index 0000000..1457119 --- /dev/null +++ b/doc/src/examples/activeqt/wrapper-demo.qdocinc @@ -0,0 +1,51 @@ +\raw HTML +//! [0] +<SCRIPT LANGUAGE="VBScript"> +Sub ToolButton_Clicked() + RadioButton.text = InputBox( "Enter something", "Wrapper Demo" ) +End Sub + +Sub PushButton_clicked() + MsgBox( "Thank you!" ) +End Sub + +Sub CheckBox_toggled( state ) + if state = 0 then + CheckBox.text = "Check me!" + else + CheckBox.text = "Uncheck me!" + end if +End Sub +</SCRIPT> +<p /> +A QPushButton:<br /> +<object ID="PushButton" CLASSID="CLSID:2B262458-A4B6-468B-B7D4-CF5FEE0A7092" +CODEBASE="http://qtsoftware.com/demos/wrapperax.cab"> + <PARAM NAME="text" VALUE="Click me!" /> +[Object not available! Did you forget to build and register the server?] +</object><br /> + +<p /> +A QCheckBox:<br /> +<object ID="CheckBox" CLASSID="CLSID:6E795de9-872d-43cf-a831-496ef9d86c68" +CODEBASE="http://qtsoftware.com/demos/wrapperax.cab"> + <PARAM NAME="text" VALUE="Check me!" /> +[Object not available! Did you forget to build and register the server?] +</object><br /> + +<p /> +A QToolButton:<br /> +<object ID="ToolButton" CLASSID="CLSID:7c0ffe7a-60c3-4666-bde2-5cf2b54390a1" +CODEBASE="http://qtsoftware.com/demos/wrapperax.cab"> +[Object not available! Did you forget to build and register the server?] +</object><br /> + +<p /> +A QRadioButton:<br /> +<object ID="RadioButton" CLASSID="CLSID:afcf78c8-446c-409a-93b3-ba2959039189" +CODEBASE="http://qtsoftware.com/demos/wrapperax.cab"> + <PARAM NAME="text" VALUE="Tune me!" /> +[Object not available! Did you forget to build and register the server?] +</object><br /> +//! [0] +\endraw diff --git a/doc/src/examples/activeqt/wrapper.qdoc b/doc/src/examples/activeqt/wrapper.qdoc new file mode 100644 index 0000000..017da30 --- /dev/null +++ b/doc/src/examples/activeqt/wrapper.qdoc @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qaxserver-demo-wrapper.html + + \title Standard Qt widgets in an HTML page + + \input examples/activeqt/wrapper-demo.qdocinc +*/ + +/*! + \example activeqt/wrapper + \title Wrapper Example (ActiveQt) + + The Wrapper example demonstrates how to export existing QWidget + classes as ActiveX controls, and the use of QAxFactory together + with the \c QAXFACTORY_EXPORT() macro. ActiveX controls in this + example are the standard button classes QPushButton, QCheckBox + and QRadioButton as provided by Qt. + + \snippet examples/activeqt/wrapper/main.cpp 0 + The factory implementation returns the list of supported controls, + creates controls on request and provides information about the unique + IDs of the COM classes and interfaces for each control. + + \snippet examples/activeqt/wrapper/main.cpp 1 + The factory is exported using the QAXFACTORY_EXPORT macro. + + To build the example you must first build the QAxServer library. + Then run \c qmake and your make tool in \c + examples/activeqt/wrapper. + + The \l{qaxserver-demo-wrapper.html}{demonstration} requires a + web browser that supports ActiveX controls, and scripting to be + enabled. + + \snippet examples/activeqt/wrapper-demo.qdocinc 0 +*/ diff --git a/doc/src/examples/addressbook.qdoc b/doc/src/examples/addressbook.qdoc new file mode 100644 index 0000000..fb5c1ea --- /dev/null +++ b/doc/src/examples/addressbook.qdoc @@ -0,0 +1,456 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/addressbook + \title Address Book Example + + The address book example shows how to use proxy models to display + different views onto data from a single model. + + \image addressbook-example.png Screenshot of the Address Book example + + This example provides an address book that allows contacts to be + grouped alphabetically into 9 groups: ABC, DEF, GHI, ... , VW, + ..., XYZ. This is achieved by using multiple views on the same + model, each of which is filtered using an instance of the + QSortFilterProxyModel class. + + + \section1 Overview + + The address book contains 5 classes: \c MainWindow, + \c AddressWidget, \c TableModel, \c NewAddressTab and + \c AddDialog. The \c MainWindow class uses \c AddressWidget as + its central widget and provides \gui File and \gui Tools menus. + + \image addressbook-classes.png Diagram for Address Book Example + + The \c AddressWidget class is a QTabWidget subclass that is used + to manipulate the 10 tabs displayed in the example: the 9 + alphabet group tabs and an instance of \c NewAddressTab. + The \c NewAddressTab class is a subclass of QWidget that + is only used whenever the address book is empty, prompting the + user to add some contacts. \c AddressWidget also interacts with + an instance of \c TableModel to add, edit and remove entries to + the address book. + + \c TableModel is a subclass of QAbstractTableModel that provides + the standard model/view API to access data. It also holds a + QList of \l{QPair}s corresponding to the contacts added. + However, this data is not all visible in a single tab. Instead, + QTableView is used to provide 9 different views of the same + data, according to the alphabet groups. + + QSortFilterProxyModel is the class responsible for filtering + the contacts for each group of contacts. Each proxy model uses + a QRegExp to filter out contacts that do not belong in the + corresponding alphabetical group. The \c AddDialog class is + used to obtain information from the user for the address book. + This QDialog subclass is instantiated by \c NewAddressTab to + add contacts, and by \c AddressWidget to add and edit contacts. + + We begin by looking at the \c TableModel implementation. + + + \section1 TableModel Class Definition + + The \c TableModel class provides standard API to access data in + its QList of \l{QPair}s by subclassing QAbstractTableModel. The + basic functions that must be implemented in order to do so are: + \c rowCount(), \c columnCount(), \c data(), \c headerData(). + For TableModel to be editable, it has to provide implementations + \c insertRows(), \c removeRows(), \c setData() and \c flags() + functions. + + \snippet itemviews/addressbook/tablemodel.h 0 + + Two constructors are used, a default constructor which uses + \c TableModel's own \c {QList<QPair<QString, QString>>} and one + that takes \c {QList<QPair<QString, QString>} as an argument, + for convenience. + + + \section1 TableModel Class Implementation + + We implement the two constructors as defined in the header file. + The second constructor initializes the list of pairs in the + model, with the parameter value. + + \snippet itemviews/addressbook/tablemodel.cpp 0 + + The \c rowCount() and \c columnCount() functions return the + dimensions of the model. Whereas, \c rowCount()'s value will vary + depending on the number of contacts added to the address book, + \c columnCount()'s value is always 2 because we only need space + for the \bold Name and \bold Address columns. + + \note The \c Q_UNUSED() macro prevents the compiler from + generating warnings regarding unused parameters. + + \snippet itemviews/addressbook/tablemodel.cpp 1 + + The \c data() function returns either a \bold Name or + \bold {Address}, based on the contents of the model index + supplied. The row number stored in the model index is used to + reference an item in the list of pairs. Selection is handled + by the QItemSelectionModel, which will be explained with + \c AddressWidget. + + \snippet itemviews/addressbook/tablemodel.cpp 2 + + The \c headerData() function displays the table's header, + \bold Name and \bold Address. If you require numbered entries + for your address book, you can use a vertical header which we + have hidden in this example (see the \c AddressWidget + implementation). + + \snippet itemviews/addressbook/tablemodel.cpp 3 + + The \c insertRows() function is called before new data is added, + otherwise the data will not be displayed. The + \c beginInsertRows() and \c endInsertRows() functions are called + to ensure all connected views are aware of the changes. + + \snippet itemviews/addressbook/tablemodel.cpp 4 + + The \c removeRows() function is called to remove data. Again, + \l{QAbstractItemModel::}{beginRemoveRows()} and + \l{QAbstractItemModel::}{endRemoveRows()} are called to ensure + all connected views are aware of the changes. + + \snippet itemviews/addressbook/tablemodel.cpp 5 + + The \c setData() function is the function that inserts data into + the table, item by item and not row by row. This means that to + fill a row in the address book, \c setData() must be called + twice, as each row has 2 columns. It is important to emit the + \l{QAbstractItemModel::}{dataChanged()} signal as it tells all + connected views to update their displays. + + \snippet itemviews/addressbook/tablemodel.cpp 6 + + The \c flags() function returns the item flags for the given + index. + + \snippet itemviews/addressbook/tablemodel.cpp 7 + + We set the Qt::ItemIsEditable flag because we want to allow the + \c TableModel to be edited. Although for this example we don't + use the editing features of the QTableView object, we enable + them here so that we can reuse the model in other programs. + + The last function in \c {TableModel}, \c getList() returns the + QList<QPair<QString, QString>> object that holds all the + contacts in the address book. We use this function later to + obtain the list of contacts to check for existing entries, write + the contacts to a file and read them back. Further explanation is + given with \c AddressWidget. + + \snippet itemviews/addressbook/tablemodel.cpp 8 + + + \section1 AddressWidget Class Definition + + The \c AddressWidget class is technically the main class + involved in this example as it provides functions to add, edit + and remove contacts, to save the contacts to a file and to load + them from a file. + + \snippet itemviews/addressbook/addresswidget.h 0 + + \c AddressWidget extends QTabWidget in order to hold 10 tabs + (\c NewAddressTab and the 9 alphabet group tabs) and also + manipulates \c table, the \c TableModel object, \c proxyModel, + the QSortFilterProxyModel object that we use to filter the + entries, and \c tableView, the QTableView object. + + + \section1 AddressWidget Class Implementation + + The \c AddressWidget constructor accepts a parent widget and + instantiates \c NewAddressTab, \c TableModel and + QSortFilterProxyModel. The \c NewAddressTab object, which is + used to indicate that the address book is empty, is added + and the rest of the 9 tabs are set up with \c setupTabs(). + + \snippet itemviews/addressbook/addresswidget.cpp 0 + + The \c setupTabs() function is used to set up the 9 alphabet + group tabs, table views and proxy models in + \c AddressWidget. Each proxy model in turn is set to filter + contact names according to the relevant alphabet group using a + \l{Qt::CaseInsensitive}{case-insensitive} QRegExp object. The + table views are also sorted in ascending order using the + corresponding proxy model's \l{QSortFilterProxyModel::}{sort()} + function. + + Each table view's \l{QTableView::}{selectionMode} is set to + QAbstractItemView::SingleSelection and + \l{QTableView::}{selectionBehavior} is set to + QAbstractItemView::SelectRows, allowing the user to select + all the items in one row at the same time. Each QTableView object + is automatically given a QItemSelectionModel that keeps track + of the selected indexes. + + \snippet itemviews/addressbook/addresswidget.cpp 1 + + The QItemSelectionModel class provides a + \l{QItemSelectionModel::selectionChanged()}{selectionChanged} + signal that is connected to \c{AddressWidget}'s + \c selectionChanged() signal. This signal to signal connection + is necessary to enable the \gui{Edit Entry...} and + \gui{Remove Entry} actions in \c MainWindow's Tools menu. This + connection is further explained in \c MainWindow's + implementation. + + Each table view in the address book is added as a tab to the + QTabWidget with the relevant label, obtained from the QStringList + of groups. + + \image addressbook-signals.png Signals and Slots Connections + + We provide 2 \c addEntry() functions: 1 which is intended to be + used to accept user input, and the other which performs the actual + task of adding new entries to the address book. We divide the + responsibility of adding entries into two parts to allow + \c newAddressTab to insert data without having to popup a dialog. + + The first \c addEntry() function is a slot connected to the + \c MainWindow's \gui{Add Entry...} action. This function creates an + \c AddDialog object and then calls the second \c addEntry() + function to actually add the contact to \c table. + + \snippet itemviews/addressbook/addresswidget.cpp 2 + + Basic validation is done in the second \c addEntry() function to + prevent duplicate entries in the address book. As mentioned with + \c TableModel, this is part of the reason why we require the + getter method \c getList(). + + \snippet itemviews/addressbook/addresswidget.cpp 3 + + If the model does not already contain an entry with the same name, + we call \c setData() to insert the name and address into the + first and second columns. Otherwise, we display a QMessageBox + to inform the user. + + \note The \c newAddressTab is removed once a contact is added + as the address book is no longer empty. + + Editing an entry is a way to update the contact's address only, + as the example does not allow the user to change the name of an + existing contact. + + Firstly, we obtain the active tab's QTableView object using + QTabWidget::currentWidget(). Then we extract the + \c selectionModel from the \c tableView to obtain the selected + indexes. + + \snippet itemviews/addressbook/addresswidget.cpp 4a + + Next we extract data from the row the user intends to + edit. This data is displayed in an instance of \c AddDialog + with a different window title. The \c table is only + updated if changes have been made to data in \c aDialog. + + \snippet itemviews/addressbook/addresswidget.cpp 4b + + \image addressbook-editdialog.png Screenshot of Dialog to Edit a Contact + + Entries are removed using the \c removeEntry() function. + The selected row is removed by accessing it through the + QItemSelectionModel object, \c selectionModel. The + \c newAddressTab is re-added to the \c AddressWidget only if + the user removes all the contacts in the address book. + + \snippet itemviews/addressbook/addresswidget.cpp 5 + + The \c writeToFile() function is used to save a file containing + all the contacts in the address book. The file is saved in a + custom \c{.dat} format. The contents of the QList of \l{QPair}s + are written to \c file using QDataStream. If the file cannot be + opened, a QMessageBox is displayed with the related error message. + + \snippet itemviews/addressbook/addresswidget.cpp 6 + + The \c readFromFile() function loads a file containing all the + contacts in the address book, previously saved using + \c writeToFile(). QDataStream is used to read the contents of a + \c{.dat} file into a list of pairs and each of these is added + using \c addEntry(). + + \snippet itemviews/addressbook/addresswidget.cpp 7 + + + \section1 NewAddressTab Class Definition + + The \c NewAddressTab class provides an informative tab telling + the user that the address book is empty. It appears and + disappears according to the contents of the address book, as + mentioned in \c{AddressWidget}'s implementation. + + \image addressbook-newaddresstab.png Screenshot of NewAddressTab + + The \c NewAddressTab class extends QWidget and contains a QLabel + and QPushButton. + + \snippet itemviews/addressbook/newaddresstab.h 0 + + + \section1 NewAddressTab Class Implementation + + The constructor instantiates the \c addButton, + \c descriptionLabel and connects the \c{addButton}'s signal to + the \c{addEntry()} slot. + + \snippet itemviews/addressbook/newaddresstab.cpp 0 + + The \c addEntry() function is similar to \c AddressWidget's + \c addEntry() in the sense that both functions instantiate an + \c AddDialog object. Data from the dialog is extracted and sent + to \c AddressWidget's \c addEntry() slot by emitting the + \c sendDetails() signal. + + \snippet itemviews/addressbook/newaddresstab.cpp 1 + + \image signals-n-slots-aw-nat.png + + + \section1 AddDialog Class Definition + + The \c AddDialog class extends QDialog and provides the user + with a QLineEdit and a QTextEdit to input data into the + address book. + + \snippet itemviews/addressbook/adddialog.h 0 + + \image addressbook-adddialog.png + + + \section1 AddDialog Class Implementation + + The \c AddDialog's constructor sets up the user interface, + creating the necessary widgets and placing them into layouts. + + \snippet itemviews/addressbook/adddialog.cpp 0 + + To give the dialog the desired behavior, we connect the \gui OK + and \gui Cancel buttons to the dialog's \l{QDialog::}{accept()} and + \l{QDialog::}{reject()} slots. Since the dialog only acts as a + container for name and address information, we do not need to + implement any other functions for it. + + + \section1 MainWindow Class Definition + + The \c MainWindow class extends QMainWindow and implements the + menus and actions necessary to manipulate the address book. + + \table + \row \o \inlineimage addressbook-filemenu.png + \o \inlineimage addressbook-toolsmenu.png + \endtable + + \snippet itemviews/addressbook/mainwindow.h 0 + + The \c MainWindow class uses an \c AddressWidget as its central + widget and provides the File menu with \gui Open, \gui Close and + \gui Exit actions, as well as the \gui Tools menu with + \gui{Add Entry...}, \gui{Edit Entry...} and \gui{Remove Entry} + actions. + + + \section1 MainWindow Class Implementation + + The constructor for \c MainWindow instantiates AddressWidget, + sets it as its central widget and calls the \c createMenus() + function. + + \snippet itemviews/addressbook/mainwindow.cpp 0 + + The \c createMenus() function sets up the \gui File and + \gui Tools menus, connecting the actions to their respective slots. + Both the \gui{Edit Entry...} and \gui{Remove Entry} actions are + disabled by default as such actions cannot be carried out on an empty + address book. They are only enabled when one or more contacts + are added. + + \snippet itemviews/addressbook/mainwindow.cpp 1a + \dots + \codeline + \snippet itemviews/addressbook/mainwindow.cpp 1b + + Apart from connecting all the actions' signals to their + respective slots, we also connect \c AddressWidget's + \c selectionChanged() signal to its \c updateActions() slot. + + The \c openFile() function allows the user to choose a file with + the \l{QFileDialog::getOpenFileName()}{open file dialog}. The chosen + file has to be a custom \c{.dat} file that contains address book + contacts. This function is a slot connected to \c openAct in the + \gui File menu. + + \snippet itemviews/addressbook/mainwindow.cpp 2 + + The \c saveFile() function allows the user to save a file with + the \l{QFileDialog::getSaveFileName()}{save file dialog}. This function + is a slot connected to \c saveAct in the \gui File menu. + + \snippet itemviews/addressbook/mainwindow.cpp 3 + + The \c updateActions() function enables and disables + \gui{Edit Entry...} and \gui{Remove Entry} depending on the contents of + the address book. If the address book is empty, these actions + are disabled; otherwise, they are enabled. This function is a slot + is connected to the \c AddressWidget's \c selectionChanged() + signal. + + \snippet itemviews/addressbook/mainwindow.cpp 4 + + + \section1 main() Function + + The main function for the address book instantiates QApplication + and opens a \c MainWindow before running the event loop. + + \snippet itemviews/addressbook/main.cpp 0 +*/ diff --git a/doc/src/examples/ahigl.qdoc b/doc/src/examples/ahigl.qdoc new file mode 100644 index 0000000..d42df66 --- /dev/null +++ b/doc/src/examples/ahigl.qdoc @@ -0,0 +1,572 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example qws/ahigl + \title OpenGL for Embedded Systems Example + + \section1 Introduction + + This example demonstrates how you can use OpenGL for Embedded + Systems (ES) in your own screen driver and \l{add your graphics + driver to Qt for Embedded Linux}. In \l{Qt for Embedded Linux}, + painting is done in software, normally performed in two steps: + First, each client renders its windows onto its window surface in + memory using a paint engine. Then the server uses the screen + driver to compose the window surface images and copy the + composition to the screen. (See the \l{Qt for Embedded Linux + Architecture} documentation for details.) + + This example is not for the novice. It assumes the reader is + familiar with both OpenGL and the screen driver framework + demonstrated in the \l {Accelerated Graphics Driver Example}. + + An OpenGL screen driver for Qt for Embedded Linux can use OpenGL ES + in three ways. First, the \l{QWSServer}{Qt for Embedded Linux server} + can use the driver to compose multiple window images and then show the + composition on the screen. Second, clients can use the driver to + accelerate OpenGL painting operations using the QOpenGLPaintEngine + class. Finally, clients can use the driver to do OpenGL operations + with instances of the QGLWidget class. This example implements all + three cases. + + The example uses an implementation of OpenGL ES from + \l {http://ati.amd.com}{ATI} for the + \l {http://ati.amd.com/products/imageon238x/}{Imageon 2380}. The + OpenGL include files gl.h and egl.h must be installed to compile + the example, and the OpenGL and EGL libraries must be installed + for linking. If your target device is different, you must install + the include files and libraries for that device, and you also + might need to modify the example source code, if any API signatures + in your EGL library differ from the ones used here. + + After compiling and linking the example source, install the + screen driver plugin with the command \c {make install}. To + start an application that uses the plugin, you can either set the + environment variable \l QWS_DISPLAY and then start the + application, or just start the application with the \c -display + switch, as follows: + + \snippet doc/src/snippets/code/doc_src_examples_ahigl.qdoc 0 + + The example driver also implements an animated transition effect + for use when showing new windows or reshowing windows that have + been minimized. To enable this transition effect, run the + application with \c {-display ahigl:effects}. + + \section1 The Class Definitions + + The example comprises three main classes plus some helper classes. + The three main classes are the plugin (QAhiGLScreenPlugin), which + is defined in qscreenahiglplugin.cpp, the screen driver + (QAhiGLScreen), which is defined in qscreenahigl_qws.h, and the + window surface (QAhiGLWindowSurface), which is defined in + qwindowsurface_ahigl_p.h. The "Ahi" prefix in these class names + stands for \e {ATI Handheld Interface}. The example was written + for the ATI Imageon 2380, but it can also be used as a template + for other ATI handheld devices. + + \section2 The Plugin Class Definition + + The screen driver plugin is class QAhiGLScreenPlugin. + + \snippet examples/qws/ahigl/qscreenahiglplugin.cpp 0 + + QAhiGLScreenPlugin is derived from class QScreenDriverPlugin, + which in turn is derived from QObject. + + \section2 The Screen Driver Class Definitions + + The screen driver classes are the public class QAhiGLScreen and + its private implementation class QAhiGLScreenPrivate. QAhiGLScreen + is derived from QGLScreen, which is derived from QScreen. If your + screen driver will only do window compositions and display them, + then you can derive your screen driver class directly from + QScreen. But if your screen driver will do accelerated graphics + rendering operations with the QOpenGLPaintEngine, or if it will + handle instances of class QGLWidget, then you must derive your + screen driver class from QGLScreen. + + \snippet examples/qws/ahigl/qscreenahigl_qws.h 0 + + All functions in the public API of class QAhiGLScreen are virtual + functions declared in its base classes. hasOpenGL() is declared in + QGLScreen. It simply returns true indicating our example screen + driver does support OpenGL operations. The other functions in the + public API are declared in QScreen. They are called by the + \l{QWSServer}{Qt for Embedded Linux server} at the appropriate times. + + Note that class QScreen is a documented class but class QGLScreen + is not. This is because the design of class QGLScreen is not yet + final. + + The only data member in class QAhiGLScreen is a standard d_ptr, + which points to an instance of the driver's private implementation + class QAhiGLScreenPrivate. The driver's internal state is stored + in the private class. Using the so-called d-pointer pattern allows + you to make changes to the driver's internal design without + breaking binary compatibility. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 0 + + Class QAhiGLScreenPrivate is derived from QObject so that it can + use the Qt signal/slot mechanism. QAhiGLScreen is not a QObject, + so it can't use the signal/slot mechanism. Signals meant for our + screen driver are received by slots in the private implementation + class, in this case, windowEvent() and redrawScreen(). + + \section2 The Window Surface Class Definitions + + The window surface classes are QAhiGLWindowSurface and its private + implementation class QAhiGLWindowSurfacePrivate. We create class + QAhiGLWindowSurface so the screen driver can use the OpenGL paint + engine and the OpenGL widget, classes QOpenGLPaintEngine and + QGLWidget. QAhiGLWindowSurface is derived from the more general + OpenGL window surface class, QWSGLWindowSurface, which is derived + from QWSWindowSurface. + + \snippet examples/qws/ahigl/qwindowsurface_ahigl_p.h 0 + + In addition to implementing the standard functionality required by + any new subclass of QWSWindowSurface, QAhiGLWindowSurface also + contains the textureId() function used by QAhiGLScreen. + + The same d-pointer pattern is used in this window surface class. + The private implementation class is QAhiGLWindowSurfacePrivate. It + allows making changes to the state variables of the window surface + without breaking binary compatibility. + + \snippet examples/qws/ahigl/qwindowsurface_ahigl.cpp 0 + + In this case, our private implementation class has no member + functions except for its constructor. It contains only public data + members which hold state information for the window surface. + + \section2 The Helper Classes + + The example screen driver maintains a static \l {QMap} {map} of + all the \l {QWSWindow} {windows} it is showing on the screen. + Each window is mapped to an instance of struct WindowInfo. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 2 + + As each new window is created, an instance of struct WindowInfo is + allocated and inserted into the window map. WindowInfo uses a + GLuint to identify the OpenGL texture it creates for the window. + Note that the example driver, in addition to drawing windows using + OpenGL, also supports drawing windows in the normal way without + OpenGL, but it uses an OpenGL texture for the rendering operations + in either case. Top-level windows that are drawn without OpenGL + are first rendered in the normal way into a shared memory segment, + which is then converted to a OpenGL texture and drawn to the + screen. + + To animate the window transition effect, WindowInfo uses an + instance of the helper class ShowAnimation. The animation is + created by the windowEvent() slot in QAhiGLScreenPrivate, whenever + a \l {QWSServer::WindowEvent} {Show} window event is emitted by + the \l {QWSServer} {window server}. The server emits this signal + when a window is shown the first time and again later, when the + window is reshown after having been minimized. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 1 + + Class ShowAnimation is derived from the QTimeLine class, which is + used for controlling animations. QTimeLine is a QObject, so + ShowAnimation can use the Qt signal/slot mechanism. We will see + how the timeline's \l {QTimeLine::valueChanged()} {valueChanged()} + and \l {QTimeLine::finished()} {finished()} signals are used to + control the animation and then destroy the instance of + ShowAnimation, when the animation ends. The ShowAnimation + constructor needs the pointer to the screen driver's private + implementation class so it can set up these signal/slot + connections. + + \section1 The Class Implementations + + \section2 The Plugin Class Implementation + + QAhiGLScreenPlugin is a straightforward derivation of + QScreenDriverPlugin. It reimplements \l{QScreenDriverPlugin::}{keys()} + and \l{QScreenDriverPlugin::}{create()}. They are + called as needed by the \l{QWSServer}{Qt for Embedded Linux server.} + Recall that the server detects that the ahigl screen driver has + been requested, either by including "ahigl" in the value for the + environment variable QWS_DISPLAY, or by running your application + with a command line like the following. + + \snippet doc/src/snippets/code/doc_src_examples_ahigl.qdoc 1 + + The server calls \l {QScreenDriverPlugin::} {keys()}, which + returns a \l {QStringList} containing the singleton "ahigl" + matching the requested screen driver and telling the server that + it can use our example screen driver. The server then calls \l + {QScreenDriverPlugin::} {create()}, which creates the instance of + QAhiGLScreen. + + \snippet examples/qws/ahigl/qscreenahiglplugin.cpp 1 + + In the code snippet above, the macro Q_EXPORT_PLUGIN2 is used to export + the plugin class, QAhiGLScreen, for the qahiglscreen plugin. + Further information regarding plugins and how to create them + can be found at \l{How to Create Qt Plugins}. + + \section2 The Screen Driver Class Implementations + + The plugin creates the singleton instance of QAhiGLScreen. The + constructor is passed a \c displayId, which is used in the base + class QGLScreen to identify the server that the screen driver is + connected to. The constructor also creates its instance of + QAhiGLScreenPrivate, which instantiates a QTimer. The timeout() + signal of this timer is connected to the redrawScreen() slot so + the timer can be used to limit the frequency of actual drawing + operations in the hardware. + + The public API of class QAhiGLScreen consists of implementations + of virtual functions declared in its base classes. The function + hasOpenGL() is declared in base class QGLScreen. The others are + declared in base class QScreen. + + The \l {QScreen::}{connect()} function is the first one called by + the server after the screen driver is constructed. It initializes + the QScreen data members to hardcoded values that describe the ATI + screen. A better implementation would query the hardware for the + corresponding values in its current state and use those. It asks + whether the screen driver was started with the \c effects option + and sets the \c doEffects flag accordingly. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 7 + + The \l {QScreen::}{initDevice()} function is called by the server + after \l {QScreen::}{connect()}. It uses EGL library functions to + initialize the ATI hardware. Note that some data structures used + in this example are specific to the EGL implementation used, e.g., + the DummyScreen structure. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 8 + + Note the signal/slot connection at the bottom of initDevice(). We + connect the server's QWSServer::windowEvent() signal to the + windowEvent() slot in the screen driver's private implementation + class. The windowEvent() slot handles three window events, + QWSServer::Create, QWSServer::Destroy, and QWSServer::Show. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 5 + + The function manages instances of the helper classes associated + with each window. When a QWSServer::Create event occurs, it means + a new top-level \l {QWSWindow} {window} has been created. In this + case, an instance of helper class WindowInfo is created and + inserted into the window map with the pointer to the new \l + {QWSWindow} {window} as its key. When a QWSServer::Destroy event + occurs, a window is being destroyed, and its mapping is removed + from the window map. These two events are straightforward. The + tricky bits happen when a QWSServer::Show event occurs. This case + occurs when a window is shown for the first time and when it is + reshown after having been minimized. If the window transition + effect has been enabled, a new instance of the helper class + ShowAnimation is created and stored in a QPointer in the window's + instance of WindowInfo. The constructor of ShowAnimation + automatically \l {QTimeLine::start()} {starts} the animation of + the transition effect. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 3 + + To ensure that a ShowAnimation is not deleted until its animation + ends, the \l {QTimeLine::finished()} {finished()} signal is + connected to the \l {QObject::deleteLater()} {deleteLater()} slot. + When the animation ends, the finished() signal is emitted and the + deleteLater() slot deletes the ShowAnimation. The key here is that + the pointer to the ShowAnimation is stored in a QPointer in the + WindowInfo class. This QPointer will also be notified when the + ShowAnimation is deleted, so the QPointer in WindowInfo can null + itself out, if and only if it is still pointing to the instance + of ShowAnimation being deleted. + + The \l {QTimeLine::valueForTime()} {valueForTime()} function in + QTimeLine is reimplemented in ShowAnimation to return time values + that represent a curved path for the window transition effect. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 4 + + valueForTime() is called internally, when the time interval it + computed during the previous call has elapsed. If it computes a + next time value that is different from the one computed + previously, the \l {QTimeLine::valueChanged()} {valueChanged()} + signal is emitted. The ShowAnimation constructor shown above + connects this signal to the redrawScreen() slot in the screen + driver's private implementation class. This is how the animation + actually happens. + + The screen driver's implementation of \l {QScreen::} + {exposeRegion()} is where the main work of the screen driver is + meant to be done, i.e., updating the screen. It is called by the + \l {QWSServer} {window system} to update a particular window's + region of the screen. But note that it doesn't actually update the + screen, i.e., it doesn't actually call redrawScreen() directly, + but starts the updateTimer, which causes redrawScreen() to be + called once for each updateTimer interval. This means that all + calls to exposeRegion() during an updateTimer interval are handled + by a single call to redrawScreen(). Thus updateTimer can be used + to limit the frequency of screen updates. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 13 + + The call to the private function invalidateTexture() destroys + the window's existing texture (image). This ensures that a new + texture will be created for the window, when redrawScreen() is + eventually called. + + But there is a caveat to using updateTimer to limit the frequency + of screen updates. When the driver's animated transition effect + for new windows is enabled and a new window is being shown for the + first time or reshown after having been minimized, an instance of + ShowAnimation is created to run the animation. The valueChanged() + signal of this ShowAnimation is also connected to the + redrawScreen() slot, and QTimeLine, the base class of our + ShowAnimation, uses its own, internal timer to limit the speed of + the animation. This means that in the driver as currently written, + if the window transition effect is enabled (i.e. if the plugin is + started, with \c {-display ahigl:effects}), then redrawScreen() + can be called both when the update timer times out and when the + ShowAnimation timer times out, so the screen might get updated + more often than the frequency established by the update timer. + This may or may not be a bug, depending on your own hardware, if + you use this example as a template for your own OpenGL driver. + + The screen driver's private function redrawScreen() constructs + the window compositions. It is called only by the function of the + same name in the screen driver's private implementation class. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 6 + + Recall that this redrawScreen() in the private implementation + class is a slot function connected to two signals, the \c + timeout() signal of the updateTimer in the private implementation + class, and the valueChanged() signal of the helper class + ShowAnimation. Thus, the screen is only ever updated when a + timeout of one of the two timers occurs. This is important for two + reasons. First, the screen is meant to be updated no more than + once per updateTimer interval. Second, however, if the animated + window transition effect is requested, the screen might be updated + more often than that, and this might be a bug if the hardware + can't handle more frequent updates. + + The redrawScreen() in QAhiGLScreen begins by using standard + OpenGL to fill the screen with the background color. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 10 + + Next it iterates over the list of all \l {QWSWindow} {client + windows} obtained from the \l {QWSServer} {server}, extracting + from each window its instance of QWSWIndowSurface, then using that + window surface to create an OpenGL texture, and finally calling + the helper function drawWindow() to draw the texture on the + screen. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 11 + + Note the call to glBindTexture() immediately before the call to + drawWindow(). This call binds the identifer \c GL_TEXTURE_2D to + the texture we have just created. This makes our texture + accessible to functions in the OpenGL libraries. If you miss that + point, digging into the internals of drawWindow() won't make much + sense. + + Finally, the cursor is added to the window composition, and in the + last statement, the whole thing is displayed on the screen. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 12 + + The call to \c drawWindow(win,progress), in addition to passing a + pointer to the window to be redrawn, also passes the \c progress + parameter obtained by calling \l {QTimeLine::currentValue()} on + the window's instance of ShowAnimation. Recall that the current + value of the timeline is updated internally by a timer local to + the timeline, and the redrawScreen() slot is called whenever the + current value changes. The progress value will only be used if + the animated transition effect has been enabled. These extra calls + of redrawScreen() may cause the screen to be updated more often + than the rate determined by updateTimer. This must be taken + into account, if you set your updateTimer to timeout at the + maximum screen update frequency your hardware can handle. + + The drawWindow() function is not shown here and not explained + further, but the call to drawWindow() is the entry point to a + hierarchy of private helper functions that execute sequences of + OpenGL and EGL library calls. The reader is assumed to be familiar + enough with the OpenGL and EGL APIs to understand the code in + these helper functions on his own. Besides drawWindow(), the list + of these helper functions includes drawQuad(), drawQuadWavyFlag(), + the two overloadings of drawQuad_helper() (used by drawQuad() and + drawQuadWacyFlag()), and setRectCoords(). + + Note the two different ways the window's texture can be created in + redrawScreen(). If the window surface is an OpenGL window surface + (QAhiGLWindowSurface described below), the texture is obtained + from the window surface directly by calling its textureId() + function. But when the window surface is not an OpenGL one, the + static function createTexture() is called with the window + surface's \l {QImage} {image} to copy that image into an OpenGL + texture. This is done with the EGL functions glTexImage2D() and + glTexSubImage2D(). createTexture() is another function that + should be understandable for exsperienced OpenGL users, so it is + not shown or explained further here. + + The two implementations of \l {QScreen::}{createSurface()} are for + instantiating new window surfaces. The overloading with the widget + parameter is called in the client. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 14 + + If the parameter is an \l {QGLWidget} {OpenGL widget}, or, when it + isn't an OpenGL widget but its size is no bigger than 256 x 256, + we instantiate our subclass QAhiGLWindowSurface. Otherwise, we + instantiate a QWSWindowSurface. The size contraint is a + limitation of the OpenGL ES libraries we are using for our ATI + device. + + Note the test at the top of the function asking if our application + process is the \l {QApplication::GuiServer} {server}. We only + create instances of QAhiGLWindowSurface if our client is in the + server process. This is because of an implementation restriction + required by the OpenGL library used in the example. They only + support use of OpenGL in the server process. Hence a client can + use the QAhiGLWindowSurface if the client is in the server + process. + + The other overloading of createSurface() is called by the + server to create a window surface that will hold a copy of a + client side window surface. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 15 + + This overloading accepts a QString parameter identifying the type + of window surface to instantiate. QAhiGLWindowSurface is + instantiated if the parameter is \c ahigl. Otherwise, a normal + QWSWindowSurface is instantiated. The client's window surface + communicates its image data to the server's window surface through + shared memory. + + The implementation of \l {QScreen::}{setMode()}, is a stub in this + example. It would normally reset the frame buffer's resolution. + Its parameters are the \e width, \e height, and the bit \e depth + for the frame buffer's new resolution. If you implement setMode() + in your screen driver, remember that it must emit a signal to warn + other applications to redraw their frame buffers with the new + resolution. There is no significance to setMode() not being + implemented in this example. It simply wasn't implemented. + However, the stub had to be included because QScreen declares + setMode() to be pure virtual. + + Before the application exits, the server will call \l {QScreen::} + {shutdownDevice()} to release the hardware resources. This is also + done using EGL library functions. + + \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 9 + + The server will also call \l {QScreen::}{disconnect()}, but this + function is only a stub in this example. + + \section2 The window Surface Class Implementations + + QAhiGLScreen creates instances of QAhiGLWindowSurface in its two + createSurface() functions, and there are two constructors for + QAhiGLWindowSurface that correspond to these two versions of + createSurface(). The constructor accepting a \l {QWidget} {widget} + parameter is called by the client side version of createSurface(), + and the constructor without the \l {QWidget} {widget} parameter is + called by the server side version. There will be a window surface + constructed on the server side for each one constructed on the + client side. + + \snippet examples/qws/ahigl/qwindowsurface_ahigl.cpp 1 + \codeline + \snippet examples/qws/ahigl/qwindowsurface_ahigl.cpp 2 + + The constructors create an instance of QAhiGLWindowSurfacePrivate, + the private implementation class, which contains all the state + variables for QAhiGLWindowSurface. The client side constructor + also creates an instance of QWSGLPaintDevice, the OpenGL paint + device, for return by \l {QWSWindowSurface::} {paintDevice()}. + This ensures that all \l {QPainter}s used on this surface will use + an OpenGL enabled QPaintEngine. It is a bit of jiggery pokery, + which is required because \l {QWSWindowSurface::} {paintDevice()} + is declared pure virtual. Normally, the client side constructor + will be called with an \l {QGLWidget}{OpenGL widget}, which has + its own \l {QWidget::} {paintEngine()} function that returns the + global static OpenGL paint engine, but because the constructor + also accepts a normal \l {QWidget}{widget}, it must be able to + find the OpenGL paint engine in that case as well, so since \l + {QWSWindowSurface::} {paintDevice()} must be implemented anyway, + the constructor creates an instance of QWSGLPaintDevice, which can + always return the global static pointer to QOpenGLPaintEngine. + + The OpenGL library implementation used for this example only + supports one OpenGL context. This context is therefore shared + among the single instance of QAhiGLScreen and all instances of + QAhiGLWindowSurface. It is passed to both constructors. + + This example uses the OpenGL frame buffer object extension, which + allows for accelerating OpenGL painting operations. Using this + OpenGL extension, painting operations are performed in a frame + buffer object, which QAhiGLScreen later uses to construct window + compositions on the screen. Allocation of the frame buffer object + is performed in \l {QWindowSurface::} {setGeometry()}. A safer way + to use this extension would be to first test to see if the + extension is supported by your OpenGL library, and use a different + approach if it is not. + + \snippet examples/qws/ahigl/qwindowsurface_ahigl.cpp 3 + + Since there can be several instances of the QAhiGLWindowSurface, we need + to make sure that the correct framebuffer object is active before painting. + This is done by reimplementing \l QWindowSurface::beginPaint(): + + \snippet examples/qws/ahigl/qwindowsurface_ahigl.cpp 4 + + Finally we need to make sure that whenever a widget grows beyond the size + supported by this driver (256 x 256), the surface is deleted and a new + standard surface is created instead. This is handled by reimplementing + \l QWSWindowSurface::isValid(): + + \snippet examples/qws/ahigl/qwindowsurface_ahigl.cpp 5 +*/ diff --git a/doc/src/examples/analogclock.qdoc b/doc/src/examples/analogclock.qdoc new file mode 100644 index 0000000..d5f7273 --- /dev/null +++ b/doc/src/examples/analogclock.qdoc @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/analogclock + \title Analog Clock Example + + The Analog Clock example shows how to draw the contents of a custom + widget. + + \image analogclock-example.png Screenshot of the Analog Clock example + + This example also demonstrates how the transformation and scaling + features of QPainter can be used to make drawing custom widgets + easier. + + \section1 AnalogClock Class Definition + + The \c AnalogClock class provides a clock widget with hour and minute + hands that is automatically updated every few seconds. + We subclass \l QWidget and reimplement the standard + \l{QWidget::paintEvent()}{paintEvent()} function to draw the clock face: + + \snippet examples/widgets/analogclock/analogclock.h 0 + + \section1 AnalogClock Class Implementation + + \snippet examples/widgets/analogclock/analogclock.cpp 1 + + When the widget is constructed, we set up a one-second timer to + keep track of the current time, and we connect it to the standard + \l{QWidget::update()}{update()} slot so that the clock face is + updated when the timer emits the \l{QTimer::timeout()}{timeout()} + signal. + + Finally, we resize the widget so that it is displayed at a + reasonable size. + + \snippet examples/widgets/analogclock/analogclock.cpp 8 + \snippet examples/widgets/analogclock/analogclock.cpp 10 + + The \c paintEvent() function is called whenever the widget's + contents need to be updated. This happens when the widget is + first shown, and when it is covered then exposed, but it is also + executed when the widget's \l{QWidget::update()}{update()} slot + is called. Since we connected the timer's + \l{QTimer::timeout()}{timeout()} signal to this slot, it will be + called at least once every five seconds. + + Before we set up the painter and draw the clock, we first define + two lists of \l {QPoint}s and two \l{QColor}s that will be used + for the hour and minute hands. The minute hand's color has an + alpha component of 191, meaning that it's 75% opaque. + + We also determine the length of the widget's shortest side so that we + can fit the clock face inside the widget. It is also useful to determine + the current time before we start drawing. + + \snippet examples/widgets/analogclock/analogclock.cpp 11 + \snippet examples/widgets/analogclock/analogclock.cpp 12 + \snippet examples/widgets/analogclock/analogclock.cpp 13 + \snippet examples/widgets/analogclock/analogclock.cpp 14 + + The contents of custom widgets are drawn with a QPainter. + Painters can be used to draw on any QPaintDevice, but they are + usually used with widgets, so we pass the widget instance to the + painter's constructor. + + We call QPainter::setRenderHint() with QPainter::Antialiasing to + turn on antialiasing. This makes drawing of diagonal lines much + smoother. + + The translation moves the origin to the center of the widget, and + the scale operation ensures that the following drawing operations + are scaled to fit within the widget. We use a scale factor that + let's us use x and y coordinates between -100 and 100, and that + ensures that these lie within the length of the widget's shortest + side. + + To make our code simpler, we will draw a fixed size clock face that will + be positioned and scaled so that it lies in the center of the widget. + + The painter takes care of all the transformations made during the + paint event, and ensures that everything is drawn correctly. Letting + the painter handle transformations is often easier than performing + manual calculations just to draw the contents of a custom widget. + + \img analogclock-viewport.png + + We draw the hour hand first, using a formula that rotates the coordinate + system counterclockwise by a number of degrees determined by the current + hour and minute. This means that the hand will be shown rotated clockwise + by the required amount. + + \snippet examples/widgets/analogclock/analogclock.cpp 15 + \snippet examples/widgets/analogclock/analogclock.cpp 16 + + We set the pen to be Qt::NoPen because we don't want any outline, + and we use a solid brush with the color appropriate for + displaying hours. Brushes are used when filling in polygons and + other geometric shapes. + + \snippet examples/widgets/analogclock/analogclock.cpp 17 + \snippet examples/widgets/analogclock/analogclock.cpp 19 + + We save and restore the transformation matrix before and after the + rotation because we want to place the minute hand without having to + take into account any previous rotations. + + \snippet examples/widgets/analogclock/analogclock.cpp 20 + \codeline + \snippet examples/widgets/analogclock/analogclock.cpp 21 + + We draw markers around the edge of the clock for each hour. We + draw each marker then rotate the coordinate system so that the + painter is ready for the next one. + + \snippet examples/widgets/analogclock/analogclock.cpp 22 + \snippet examples/widgets/analogclock/analogclock.cpp 23 + + The minute hand is rotated in a similar way to the hour hand. + + \snippet examples/widgets/analogclock/analogclock.cpp 25 + \codeline + \snippet examples/widgets/analogclock/analogclock.cpp 26 + + Again, we draw markers around the edge of the clock, but this + time to indicate minutes. We skip multiples of 5 to avoid drawing + minute markers on top of hour markers. +*/ diff --git a/doc/src/examples/application.qdoc b/doc/src/examples/application.qdoc new file mode 100644 index 0000000..32e8c10 --- /dev/null +++ b/doc/src/examples/application.qdoc @@ -0,0 +1,410 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example mainwindows/application + \title Application Example + + The Application example shows how to implement a standard GUI + application with menus, toolbars, and a status bar. The example + itself is a simple text editor program built around QTextEdit. + + \image application.png Screenshot of the Application example + + Nearly all of the code for the Application example is in the \c + MainWindow class, which inherits QMainWindow. QMainWindow + provides the framework for windows that have menus, toolbars, + dock windows, and a status bar. The application provides + \menu{File}, \menu{Edit}, and \menu{Help} entries in the menu + bar, with the following popup menus: + + \image application-menus.png The Application example's menu system + + The status bar at the bottom of the main window shows a + description of the menu item or toolbar button under the cursor. + + To keep the example simple, recently opened files aren't shown in + the \menu{File} menu, even though this feature is desired in 90% + of applications. The \l{mainwindows/recentfiles}{Recent Files} + example shows how to implement this. Furthermore, this example + can only load one file at a time. The \l{mainwindows/sdi}{SDI} + and \l{mainwindows/mdi}{MDI} examples shows how to lift these + restrictions. + + \section1 MainWindow Class Definition + + Here's the class definition: + + \snippet examples/mainwindows/application/mainwindow.h 0 + + The public API is restricted to the constructor. In the \c + protected section, we reimplement QWidget::closeEvent() to detect + when the user attempts to close the window, and warn the user + about unsaved changes. In the \c{private slots} section, we + declare slots that correspond to menu entries, as well as a + mysterious \c documentWasModified() slot. Finally, in the \c + private section of the class, we have various members that will + be explained in due time. + + \section1 MainWindow Class Implementation + + \snippet examples/mainwindows/application/mainwindow.cpp 0 + + We start by including \c <QtGui>, a header file that contains the + definition of all classes in the \l QtCore and \l QtGui + libraries. This saves us from the trouble of having to include + every class individually. We also include \c mainwindow.h. + + You might wonder why we don't include \c <QtGui> in \c + mainwindow.h and be done with it. The reason is that including + such a large header from another header file can rapidly degrade + performances. Here, it wouldn't do any harm, but it's still + generally a good idea to include only the header files that are + strictly necessary from another header file. + + \snippet examples/mainwindows/application/mainwindow.cpp 1 + \snippet examples/mainwindows/application/mainwindow.cpp 2 + + In the constructor, we start by creating a QTextEdit widget as a + child of the main window (the \c this object). Then we call + QMainWindow::setCentralWidget() to tell that this is going to be + the widget that occupies the central area of the main window, + between the toolbars and the status bar. + + Then we call \c createActions(), \c createMenus(), \c + createToolBars(), and \c createStatusBar(), four private + functions that set up the user interface. After that, we call \c + readSettings() to restore the user's preferences. + + We establish a signal-slot connection between the QTextEdit's + document object and our \c documentWasModified() slot. Whenever + the user modifies the text in the QTextEdit, we want to update + the title bar to show that the file was modified. + + At the end, we set the window title using the private + \c setCurrentFile() function. We'll come back to this later. + + \target close event handler + \snippet examples/mainwindows/application/mainwindow.cpp 3 + \snippet examples/mainwindows/application/mainwindow.cpp 4 + + When the user attempts to close the window, we call the private + function \c maybeSave() to give the user the possibility to save + pending changes. The function returns true if the user wants the + application to close; otherwise, it returns false. In the first + case, we save the user's preferences to disk and accept the close + event; in the second case, we ignore the close event, meaning + that the application will stay up and running as if nothing + happened. + + \snippet examples/mainwindows/application/mainwindow.cpp 5 + \snippet examples/mainwindows/application/mainwindow.cpp 6 + + The \c newFile() slot is invoked when the user selects + \menu{File|New} from the menu. We call \c maybeSave() to save any + pending changes and if the user accepts to go on, we clear the + QTextEdit and call the private function \c setCurrentFile() to + update the window title and clear the + \l{QWidget::windowModified}{windowModified} flag. + + \snippet examples/mainwindows/application/mainwindow.cpp 7 + \snippet examples/mainwindows/application/mainwindow.cpp 8 + + The \c open() slot is invoked when the user clicks + \menu{File|Open}. We pop up a QFileDialog asking the user to + choose a file. If the user chooses a file (i.e., \c fileName is + not an empty string), we call the private function \c loadFile() + to actually load the file. + + \snippet examples/mainwindows/application/mainwindow.cpp 9 + \snippet examples/mainwindows/application/mainwindow.cpp 10 + + The \c save() slot is invoked when the user clicks + \menu{File|Save}. If the user hasn't provided a name for the file + yet, we call \c saveAs(); otherwise, we call the private function + \c saveFile() to actually save the file. + + \snippet examples/mainwindows/application/mainwindow.cpp 11 + \snippet examples/mainwindows/application/mainwindow.cpp 12 + + In \c saveAs(), we start by popping up a QFileDialog asking the + user to provide a name. If the user clicks \gui{Cancel}, the + returned file name is empty, and we do nothing. + + \snippet examples/mainwindows/application/mainwindow.cpp 13 + \snippet examples/mainwindows/application/mainwindow.cpp 14 + + The application's About box is done using one statement, using + the QMessageBox::about() static function and relying on its + support for an HTML subset. + + The \l{QObject::tr()}{tr()} call around the literal string marks + the string for translation. It is a good habit to call + \l{QObject::tr()}{tr()} on all user-visible strings, in case you + later decide to translate your application to other languages. + The \l{Internationalization with Qt} overview convers + \l{QObject::tr()}{tr()} in more detail. + + \snippet examples/mainwindows/application/mainwindow.cpp 15 + \snippet examples/mainwindows/application/mainwindow.cpp 16 + + The \c documentWasModified() slot is invoked each time the text + in the QTextEdit changes because of user edits. We call + QWidget::setWindowModified() to make the title bar show that the + file was modified. How this is done varies on each platform. + + \snippet examples/mainwindows/application/mainwindow.cpp 17 + \snippet examples/mainwindows/application/mainwindow.cpp 18 + \dots + \snippet examples/mainwindows/application/mainwindow.cpp 22 + + The \c createActions() private function, which is called from the + \c MainWindow constructor, creates \l{QAction}s. The code is very + repetitive, so we show only the actions corresponding to + \menu{File|New}, \menu{File|Open}, and \menu{Help|About Qt}. + + A QAction is an object that represents one user action, such as + saving a file or invoking a dialog. An action can be put in a + QMenu or a QToolBar, or both, or in any other widget that + reimplements QWidget::actionEvent(). + + An action has a text that is shown in the menu, an icon, a + shortcut key, a tooltip, a status tip (shown in the status bar), + a "What's This?" text, and more. It emits a + \l{QAction::triggered()}{triggered()} signal whenever the user + invokes the action (e.g., by clicking the associated menu item or + toolbar button). We connect this signal to a slot that performs + the actual action. + + The code above contains one more idiom that must be explained. + For some of the actions, we specify an icon as a QIcon to the + QAction constructor. The QIcon constructor takes the file name + of an image that it tries to load. Here, the file name starts + with \c{:}. Such file names aren't ordinary file names, but + rather path in the executable's stored resources. We'll come back + to this when we review the \c application.qrc file that's part of + the project. + + \snippet examples/mainwindows/application/mainwindow.cpp 23 + \snippet examples/mainwindows/application/mainwindow.cpp 24 + + The \gui{Edit|Cut} and \gui{Edit|Copy} actions must be available + only when the QTextEdit contains selected text. We disable them + by default and connect the QTextEdit::copyAvailable() signal to + the QAction::setEnabled() slot, ensuring that the actions are + disabled when the text editor has no selection. + + \snippet examples/mainwindows/application/mainwindow.cpp 25 + \snippet examples/mainwindows/application/mainwindow.cpp 27 + + Creating actions isn't sufficient to make them available to the + user; we must also add them to the menu system. This is what \c + createMenus() does. We create a \menu{File}, an \menu{Edit}, and + a \menu{Help} menu. QMainWindow::menuBar() lets us access the + window's menu bar widget. We don't have to worry about creating + the menu bar ourselves; the first time we call this function, the + QMenuBar is created. + + Just before we create the \menu{Help} menu, we call + QMenuBar::addSeparator(). This has no effect for most widget + styles (e.g., Windows and Mac OS X styles), but for Motif-based + styles this makes sure that \menu{Help} is pushed to the right + side of the menu bar. Try running the application with various + styles and see the results: + + \snippet doc/src/snippets/code/doc_src_examples_application.qdoc 0 + + Let's now review the toolbars: + + \snippet examples/mainwindows/application/mainwindow.cpp 30 + + Creating toolbars is very similar to creating menus. The same + actions that we put in the menus can be reused in the toolbars. + + \snippet examples/mainwindows/application/mainwindow.cpp 32 + \snippet examples/mainwindows/application/mainwindow.cpp 33 + + QMainWindow::statusBar() returns a pointer to the main window's + QStatusBar widget. Like with \l{QMainWindow::menuBar()}, the + widget is automatically created the first time the function is + called. + + \snippet examples/mainwindows/application/mainwindow.cpp 34 + \snippet examples/mainwindows/application/mainwindow.cpp 36 + + The \c readSettings() function is called from the constructor to + load the user's preferences and other application settings. The + QSettings class provides a high-level interface for storing + settings permanently on disk. On Windows, it uses the (in)famous + Windows registry; on Mac OS X, it uses the native XML-based + CFPreferences API; on Unix/X11, it uses text files. + + The QSettings constructor takes arguments that identify your + company and the name of the product. This ensures that the + settings for different applications are kept separately. + + We use QSettings::value() to extract the value of the "pos" and + "size" settings. The second argument to QSettings::value() is + optional and specifies a default value for the setting if there + exists none. This value is used the first time the application is + run. + + When restoring the position and size of a window, it's important + to call QWidget::resize() before QWidget::move(). The reason why + is given in the \l{geometry.html}{Window Geometry} overview. + + \snippet examples/mainwindows/application/mainwindow.cpp 37 + \snippet examples/mainwindows/application/mainwindow.cpp 39 + + The \c writeSettings() function is called from \c closeEvent(). + Writing settings is similar to reading them, except simpler. The + arguments to the QSettings constructor must be the same as in \c + readSettings(). + + \snippet examples/mainwindows/application/mainwindow.cpp 40 + \snippet examples/mainwindows/application/mainwindow.cpp 41 + + The \c maybeSave() function is called to save pending changes. If + there are pending changes, it pops up a QMessageBox giving the + user to save the document. The options are QMessageBox::Yes, + QMessageBox::No, and QMessageBox::Cancel. The \gui{Yes} button is + made the default button (the button that is invoked when the user + presses \key{Return}) using the QMessageBox::Default flag; the + \gui{Cancel} button is made the escape button (the button that is + invoked when the user presses \key{Esc}) using the + QMessageBox::Escape flag. + + The \c maybeSave() function returns \c true in all cases, except + when the user clicks \gui{Cancel}. The caller must check the + return value and stop whatever it was doing if the return value + is \c false. + + \snippet examples/mainwindows/application/mainwindow.cpp 42 + \snippet examples/mainwindows/application/mainwindow.cpp 43 + + In \c loadFile(), we use QFile and QTextStream to read in the + data. The QFile object provides access to the bytes stored in a + file. + + We start by opening the file in read-only mode. The QFile::Text + flag indicates that the file is a text file, not a binary file. + On Unix and Mac OS X, this makes no difference, but on Windows, + it ensures that the "\\r\\n" end-of-line sequence is converted to + "\\n" when reading. + + If we successfully opened the file, we use a QTextStream object + to read in the data. QTextStream automatically converts the 8-bit + data into a Unicode QString and supports various encodings. If no + encoding is specified, QTextStream assumes the file is written + using the system's default 8-bit encoding (for example, Latin-1; + see QTextCodec::codecForLocale() for details). + + Since the call to QTextStream::readAll() might take some time, we + set the cursor to be Qt::WaitCursor for the entire application + while it goes on. + + At the end, we call the private \c setCurrentFile() function, + which we'll cover in a moment, and we display the string "File + loaded" in the status bar for 2 seconds (2000 milliseconds). + + \snippet examples/mainwindows/application/mainwindow.cpp 44 + \snippet examples/mainwindows/application/mainwindow.cpp 45 + + Saving a file is very similar to loading one. Here, the + QFile::Text flag ensures that on Windows, "\\n" is converted into + "\\r\\n" to conform to the Windows convension. + + \snippet examples/mainwindows/application/mainwindow.cpp 46 + \snippet examples/mainwindows/application/mainwindow.cpp 47 + + The \c setCurrentFile() function is called to reset the state of + a few variables when a file is loaded or saved, or when the user + starts editing a new file (in which case \c fileName is empty). + We update the \c curFile variable, clear the + QTextDocument::modified flag and the associated \c + QWidget:windowModified flag, and update the window title to + contain the new file name (or \c untitled.txt). + + The \c strippedName() function call around \c curFile in the + QWidget::setWindowTitle() call shortens the file name to exclude + the path. Here's the function: + + \snippet examples/mainwindows/application/mainwindow.cpp 48 + \snippet examples/mainwindows/application/mainwindow.cpp 49 + + \section1 The main() Function + + The \c main() function for this application is typical of + applications that contain one main window: + + \snippet examples/mainwindows/application/main.cpp 0 + + \section1 The Resource File + + As you will probably recall, for some of the actions, we + specified icons with file names starting with \c{:} and mentioned + that such file names aren't ordinary file names, but path in the + executable's stored resources. These resources are compiled + + The resources associated with an application are specified in a + \c .qrc file, an XML-based file format that lists files on the + disk. Here's the \c application.qrc file that's used by the + Application example: + + \quotefile mainwindows/application/application.qrc + + The \c .png files listed in the \c application.qrc file are files + that are part of the Application example's source tree. Paths are + relative to the directory where the \c application.qrc file is + located (the \c mainwindows/application directory). + + The resource file must be mentioned in the \c application.pro + file so that \c qmake knows about it: + + \snippet examples/mainwindows/application/application.pro 0 + + \c qmake will produce make rules to generate a file called \c + qrc_application.cpp that is linked into the application. This + file contains all the data for the images and other resources as + static C++ arrays of compressed binary data. See + \l{resources.html}{The Qt Resource System} for more information + about resources. +*/ diff --git a/doc/src/examples/arrowpad.qdoc b/doc/src/examples/arrowpad.qdoc new file mode 100644 index 0000000..76b753b --- /dev/null +++ b/doc/src/examples/arrowpad.qdoc @@ -0,0 +1,237 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example linguist/arrowpad + \title Arrow Pad Example + + This example is a slightly more involved and introduces a key \e + {Qt Linguist} concept: "contexts". It also shows how to use two + or more languages. + + \image linguist-arrowpad_en.png + + We will use two translations, French and Dutch, although there is no + effective limit on the number of possible translations that can be used + with an application. The relevant lines of \c arrowpad.pro are + + \snippet examples/linguist/arrowpad/arrowpad.pro 0 + \codeline + \snippet examples/linguist/arrowpad/arrowpad.pro 1 + + Run \c lupdate; it should produce two identical message files + \c arrowpad_fr.ts and \c arrowpad_nl.ts. These files will contain all the source + texts marked for translation with \c tr() calls and their contexts. + + See the \l{Qt Linguist manual} for more information about + translating Qt application. + + \section1 Line by Line Walkthrough + + In \c arrowpad.h we define the \c ArrowPad subclass which is a + subclass of QWidget. In the screenshot above, the central + widget with the four buttons is an \c ArrowPad. + + \snippet examples/linguist/arrowpad/arrowpad.h 0 + \snippet examples/linguist/arrowpad/arrowpad.h 1 + \snippet examples/linguist/arrowpad/arrowpad.h 2 + + When \c lupdate is run it not only extracts the source texts but it + also groups them into contexts. A context is the name of the class in + which the source text appears. Thus, in this example, "ArrowPad" is a + context: it is the context of the texts in the \c ArrowPad class. + The \c Q_OBJECT macro defines \c tr(x) in \c ArrowPad like this: + + \snippet doc/src/snippets/code/doc_src_examples_arrowpad.qdoc 0 + + Knowing which class each source text appears in enables \e {Qt + Linguist} to group texts that are logically related together, e.g. + all the text in a dialog will have the context of the dialog's class + name and will be shown together. This provides useful information for + the translator since the context in which text appears may influence how + it should be translated. For some translations keyboard + accelerators may need to be changed and having all the source texts in a + particular context (class) grouped together makes it easier for the + translator to perform any accelerator changes without introducing + conflicts. + + In \c arrowpad.cpp we implement the \c ArrowPad class. + + \snippet examples/linguist/arrowpad/arrowpad.cpp 0 + \snippet examples/linguist/arrowpad/arrowpad.cpp 1 + \snippet examples/linguist/arrowpad/arrowpad.cpp 2 + \snippet examples/linguist/arrowpad/arrowpad.cpp 3 + + We call \c ArrowPad::tr() for each button's label since the labels are + user-visible text. + + \image linguist-arrowpad_en.png + + \snippet examples/linguist/arrowpad/mainwindow.h 0 + \snippet examples/linguist/arrowpad/mainwindow.h 1 + + In the screenshot above, the whole window is a \c MainWindow. + This is defined in the \c mainwindow.h header file. Here too, we + use \c Q_OBJECT, so that \c MainWindow will become a context in + \e {Qt Linguist}. + + \snippet examples/linguist/arrowpad/mainwindow.cpp 0 + + In the implementation of \c MainWindow, \c mainwindow.cpp, we create + an instance of our \c ArrowPad class. + + \snippet examples/linguist/arrowpad/mainwindow.cpp 1 + + We also call \c MainWindow::tr() twice, once for the action and + once for the shortcut. + + Note the use of \c tr() to support different keys in other + languages. "Ctrl+Q" is a good choice for Quit in English, but a + Dutch translator might want to use "Ctrl+A" (for Afsluiten) and a + German translator "Strg+E" (for Beenden). When using \c tr() for + \key Ctrl key accelerators, the two argument form should be used + with the second argument describing the function that the + accelerator performs. + + Our \c main() function is defined in \c main.cpp as usual. + + \snippet examples/linguist/arrowpad/main.cpp 2 + \snippet examples/linguist/arrowpad/main.cpp 3 + + We choose which translation to use according to the current locale. + QLocale::system() can be influenced by setting the \c LANG + environment variable, for example. Notice that the use of a naming + convention that incorporates the locale for \c .qm message files, + (and \c .ts files), makes it easy to implement choosing the + translation file according to locale. + + If there is no \c .qm message file for the locale chosen the original + source text will be used and no error raised. + + \section1 Translating to French and Dutch + + We'll begin by translating the example application into French. Start + \e {Qt Linguist} with \c arrowpad_fr.ts. You should get the seven source + texts ("\&Up", "\&Left", etc.) grouped in two contexts ("ArrowPad" + and "MainWindow"). + + Now, enter the following translations: + + \list + \o \c ArrowPad + \list + \o \&Up - \&Haut + \o \&Left - \&Gauche + \o \&Right - \&Droite + \o \&Down - \&Bas + \endlist + \o \c MainWindow + \list + \o E\&xit - \&Quitter + \o Ctrl+Q - Ctrl+Q + \o \&File - \&Fichier + \endlist + \endlist + + It's quickest to press \key{Alt+D} (which clicks the \gui {Done \& Next} + button) after typing each translation, since this marks the + translation as done and moves on to the next source text. + + Save the file and do the same for Dutch working with \c arrowpad_nl.ts: + + \list + \o \c ArrowPad + \list + \o \&Up - \&Omhoog + \o \&Left - \&Links + \o \&Right - \&Rechts + \o \&Down - Omlaa\&g + \endlist + \o \c MainWindow + \list + \o E\&xit - \&Afsluiten + \o Ctrl+Q - Ctrl+A + \o File - \&Bestand + \endlist + \endlist + + We have to convert the \c tt1_fr.ts and \c tt1_nl.ts translation source + files into \c .qm files. We could use \e {Qt Linguist} as we've done + before; however using the command line tool \c lrelease ensures that + \e all the \c .qm files for the application are created without us + having to remember to load and \gui File|Release each one + individually from \e {Qt Linguist}. + + Type + + \snippet doc/src/snippets/code/doc_src_examples_arrowpad.qdoc 1 + + This should create both \c arrowpad_fr.qm and \c arrowpad_nl.qm. Set the \c + LANG environment variable to \c fr. In Unix, one of the two following + commands should work + + \snippet doc/src/snippets/code/doc_src_examples_arrowpad.qdoc 2 + + In Windows, either modify \c autoexec.bat or run + + \snippet doc/src/snippets/code/doc_src_examples_arrowpad.qdoc 3 + + When you run the program, you should now see the French version: + + \image linguist-arrowpad_fr.png + + Try the same with Dutch, by setting \c LANG=nl. Now the Dutch + version should appear: + + \image linguist-arrowpad_nl.png + + \section1 Exercises + + Mark one of the translations in \e {Qt Linguist} as not done, i.e. + by unchecking the "done" checkbox; run \c lupdate, then \c lrelease, + then the example. What effect did this change have? + + Set \c LANG=fr_CA (French Canada) and run the example program again. + Explain why the result is the same as with \c LANG=fr. + + Change one of the accelerators in the Dutch translation to eliminate the + conflict between \e \&Bestand and \e \&Boven. +*/ diff --git a/doc/src/examples/basicdrawing.qdoc b/doc/src/examples/basicdrawing.qdoc new file mode 100644 index 0000000..5297201 --- /dev/null +++ b/doc/src/examples/basicdrawing.qdoc @@ -0,0 +1,468 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example painting/basicdrawing + \title Basic Drawing Example + + The Basic Drawing example shows how to display basic graphics + primitives in a variety of styles using the QPainter class. + + QPainter performs low-level painting on widgets and other paint + devices. The class can draw everything from simple lines to + complex shapes like pies and chords. It can also draw aligned text + and pixmaps. Normally, it draws in a "natural" coordinate system, + but it can in addition do view and world transformation. + + \image basicdrawing-example.png + + The example provides a render area, displaying the currently + active shape, and lets the user manipulate the rendered shape and + its appearance using the QPainter parameters: The user can change + the active shape (\gui Shape), and modify the QPainter's pen (\gui + {Pen Width}, \gui {Pen Style}, \gui {Pen Cap}, \gui {Pen Join}), + brush (\gui {Brush Style}) and render hints (\gui + Antialiasing). In addition the user can rotate a shape (\gui + Transformations); behind the scenes we use QPainter's ability to + manipulate the coordinate system to perform the rotation. + + The Basic Drawing example consists of two classes: + + \list + \o \c RenderArea is a custom widget that renders multiple + copies of the currently active shape. + \o \c Window is the application's main window displaying a + \c RenderArea widget in addition to several parameter widgets. + \endlist + + First we will review the \c Window class, then we will take a + look at the \c RenderArea class. + + \section1 Window Class Definition + + The Window class inherits QWidget, and is the application's main + window displaying a \c RenderArea widget in addition to several + parameter widgets. + + \snippet examples/painting/basicdrawing/window.h 0 + + We declare the various widgets, and three private slots updating + the \c RenderArea widget: The \c shapeChanged() slot updates the + \c RenderArea widget when the user changes the currently active + shape. We call the \c penChanged() slot when either of the + QPainter's pen parameters changes. And the \c brushChanged() slot + updates the \c RenderArea widget when the user changes the + painter's brush style. + + \section1 Window Class Implementation + + In the constructor we create and initialize the various widgets + appearing in the main application window. + + \snippet examples/painting/basicdrawing/window.cpp 1 + + First we create the \c RenderArea widget that will render the + currently active shape. Then we create the \gui Shape combobox, + and add the associated items (i.e. the different shapes a QPainter + can draw). + + \snippet examples/painting/basicdrawing/window.cpp 2 + + QPainter's pen is a QPen object; the QPen class defines how a + painter should draw lines and outlines of shapes. A pen has + several properties: Width, style, cap and join. + + A pen's width can be \e zero or greater, but the most common width + is zero. Note that this doesn't mean 0 pixels, but implies that + the shape is drawn as smoothly as possible although perhaps not + mathematically correct. + + We create a QSpinBox for the \gui {Pen Width} parameter. + + \snippet examples/painting/basicdrawing/window.cpp 3 + + The pen style defines the line type. The default style is solid + (Qt::SolidLine). Setting the style to none (Qt::NoPen) tells the + painter to not draw lines or outlines. The pen cap defines how + the end points of lines are drawn. And the pen join defines how + two lines join when multiple connected lines are drawn. The cap + and join only apply to lines with a width of 1 pixel or greater. + + We create \l {QComboBox}es for each of the \gui {Pen Style}, \gui + {Pen Cap} and \gui {Pen Join} parameters, and adds the associated + items (i.e the values of the Qt::PenStyle, Qt::PenCapStyle and + Qt::PenJoinStyle enums respectively). + + \snippet examples/painting/basicdrawing/window.cpp 4 + + The QBrush class defines the fill pattern of shapes drawn by a + QPainter. The default brush style is Qt::NoBrush. This style tells + the painter to not fill shapes. The standard style for filling is + Qt::SolidPattern. + + We create a QComboBox for the \gui {Brush Style} parameter, and add + the associated items (i.e. the values of the Qt::BrushStyle enum). + + \snippet examples/painting/basicdrawing/window.cpp 5 + \snippet examples/painting/basicdrawing/window.cpp 6 + + Antialiasing is a feature that "smoothes" the pixels to create + more even and less jagged lines, and can be applied using + QPainter's render hints. QPainter::RenderHints are used to specify + flags to QPainter that may or may not be respected by any given + engine. + + We simply create a QCheckBox for the \gui Antialiasing option. + + \snippet examples/painting/basicdrawing/window.cpp 7 + + The \gui Transformations option implies a manipulation of the + coordinate system that will appear as if the rendered shape is + rotated in three dimensions. + + We use the QPainter::translate(), QPainter::rotate() and + QPainter::scale() functions to implement this feature represented + in the main application window by a simple QCheckBox. + + \snippet examples/painting/basicdrawing/window.cpp 8 + + Then we connect the parameter widgets with their associated slots + using the static QObject::connect() function, ensuring that the \c + RenderArea widget is updated whenever the user changes the shape, + or any of the other parameters. + + \snippet examples/painting/basicdrawing/window.cpp 9 + \snippet examples/painting/basicdrawing/window.cpp 10 + + Finally, we add the various widgets to a layout, and call the \c + shapeChanged(), \c penChanged(), and \c brushChanged() slots to + initialize the application. We also turn on antialiasing. + + \snippet examples/painting/basicdrawing/window.cpp 11 + + The \c shapeChanged() slot is called whenever the user changes the + currently active shape. + + First we retrieve the shape the user has chosen using the + QComboBox::itemData() function. This function returns the data for + the given role in the given index in the combobox. We use + QComboBox::currentIndex() to retrieve the index of the shape, and + the role is defined by the Qt::ItemDataRole enum; \c IdRole is an + alias for Qt::UserRole. + + Note that Qt::UserRole is only the first role that can be used for + application-specific purposes. If you need to store different data + in the same index, you can use different roles by simply + incrementing the value of Qt::UserRole, for example: 'Qt::UserRole + + 1' and 'Qt::UserRole + 2'. However, it is a good programming + practice to give each role their own name: 'myFirstRole = + Qt::UserRole + 1' and 'mySecondRole = Qt::UserRole + 2'. Even + though we only need a single role in this particular example, we + add the following line of code to the beginning of the \c + window.cpp file. + + \snippet examples/painting/basicdrawing/window.cpp 0 + + The QComboBox::itemData() function returns the data as a QVariant, + so we need to cast the data to \c RenderArea::Shape. If there is + no data for the given role, the function returns + QVariant::Invalid. + + In the end we call the \c RenderArea::setShape() slot to update + the \c RenderArea widget. + + \snippet examples/painting/basicdrawing/window.cpp 12 + + We call the \c penChanged() slot whenever the user changes any of + the pen parameters. Again we use the QComboBox::itemData() + function to retrieve the parameters, and then we call the \c + RenderArea::setPen() slot to update the \c RenderArea widget. + + \snippet examples/painting/basicdrawing/window.cpp 13 + + The brushChanged() slot is called whenever the user changes the + brush parameter which we retrieve using the QComboBox::itemData() + function as before. + + \snippet examples/painting/basicdrawing/window.cpp 14 + + If the brush parameter is a gradient fill, special actions are + required. + + The QGradient class is used in combination with QBrush to specify + gradient fills. Qt currently supports three types of gradient + fills: linear, radial and conical. Each of these is represented by + a subclass of QGradient: QLinearGradient, QRadialGradient and + QConicalGradient. + + So if the brush style is Qt::LinearGradientPattern, we first + create a QLinearGradient object with interpolation area between + the coordinates passed as arguments to the constructor. The + positions are specified using logical coordinates. Then we set the + gradient's colors using the QGradient::setColorAt() function. The + colors is defined using stop points which are composed by a + position (between 0 and 1) and a QColor. The set of stop points + describes how the gradient area should be filled. A gradient can + have an arbitrary number of stop points. + + In the end we call \c RenderArea::setBrush() slot to update the \c + RenderArea widget's brush with the QLinearGradient object. + + \snippet examples/painting/basicdrawing/window.cpp 15 + + A similar pattern of actions, as the one used for QLinearGradient, + is used in the cases of Qt::RadialGradientPattern and + Qt::ConicalGradientPattern. + + The only difference is the arguments passed to the constructor: + Regarding the QRadialGradient constructor the first argument is + the center, and the second the radial gradient's radius. The third + argument is optional, but can be used to define the focal point of + the gradient inside the circle (the default focal point is the + circle center). Regarding the QConicalGradient constructor, the + first argument specifies the center of the conical, and the second + specifies the start angle of the interpolation. + + \snippet examples/painting/basicdrawing/window.cpp 16 + + If the brush style is Qt::TexturePattern we create a QBrush from a + QPixmap. Then we call \c RenderArea::setBrush() slot to update the + \c RenderArea widget with the newly created brush. + + \snippet examples/painting/basicdrawing/window.cpp 17 + + Otherwise we simply create a brush with the given style and a + green color, and then call \c RenderArea::setBrush() slot to + update the \c RenderArea widget with the newly created brush. + + \section1 RenderArea Class Definition + + The \c RenderArea class inherits QWidget, and renders multiple + copies of the currently active shape using a QPainter. + + \snippet examples/painting/basicdrawing/renderarea.h 0 + + First we define a public \c Shape enum to hold the different + shapes that can be rendered by the widget (i.e the shapes that can + be rendered by a QPainter). Then we reimplement the constructor as + well as two of QWidget's public functions: \l + {QWidget::minimumSizeHint()}{minimumSizeHint()} and \l + {QWidget::sizeHint()}{sizeHint()}. + + We also reimplement the QWidget::paintEvent() function to be able + to draw the currently active shape according to the specified + parameters. + + We declare several private slots: The \c setShape() slot changes + the \c RenderArea's shape, the \c setPen() and \c setBrush() slots + modify the widget's pen and brush, and the \c setAntialiased() and + \c setTransformed() slots modify the widget's respective + properties. + + \section1 RenderArea Class Implementation + + In the constructor we initialize some of the widget's variables. + + \snippet examples/painting/basicdrawing/renderarea.cpp 0 + + We set its shape to be a \gui Polygon, its antialiased property to + be false and we load an image into the widget's pixmap + variable. In the end we set the widget's background role, defining + the brush from the widget's \l {QWidget::palette}{palette} that + will be used to render the background. QPalette::Base is typically + white. + + \snippet examples/painting/basicdrawing/renderarea.cpp 2 + + The \c RenderArea inherits QWidget's \l + {QWidget::sizeHint()}{sizeHint} property holding the recommended + size for the widget. If the value of this property is an invalid + size, no size is recommended. + + The default implementation of the QWidget::sizeHint() function + returns an invalid size if there is no layout for the widget, and + returns the layout's preferred size otherwise. + + Our reimplementation of the function returns a QSize with a 400 + pixels width and a 200 pixels height. + + \snippet examples/painting/basicdrawing/renderarea.cpp 1 + + \c RenderArea also inherits QWidget's + \l{QWidget::minimumSizeHint()}{minimumSizeHint} property holding + the recommended minimum size for the widget. Again, if the value + of this property is an invalid size, no size is recommended. + + The default implementation of QWidget::minimumSizeHint() returns + an invalid size if there is no layout for the widget, and returns + the layout's minimum size otherwise. + + Our reimplementation of the function returns a QSize with a 100 + pixels width and a 100 pixels height. + + \snippet examples/painting/basicdrawing/renderarea.cpp 3 + \codeline + \snippet examples/painting/basicdrawing/renderarea.cpp 4 + \codeline + \snippet examples/painting/basicdrawing/renderarea.cpp 5 + + The public \c setShape(), \c setPen() and \c setBrush() slots are + called whenever we want to modify a \c RenderArea widget's shape, + pen or brush. We set the shape, pen or brush according to the + slot parameter, and call QWidget::update() to make the changes + visible in the \c RenderArea widget. + + The QWidget::update() slot does not cause an immediate + repaint; instead it schedules a paint event for processing when Qt + returns to the main event loop. + + \snippet examples/painting/basicdrawing/renderarea.cpp 6 + \codeline + \snippet examples/painting/basicdrawing/renderarea.cpp 7 + + With the \c setAntialiased() and \c setTransformed() slots we + change the state of the properties according to the slot + parameter, and call the QWidget::update() slot to make the changes + visible in the \c RenderArea widget. + + \snippet examples/painting/basicdrawing/renderarea.cpp 8 + + Then we reimplement the QWidget::paintEvent() function. The first + thing we do is to create the graphical objects we will need to + draw the various shapes. + + We create a vector of four \l {QPoint}s. We use this vector to + render the \gui Points, \gui Polyline and \gui Polygon + shapes. Then we create a QRect, defining a rectangle in the plane, + which we use as the bounding rectangle for all the shapes excluding + the \gui Path and the \gui Pixmap. + + We also create a QPainterPath. The QPainterPath class provides a + container for painting operations, enabling graphical shapes to be + constructed and reused. A painter path is an object composed of a + number of graphical building blocks, such as rectangles, ellipses, + lines, and curves. For more information about the QPainterPath + class, see the \l {painting/painterpaths}{Painter Paths} + example. In this example, we create a painter path composed of one + straight line and a Bezier curve. + + In addition we define a start angle and an arc length that we will + use when drawing the \gui Arc, \gui Chord and \gui Pie shapes. + + \snippet examples/painting/basicdrawing/renderarea.cpp 9 + + We create a QPainter for the \c RenderArea widget, and set the + painters pen and brush according to the \c RenderArea's pen and + brush. If the \gui Antialiasing parameter option is checked, we + also set the painter's render hints. QPainter::Antialiasing + indicates that the engine should antialias edges of primitives if + possible. + + \snippet examples/painting/basicdrawing/renderarea.cpp 10 + + Finally, we render the multiple copies of the \c RenderArea's + shape. The number of copies is depending on the size of the \c + RenderArea widget, and we calculate their positions using two \c + for loops and the widgets height and width. + + For each copy we first save the current painter state (pushes the + state onto a stack). Then we translate the coordinate system, + using the QPainter::translate() function, to the position + determined by the variables of the \c for loops. If we omit this + translation of the coordinate system all the copies of the shape + will be rendered on top of each other in the top left cormer of + the \c RenderArea widget. + + \snippet examples/painting/basicdrawing/renderarea.cpp 11 + + If the \gui Transformations parameter option is checked, we do an + additional translation of the coordinate system before we rotate + the coordinate system 60 degrees clockwise using the + QPainter::rotate() function and scale it down in size using the + QPainter::scale() function. In the end we translate the coordinate + system back to where it was before we rotated and scaled it. + + Now, when rendering the shape, it will appear as if it was rotated + in three dimensions. + + \snippet examples/painting/basicdrawing/renderarea.cpp 12 + + Next, we identify the \c RenderArea's shape, and render it using + the associated QPainter drawing function: + + \list + \o QPainter::drawLine(), + \o QPainter::drawPoints(), + \o QPainter::drawPolyline(), + \o QPainter::drawPolygon(), + \o QPainter::drawRect(), + \o QPainter::drawRoundedRect(), + \o QPainter::drawEllipse(), + \o QPainter::drawArc(), + \o QPainter::drawChord(), + \o QPainter::drawPie(), + \o QPainter::drawPath(), + \o QPainter::drawText() or + \o QPainter::drawPixmap() + \endlist + + Before we started rendering, we saved the current painter state + (pushes the state onto a stack). The rationale for this is that we + calculate each shape copy's position relative to the same point in + the coordinate system. When translating the coordinate system, we + lose the knowledge of this point unless we save the current + painter state \e before we start the translating process. + + \snippet examples/painting/basicdrawing/renderarea.cpp 13 + + Then, when we are finished rendering a copy of the shape we can + restore the original painter state, with its associated coordinate + system, using the QPainter::restore() function. In this way we + ensure that the next shape copy will be rendered in the correct + position. + + We could translate the coordinate system back using + QPainter::translate() instead of saving the painter state. But + since we in addition to translating the coordinate system (when + the \gui Transformation parameter option is checked) both rotate + and scale the coordinate system, the easiest solution is to save + the current painter state. +*/ diff --git a/doc/src/examples/basicgraphicslayouts.qdoc b/doc/src/examples/basicgraphicslayouts.qdoc new file mode 100644 index 0000000..92571af --- /dev/null +++ b/doc/src/examples/basicgraphicslayouts.qdoc @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example graphicsview/basicgraphicslayouts + \title Basic Graphics Layouts Example + + The Basic Graphics Layouts example shows how to use the layout classes + in QGraphicsView: QGraphicsLinearLayout and QGraphicsGridLayout. + + \image basicgraphicslayouts-example.png Screenshot of the Basic Layouts Example + + \section1 Window Class Definition + + The \c Window class is a subclass of QGraphicsWidget. It has a + constructor with a QGraphicsWidget \a parent as its parameter. + + \snippet examples/graphicsview/basicgraphicslayouts/window.h 0 + + \section1 Window Class Implementation + + The constructor of \c Window instantiates a QGraphicsLinearLayout object, + \c windowLayout, with vertical orientation. We instantiate another + QGraphicsLinearLayout object, \c linear, whose parent is \c windowLayout. + Next, we create a \c LayoutItem object, \c item and add it to \c linear + with the \l{QGraphicsLinearLayout::}{addItem()} function. We also provide + \c item with a \l{QGraphicsLinearLayout::setStretchFactor()} + {stretchFactor}. + + \snippet examples/graphicsview/basicgraphicslayouts/window.cpp 0 + + We repeat the process: + + \list + \o create a new \c LayoutItem, + \o add the item \c linear, and + \o provide a stretch factor. + \endlist + + \snippet examples/graphicsview/basicgraphicslayouts/window.cpp 1 + + We then add \c linear to \c windowLayout, nesting two + QGraphicsLinearLayout objects. Apart from the QGraphicsLinearLayout, we + also use a QGraphicsGridLayout object, \c grid, which is a 4x3 grid with + some cells spanning to other rows. + + We create seven \c LayoutItem objects and place them into \c grid with + the \l{QGraphicsGridLayout::}{addItem()} function as shown in the code + snippet below: + + \snippet examples/graphicsview/basicgraphicslayouts/window.cpp 2 + + The first item we add to \c grid is placed in the top left cell, + spanning four rows. The next two items are placed in the second column, + and they span two rows. Each item's \l{QGraphicsWidget::}{maximumHeight()} + and \l{QGraphicsWidget::}{minimumHeight()} are set to be equal so that + they do not expand vertically. As a result, these items will not + fit vertically in their cells. So, we specify that they should be + vertically aligned in the center of the cell using Qt::AlignVCenter. + + Finally, \c grid itself is added to \c windowLayout. Unlike + QGridLayout::addItem(), QGraphicsGridLayout::addItem() requires a row + and a column for its argument, specifying which cell the item should be + positioned in. Also, if the \c rowSpan and \c columnSpan arguments + are omitted, they will default to 1. + + Note that we do not specify a parent for each \c LayoutItem that we + construct, as all these items will be added to \c windowLayout. When we + add an item to a layout, it will be automatically reparented to the widget + on which the layout is installed. + + \snippet examples/graphicsview/basicgraphicslayouts/window.cpp 3 + + Now that we have set up \c grid and added it to \c windowLayout, we + install \c windowLayout onto the window object using + QGraphicsWidget::setLayout() and we set the window title. + + \section1 LayoutItem Class Definition + + The \c LayoutItem class is a subclass of QGraphicsWidget. It has a + constructor, a destructor, and a reimplementation of the + {QGraphicsItem::paint()}{paint()} function. + + \snippet examples/graphicsview/basicgraphicslayouts/layoutitem.h 0 + + The \c LayoutItem class also has a private instance of QPixmap, \c pix. + + \note We subclass QGraphicsWidget so that \c LayoutItem objects can + be automatically plugged into a layout, as QGraphicsWidget is a + specialization of QGraphicsLayoutItem. + + \section1 LayoutItem Class Implementation + + In \c{LayoutItem}'s constructor, \c pix is instantiated and the + \c{QT_original_R.png} image is loaded into it. We set the size of + \c LayoutItem to be slightly larger than the size of the pixmap as we + require some space around it for borders that we will paint later. + Alternatively, you could scale the pixmap to prevent the item from + becoming smaller than the pixmap. + + \snippet examples/graphicsview/basicgraphicslayouts/layoutitem.cpp 0 + + We use the Q_UNUSED() macro to prevent the compiler from generating + warnings regarding unused parameters. + + \snippet examples/graphicsview/basicgraphicslayouts/layoutitem.cpp 1 + + The idea behind the \c paint() function is to paint the + background rect then paint a rect around the pixmap. + + \snippet examples/graphicsview/basicgraphicslayouts/layoutitem.cpp 2 + +*/
\ No newline at end of file diff --git a/doc/src/examples/basiclayouts.qdoc b/doc/src/examples/basiclayouts.qdoc new file mode 100644 index 0000000..0d64b1f --- /dev/null +++ b/doc/src/examples/basiclayouts.qdoc @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example layouts/basiclayouts + \title Basic Layouts Example + + The Basic Layouts example shows how to use the standard layout + managers that are available in Qt: QBoxLayout, QGridLayout and + QFormLayout. + + \image basiclayouts-example.png Screenshot of the Basic Layouts example + + The QBoxLayout class lines up widgets horizontally or vertically. + QHBoxLayout and QVBoxLayout are convenience subclasses of QBoxLayout. + QGridLayout lays out widgets in cells by dividing the available space + into rows and columns. QFormLayout, on the other hand, lays out its + children in a two-column form with labels in the left column and + input fields in the right column. + + \section1 Dialog Class Definition + + \snippet examples/layouts/basiclayouts/dialog.h 0 + + The \c Dialog class inherits QDialog. It is a custom widget that + displays its child widgets using the geometry managers: + QHBoxLayout, QVBoxLayout, QGridLayout and QFormLayout. + + We declare four private functions to simplify the class + constructor: The \c createMenu(), \c createHorizontalGroupBox(), + \c createGridGroupBox() and \c createFormGroupBox() functions create + several widgets that the example uses to demonstrate how the layout + affects their appearances. + + \section1 Dialog Class Implementation + + \snippet examples/layouts/basiclayouts/dialog.cpp 0 + + In the constructor, we first use the \c createMenu() function to + create and populate a menu bar and the \c createHorizontalGroupBox() + function to create a group box containing four buttons with a + horizontal layout. Next we use the \c createGridGroupBox() function + to create a group box containing several line edits and a small text + editor which are displayed in a grid layout. Finally, we use the + \c createFormGroupBox() function to createa a group box with + three labels and three input fields: a line edit, a combo box and + a spin box. + + \snippet examples/layouts/basiclayouts/dialog.cpp 1 + + We also create a big text editor and a dialog button box. The + QDialogButtonBox class is a widget that presents buttons in a + layout that is appropriate to the current widget style. The + preferred buttons can be specified as arguments to the + constructor, using the QDialogButtonBox::StandardButtons enum. + + Note that we don't have to specify a parent for the widgets when + we create them. The reason is that all the widgets we create here + will be added to a layout, and when we add a widget to a layout, + it is automatically reparented to the widget the layout is + installed on. + + \snippet examples/layouts/basiclayouts/dialog.cpp 2 + + The main layout is a QVBoxLayout object. QVBoxLayout is a + convenience class for a box layout with vertical orientation. + + In general, the QBoxLayout class takes the space it gets (from its + parent layout or from the parent widget), divides it up into a + series of boxes, and makes each managed widget fill one box. If + the QBoxLayout's orientation is Qt::Horizontal the boxes are + placed in a row. If the orientation is Qt::Vertical, the boxes are + placed in a column. The corresponding convenience classes are + QHBoxLayout and QVBoxLayout, respectively. + + \snippet examples/layouts/basiclayouts/dialog.cpp 3 + + When we call the QLayout::setMenuBar() function, the layout places + the provided menu bar at the top of the parent widget, and outside + the widget's \l {QWidget::contentsRect()}{content margins}. All + child widgets are placed below the bottom edge of the menu bar. + + \snippet examples/layouts/basiclayouts/dialog.cpp 4 + + We use the QBoxLayout::addWidget() function to add the widgets to + the end of layout. Each widget will get at least its minimum size + and at most its maximum size. It is possible to specify a stretch + factor in the \l {QBoxLayout::addWidget()}{addWidget()} function, + and any excess space is shared according to these stretch + factors. If not specified, a widget's stretch factor is 0. + + \snippet examples/layouts/basiclayouts/dialog.cpp 5 + + We install the main layout on the \c Dialog widget using the + QWidget::setLayout() function, and all of the layout's widgets are + automatically reparented to be children of the \c Dialog widget. + + \snippet examples/layouts/basiclayouts/dialog.cpp 6 + + In the private \c createMenu() function we create a menu bar, and + add a pull-down \gui File menu containing an \gui Exit option. + + \snippet examples/layouts/basiclayouts/dialog.cpp 7 + + When we create the horizontal group box, we use a QHBoxLayout as + the internal layout. We create the buttons we want to put in the + group box, add them to the layout and install the layout on the + group box. + + \snippet examples/layouts/basiclayouts/dialog.cpp 8 + + In the \c createGridGroupBox() function we use a QGridLayout which + lays out widgets in a grid. It takes the space made available to + it (by its parent layout or by the parent widget), divides it up + into rows and columns, and puts each widget it manages into the + correct cell. + + \snippet examples/layouts/basiclayouts/dialog.cpp 9 + + For each row in the grid we create a label and an associated line + edit, and add them to the layout. The QGridLayout::addWidget() + function differ from the corresponding function in QBoxLayout: It + needs the row and column specifying the grid cell to put the + widget in. + + \snippet examples/layouts/basiclayouts/dialog.cpp 10 + + QGridLayout::addWidget() can in addition take arguments + specifying the number of rows and columns the cell will be + spanning. In this example, we create a small editor which spans + three rows and one column. + + For both the QBoxLayout::addWidget() and QGridLayout::addWidget() + functions it is also possible to add a last argument specifying + the widget's alignment. By default it fills the whole cell. But we + could, for example, align a widget with the right edge by + specifying the alignment to be Qt::AlignRight. + + \snippet examples/layouts/basiclayouts/dialog.cpp 11 + + Each column in a grid layout has a stretch factor. The stretch + factor is set using QGridLayout::setColumnStretch() and determines + how much of the available space the column will get over and above + its necessary minimum. + + In this example, we set the stretch factors for columns 1 and 2. + The stretch factor is relative to the other columns in this grid; + columns with a higher stretch factor take more of the available + space. So column 2 in our grid layout will get more of the + available space than column 1, and column 0 will not grow at all + since its stretch factor is 0 (the default). + + Columns and rows behave identically; there is an equivalent + stretch factor for rows, as well as a QGridLayout::setRowStretch() + function. + + \snippet examples/layouts/basiclayouts/dialog.cpp 12 + + In the \c createFormGroupBox() function, we use a QFormLayout + to neatly arrange objects into two columns - name and field. + There are three QLabel objects for names with three + corresponding input widgets as fields: a QLineEdit, a QComboBox + and a QSpinBox. Unlike QBoxLayout::addWidget() and + QGridLayout::addWidget(), we use QFormLayout::addRow() to add widgets + to the layout. +*/ diff --git a/doc/src/examples/basicsortfiltermodel.qdoc b/doc/src/examples/basicsortfiltermodel.qdoc new file mode 100644 index 0000000..557729a --- /dev/null +++ b/doc/src/examples/basicsortfiltermodel.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/basicsortfiltermodel + \title Basic Sort/Filter Model Example + + The Basic Sort/Filter Model example illustrates how to use + QSortFilterProxyModel to perform basic sorting and filtering. + + \image basicsortfiltermodel-example.png Screenshot of the Basic Sort/Filter Model Example + +*/ diff --git a/doc/src/examples/blockingfortuneclient.qdoc b/doc/src/examples/blockingfortuneclient.qdoc new file mode 100644 index 0000000..5c9dbe1 --- /dev/null +++ b/doc/src/examples/blockingfortuneclient.qdoc @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example network/blockingfortuneclient + \title Blocking Fortune Client Example + + The Blocking Fortune Client example shows how to create a client for a + network service using QTcpSocket's synchronous API in a non-GUI thread. + + \image blockingfortuneclient-example.png + + QTcpSocket supports two general approaches to network programming: + + \list + + \o \e{The asynchronous (non-blocking) approach.} Operations are scheduled + and performed when control returns to Qt's event loop. When the operation + is finished, QTcpSocket emits a signal. For example, + QTcpSocket::connectToHost() returns immediately, and when the connection + has been established, QTcpSocket emits + \l{QTcpSocket::connected()}{connected()}. + + \o \e{The synchronous (blocking) approach.} In non-GUI and multithreaded + applications, you can call the \c waitFor...() functions (e.g., + QTcpSocket::waitForConnected()) to suspend the calling thread until the + operation has completed, instead of connecting to signals. + + \endlist + + The implementation is very similar to the + \l{network/fortuneclient}{Fortune Client} example, but instead of having + QTcpSocket as a member of the main class, doing asynchronous networking in + the main thread, we will do all network operations in a separate thread + and use QTcpSocket's blocking API. + + The purpose of this example is to demonstrate a pattern that you can use + to simplify your networking code, without losing responsiveness in your + user interface. Use of Qt's blocking network API often leads to + simpler code, but because of its blocking behavior, it should only be used + in non-GUI threads to prevent the user interface from freezing. But + contrary to what many think, using threads with QThread does not + necessarily add unmanagable complexity to your application. + + We will start with the FortuneThread class, which handles the network + code. + + \snippet examples/network/blockingfortuneclient/fortunethread.h 0 + + FortuneThread is a QThread subclass that provides an API for scheduling + requests for fortunes, and it has signals for delivering fortunes and + reporting errors. You can call requestNewFortune() to request a new + fortune, and the result is delivered by the newFortune() signal. If any + error occurs, the error() signal is emitted. + + It's important to notice that requestNewFortune() is called from the main, + GUI thread, but the host name and port values it stores will be accessed + from FortuneThread's thread. Because we will be reading and writing + FortuneThread's data members from different threads concurrently, we use + QMutex to synchronize access. + + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 2 + + The requestNewFortune() function stores the host name and port of the + fortune server as member data, and we lock the mutex with QMutexLocker to + protect this data. We then start the thread, unless it is already + running. We will come back to the QWaitCondition::wakeOne() call later. + + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 4 + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 5 + + In the run() function, we start by acquiring the mutex lock, fetching the + host name and port from the member data, and then releasing the lock + again. The case that we are protecting ourselves against is that \c + requestNewFortune() could be called at the same time as we are fetching + this data. QString is \l reentrant but \e not \l{thread-safe}, and we must + also avoid the unlikely risk of reading the host name from one request, + and port of another. And as you might have guessed, FortuneThread can only + handle one request at a time. + + The run() function now enters a loop: + + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 6 + + The loop will continue requesting fortunes for as long as \e quit is + false. We start our first request by creating a QTcpSocket on the stack, + and then we call \l{QTcpSocket::connectToHost()}{connectToHost()}. This + starts an asynchronous operation which, after control returns to Qt's + event loop, will cause QTcpSocket to emit + \l{QTcpSocket::connected()}{connected()} or + \l{QTcpSocket::error()}{error()}. + + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 8 + + But since we are running in a non-GUI thread, we do not have to worry + about blocking the user interface. So instead of entering an event loop, + we simply call QTcpSocket::waitForConnected(). This function will wait, + blocking the calling thread, until QTcpSocket emits connected() or an + error occurs. If connected() is emitted, the function returns true; if the + connection failed or timed out (which in this example happens after 5 + seconds), false is returned. QTcpSocket::waitForConnected(), like the + other \c waitFor...() functions, is part of QTcpSocket's \e{blocking + API}. + + After this statement, we have a connected socket to work with. Now it's + time to see what the fortune server has sent us. + + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 9 + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 10 + + This step is to read the size of the packet. Although we are only reading + two bytes here, and the \c while loop may seem to overdo it, we present this + code to demonstrate a good pattern for waiting for data using + QTcpSocket::waitForReadyRead(). It goes like this: For as long as we still + need more data, we call waitForReadyRead(). If it returns false, + we abort the operation. After this statement, we know that we have received + enough data. + + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 11 + + Now we can create a QDataStream object, passing the socket to + QDataStream's constructor, and as in the other client examples we set + the stream protocol version to QDataStream::Qt_4_0, and read the size + of the packet. + + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 12 + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 13 + + Again, we'll use a loop that waits for more data by calling + QTcpSocket::waitForReadyRead(). In this loop, we're waiting until + QTcpSocket::bytesAvailable() returns the full packet size. + + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 14 + + Now that we have all the data that we need, we can use QDataStream to + read the fortune string from the packet. The resulting fortune is + delivered by emitting newFortune(). + + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 15 + + The final part of our loop is that we acquire the mutex so that we can + safely read from our member data. We then let the thread go to sleep by + calling QWaitCondition::wait(). At this point, we can go back to + requestNewFortune() and look closed at the call to wakeOne(): + + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 1 + \dots + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 3 + + What happened here was that because the thread falls asleep waiting for a + new request, we needed to wake it up again when a new request + arrives. QWaitCondition is often used in threads to signal a wakeup call + like this. + + \snippet examples/network/blockingfortuneclient/fortunethread.cpp 0 + + Finishing off the FortuneThread walkthrough, this is the destructor that + sets \e quit to true, wakes up the thread and waits for the thread to exit + before returning. This lets the \c while loop in run() will finish its current + iteration. When run() returns, the thread will terminate and be destroyed. + + Now for the BlockingClient class: + + \snippet examples/network/blockingfortuneclient/blockingclient.h 0 + + BlockingClient is very similar to the Client class in the + \l{network/fortuneclient}{Fortune Client} example, but in this class + we store a FortuneThread member instead of a pointer to a QTcpSocket. + When the user clicks the "Get Fortune" button, the same slot is called, + but its implementation is slightly different: + + \snippet examples/network/blockingfortuneclient/blockingclient.cpp 0 + \snippet examples/network/blockingfortuneclient/blockingclient.cpp 1 + + We connect our FortuneThread's two signals newFortune() and error() (which + are somewhat similar to QTcpSocket::readyRead() and QTcpSocket::error() in + the previous example) to requestNewFortune() and displayError(). + + \snippet examples/network/blockingfortuneclient/blockingclient.cpp 2 + + The requestNewFortune() slot calls FortuneThread::requestNewFortune(), + which \e shedules the request. When the thread has received a new fortune + and emits newFortune(), our showFortune() slot is called: + + \snippet examples/network/blockingfortuneclient/blockingclient.cpp 3 + \codeline + \snippet examples/network/blockingfortuneclient/blockingclient.cpp 4 + + Here, we simply display the fortune we received as the argument. + + \sa {Fortune Client Example}, {Fortune Server Example} +*/ diff --git a/doc/src/examples/borderlayout.qdoc b/doc/src/examples/borderlayout.qdoc new file mode 100644 index 0000000..6275249 --- /dev/null +++ b/doc/src/examples/borderlayout.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example layouts/borderlayout + \title Border Layout Example + + The Border Layout example shows how to create a custom layout that arranges + child widgets according to a simple set of rules. + + \image borderlayout-example.png +*/ diff --git a/doc/src/examples/broadcastreceiver.qdoc b/doc/src/examples/broadcastreceiver.qdoc new file mode 100644 index 0000000..253b68b --- /dev/null +++ b/doc/src/examples/broadcastreceiver.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example network/broadcastreceiver + \title Broadcast Receiver Example + + The Broadcast Receiever example shows how to receive information that is broadcasted + over a local network. + + \image broadcastreceiver-example.png +*/ diff --git a/doc/src/examples/broadcastsender.qdoc b/doc/src/examples/broadcastsender.qdoc new file mode 100644 index 0000000..05975aa --- /dev/null +++ b/doc/src/examples/broadcastsender.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example network/broadcastsender + \title Broadcast Sender Example + + The Broadcast Sender example shows how to broadcast information to multiple clients + on a local network. + + \image broadcastsender-example.png +*/ diff --git a/doc/src/examples/cachedtable.qdoc b/doc/src/examples/cachedtable.qdoc new file mode 100644 index 0000000..b7f416b --- /dev/null +++ b/doc/src/examples/cachedtable.qdoc @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example sql/cachedtable + \title Cached Table Example + + The Cached Table example shows how a table view can be used to access a database, + caching any changes to the data until the user explicitly submits them using a + push button. + + \image cachedtable-example.png + + The example consists of a single class, \c TableEditor, which is a + custom dialog widget that allows the user to modify data stored in + a database. We will first review the class definiton and how to + use the class, then we will take a look at the implementation. + + \section1 TableEditor Class Definition + + The \c TableEditor class inherits QDialog making the table editor + widget a top-level dialog window. + + \snippet examples/sql/cachedtable/tableeditor.h 0 + + The \c TableEditor constructor takes two arguments: The first is a + pointer to the parent widget and is passed on to the base class + constructor. The other is a reference to the database table the \c + TableEditor object will operate on. + + Note the QSqlTableModel variable declaration: As we will see in + this example, the QSqlTableModel class can be used to provide data + to view classes such as QTableView. The QSqlTableModel class + provides an editable data model making it possible to read and + write database records from a single table. It is build on top of + the lower-level QSqlQuery class which provides means of executing + and manipulating SQL statements. + + We are also going to show how a table view can be used to cache + any changes to the data until the user explicitly requests to + submit them. For that reason we need to declare a \c submit() slot + in additon to the model and the editor's buttons. + + \table 100% + \header \o Connecting to a Database + \row + \o + + Before we can use the \c TableEditor class, we must create a + connection to the database containing the table we want to edit: + + \snippet examples/sql/cachedtable/main.cpp 0 + + The \c createConnection() function is a helper function provided + for convenience. It is defined in the \c connection.h file which + is located in the \c sql example directory (all the examples in + the \c sql directory use this function to connect to a database). + + \snippet examples/sql/connection.h 0 + + The \c createConnection function opens a connection to an + in-memory SQLITE database and creates a test table. If you want + to use another database, simply modify this function's code. + \endtable + + \section1 TableEditor Class Implementation + + The class implementation consists of only two functions, the + constructor and the \c submit() slot. In the constructor we create + and customize the data model and the various window elements: + + \snippet examples/sql/cachedtable/tableeditor.cpp 0 + + First we create the data model and set the SQL database table we + want the model to operate on. Note that the + QSqlTableModel::setTable() function does not select data from the + table; it only fetches its field information. For that reason we + call the QSqlTableModel::select() function later on, populating + the model with data from the table. The selection can be + customized by specifying filters and sort conditions (see the + QSqlTableModel class documentation for more details). + + We also set the model's edit strategy. The edit strategy dictates + when the changes done by the user in the view, are actually + applied to the database. Since we want to cache the changes in the + table view (i.e. in the model) until the user explicitly submits + them, we choose the QSqlTableModel::OnManualSubmit strategy. The + alternatives are QSqlTableModel::OnFieldChange and + QSqlTableModel::OnRowChange. + + Finally, we set up the labels displayed in the view header using + the \l {QSqlQueryModel::setHeaderData()}{setHeaderData()} function + that the model inherits from the QSqlQueryModel class. + + \snippet examples/sql/cachedtable/tableeditor.cpp 1 + + Then we create a table view. The QTableView class provides a + default model/view implementation of a table view, i.e. it + implements a table view that displays items from a model. It also + allows the user to edit the items, storing the changes in the + model. To create a read only view, set the proper flag using the + \l {QAbstractItemView::editTriggers}{editTriggers} property the + view inherits from the QAbstractItemView class. + + To make the view present our data, we pass our model to the view + using the \l {QAbstractItemView::setModel()}{setModel()} function. + + \snippet examples/sql/cachedtable/tableeditor.cpp 2 + + The \c {TableEditor}'s buttons are regular QPushButton objects. We + add them to a button box to ensure that the buttons are presented + in a layout that is appropriate to the current widget style. The + rationale for this is that dialogs and message boxes typically + present buttons in a layout that conforms to the interface + guidelines for that platform. Invariably, different platforms have + different layouts for their dialogs. QDialogButtonBox allows a + developer to add buttons to it and will automatically use the + appropriate layout for the user's desktop environment. + + Most buttons for a dialog follow certain roles. When adding a + button to a button box using the \l + {QDialogButtonBox}{addButton()} function, the button's role must + be specified using the QDialogButtonBox::ButtonRole + enum. Alternatively, QDialogButtonBox provides several standard + buttons (e.g. \gui OK, \gui Cancel, \gui Save) that you can + use. They exist as flags so you can OR them together in the + constructor. + + \snippet examples/sql/cachedtable/tableeditor.cpp 3 + + We connect the \gui Quit button to the table editor's \l + {QWidget::close()}{close()} slot, and the \gui Submit button to + our private \c submit() slot. The latter slot will take care of + the data transactions. Finally, we connect the \gui Revert button + to our model's \l {QSqlTableModel::revertAll()}{revertAll()} slot, + reverting all pending changes (i.e., restoring the original data). + + \snippet examples/sql/cachedtable/tableeditor.cpp 4 + + In the end we add the button box and the table view to a layout, + install the layout on the table editor widget, and set the + editor's window title. + + \snippet examples/sql/cachedtable/tableeditor.cpp 5 + + The \c submit() slot is called whenever the users hit the \gui + Submit button to save their changes. + + First, we begin a transaction on the database using the + QSqlDatabase::transaction() function. A database transaction is a + unit of interaction with a database management system or similar + system that is treated in a coherent and reliable way independent + of other transactions. A pointer to the used database can be + obtained using the QSqlTableModel::database() function. + + Then, we try to submit all the pending changes, i.e. the model's + modified items. If no error occurs, we commit the transaction to + the database using the QSqlDatabase::commit() function (note that + on some databases, this function will not work if there is an + active QSqlQuery on the database). Otherwise we perform a rollback + of the transaction using the QSqlDatabase::rollback() function and + post a warning to the user. + + \table 100% + \row + \o + \bold {See also:} + + A complete list of Qt's SQL \l {Database Classes}, and the \l + {Model/View Programming} documentation. + + \endtable +*/ diff --git a/doc/src/examples/calculator.qdoc b/doc/src/examples/calculator.qdoc new file mode 100644 index 0000000..2cae6ce --- /dev/null +++ b/doc/src/examples/calculator.qdoc @@ -0,0 +1,389 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/calculator + \title Calculator Example + + The example shows how to use signals and slots to implement the + functionality of a calculator widget, and how to use QGridLayout + to place child widgets in a grid. + + \image calculator-example.png Screenshot of the Calculator example + + The example consists of two classes: + + \list + \o \c Calculator is the calculator widget, with all the + calculator functionality. + \o \c Button is the widget used for each of the calculator + button. It derives from QToolButton. + \endlist + + We will start by reviewing \c Calculator, then we will take a + look at \c Button. + + \section1 Calculator Class Definition + + \snippet examples/widgets/calculator/calculator.h 0 + + The \c Calculator class provides a simple calculator widget. It + inherits from QDialog and has several private slots associated + with the calculator's buttons. QObject::eventFilter() is + reimplemented to handle mouse events on the calculator's display. + + Buttons are grouped in categories according to their behavior. + For example, all the digit buttons (labeled \gui 0 to \gui 9) + append a digit to the current operand. For these, we connect + multiple buttons to the same slot (e.g., \c digitClicked()). The + categories are digits, unary operators (\gui{Sqrt}, \gui{x\unicode{178}}, + \gui{1/x}), additive operators (\gui{+}, \gui{-}), and + multiplicative operators (\gui{\unicode{215}}, \gui{\unicode{247}}). The other buttons + have their own slots. + + \snippet examples/widgets/calculator/calculator.h 1 + \snippet examples/widgets/calculator/calculator.h 2 + + The private \c createButton() function is used as part of the + widget construction. \c abortOperation() is called whenever a + division by zero occurs or when a square root operation is + applied to a negative number. \c calculate() applies a binary + operator (\gui{+}, \gui{-}, \gui{\unicode{215}}, or \gui{\unicode{247}}). + + \snippet examples/widgets/calculator/calculator.h 3 + \snippet examples/widgets/calculator/calculator.h 4 + \snippet examples/widgets/calculator/calculator.h 5 + \snippet examples/widgets/calculator/calculator.h 6 + \snippet examples/widgets/calculator/calculator.h 7 + \snippet examples/widgets/calculator/calculator.h 8 + + These variables, together with the contents of the calculator + display (a QLineEdit), encode the state of the calculator: + + \list + \o \c sumInMemory contains the value stored in the calculator's memory + (using \gui{MS}, \gui{M+}, or \gui{MC}). + \o \c sumSoFar stores the value accumulated so far. When the user + clicks \gui{=}, \c sumSoFar is recomputed and shown on the + display. \gui{Clear All} resets \c sumSoFar to zero. + \o \c factorSoFar stores a temporary value when doing + multiplications and divisions. + \o \c pendingAdditiveOperator stores the last additive operator + clicked by the user. + \o \c pendingMultiplicativeOperator stores the last multiplicative operator + clicked by the user. + \o \c waitingForOperand is \c true when the calculator is + expecting the user to start typing an operand. + \endlist + + Additive and multiplicative operators are treated differently + because they have different precedences. For example, \gui{1 + 2 \unicode{247} + 3} is interpreted as \gui{1 + (2 \unicode{247} 3)} because \gui{\unicode{247}} has higher + precedence than \gui{+}. + + The table below shows the evolution of the calculator state as + the user enters a mathematical expression. + + \table + \header \o User Input \o Display \o Sum so Far \o Add. Op. \o Factor so Far \o Mult. Op. \o Waiting for Operand? + \row \o \o 0 \o 0 \o \o \o \o \c true + \row \o \gui{1} \o 1 \o 0 \o \o \o \o \c false + \row \o \gui{1 +} \o 1 \o 1 \o \gui{+} \o \o \o \c true + \row \o \gui{1 + 2} \o 2 \o 1 \o \gui{+} \o \o \o \c false + \row \o \gui{1 + 2 \unicode{247}} \o 2 \o 1 \o \gui{+} \o 2 \o \gui{\unicode{247}} \o \c true + \row \o \gui{1 + 2 \unicode{247} 3} \o 3 \o 1 \o \gui{+} \o 2 \o \gui{\unicode{247}} \o \c false + \row \o \gui{1 + 2 \unicode{247} 3 -} \o 1.66667 \o 1.66667 \o \gui{-} \o \o \o \c true + \row \o \gui{1 + 2 \unicode{247} 3 - 4} \o 4 \o 1.66667 \o \gui{-} \o \o \o \c false + \row \o \gui{1 + 2 \unicode{247} 3 - 4 =} \o -2.33333 \o 0 \o \o \o \o \c true + \endtable + + Unary operators, such as \gui Sqrt, require no special handling; + they can be applied immediately since the operand is already + known when the operator button is clicked. + + \snippet examples/widgets/calculator/calculator.h 9 + \codeline + \snippet examples/widgets/calculator/calculator.h 10 + + Finally, we declare the variables associated with the display and the + buttons used to display numerals. + + \section1 Calculator Class Implementation + + \snippet examples/widgets/calculator/calculator.cpp 0 + + In the constructor, we initialize the calculator's state. The \c + pendingAdditiveOperator and \c pendingMultiplicativeOperator + variables don't need to be initialized explicitly, because the + QString constructor initializes them to empty strings. + + \snippet examples/widgets/calculator/calculator.cpp 1 + \snippet examples/widgets/calculator/calculator.cpp 2 + + We create the QLineEdit representing the calculator's display and + set up some of its properties. In particular, we set it to be + read-only. + + We also enlarge \c{display}'s font by 8 points. + + \snippet examples/widgets/calculator/calculator.cpp 4 + + For each button, we call the private \c createButton() function with + the proper text label and a slot to connect to the button. + + \snippet examples/widgets/calculator/calculator.cpp 5 + \snippet examples/widgets/calculator/calculator.cpp 6 + + The layout is handled by a single QGridLayout. The + QLayout::setSizeConstraint() call ensures that the \c Calculator + widget is always shown as its optimal size (its + \l{QWidget::sizeHint()}{size hint}), preventing the user from + resizing the calculator. The size hint is determined by the size + and \l{QWidget::sizePolicy()}{size policy} of the child widgets. + + Most child widgets occupy only one cell in the grid layout. For + these, we only need to pass a row and a column to + QGridLayout::addWidget(). The \c display, \c backspaceButton, \c + clearButton, and \c clearAllButton widgets occupy more than one + column; for these we must also pass a row span and a column + span. + + \snippet examples/widgets/calculator/calculator.cpp 7 + + Pressing one of the calculator's digit buttons will emit the + button's \l{QToolButton::clicked()}{clicked()} signal, which will + trigger the \c digitClicked() slot. + + First, we find out which button sent the signal using + QObject::sender(). This function returns the sender as a QObject + pointer. Since we know that the sender is a \c Button object, we + can safely cast the QObject. We could have used a C-style cast or + a C++ \c static_cast<>(), but as a defensive programming + technique we use a \l qobject_cast(). The advantage is that if + the object has the wrong type, a null pointer is returned. + Crashes due to null pointers are much easier to diagnose than + crashes due to unsafe casts. Once we have the button, we extract + the operator using QToolButton::text(). + + The slot needs to consider two situations in particular. If \c + display contains "0" and the user clicks the \gui{0} button, it + would be silly to show "00". And if the calculator is in + a state where it is waiting for a new operand, + the new digit is the first digit of that new operand; in that case, + any result of a previous calculation must be cleared first. + + At the end, we append the new digit to the value in the display. + + \snippet examples/widgets/calculator/calculator.cpp 8 + \snippet examples/widgets/calculator/calculator.cpp 9 + + The \c unaryOperatorClicked() slot is called whenever one of the + unary operator buttons is clicked. Again a pointer to the clicked + button is retrieved using QObject::sender(). The operator is + extracted from the button's text and stored in \c + clickedOperator. The operand is obtained from \c display. + + Then we perform the operation. If \gui Sqrt is applied to a + negative number or \gui{1/x} to zero, we call \c + abortOperation(). If everything goes well, we display the result + of the operation in the line edit and we set \c waitingForOperand + to \c true. This ensures that if the user types a new digit, the + digit will be considered as a new operand, instead of being + appended to the current value. + + \snippet examples/widgets/calculator/calculator.cpp 10 + \snippet examples/widgets/calculator/calculator.cpp 11 + + The \c additiveOperatorClicked() slot is called when the user + clicks the \gui{+} or \gui{-} button. + + Before we can actually do something about the clicked operator, + we must handle any pending operations. We start with the + multiplicative operators, since these have higher precedence than + additive operators: + + \snippet examples/widgets/calculator/calculator.cpp 12 + \snippet examples/widgets/calculator/calculator.cpp 13 + + If \gui{\unicode{215}} or \gui{\unicode{247}} has been clicked earlier, without clicking + \gui{=} afterward, the current value in the display is the right + operand of the \gui{\unicode{215}} or \gui{\unicode{247}} operator and we can finally + perform the operation and update the display. + + \snippet examples/widgets/calculator/calculator.cpp 14 + \snippet examples/widgets/calculator/calculator.cpp 15 + + If \gui{+} or \gui{-} has been clicked earlier, \c sumSoFar is + the left operand and the current value in the display is the + right operand of the operator. If there is no pending additive + operator, \c sumSoFar is simply set to be the text in the + display. + + \snippet examples/widgets/calculator/calculator.cpp 16 + \snippet examples/widgets/calculator/calculator.cpp 17 + + Finally, we can take care of the operator that was just clicked. + Since we don't have the right-hand operand yet, we store the clicked + operator in the \c pendingAdditiveOperator variable. We will + apply the operation later, when we have a right operand, with \c + sumSoFar as the left operand. + + \snippet examples/widgets/calculator/calculator.cpp 18 + + The \c multiplicativeOperatorClicked() slot is similar to \c + additiveOperatorClicked(). We don't need to worry about pending + additive operators here, because multiplicative operators have + precedence over additive operators. + + \snippet examples/widgets/calculator/calculator.cpp 20 + + Like in \c additiveOperatorClicked(), we start by handing any + pending multiplicative and additive operators. Then we display \c + sumSoFar and reset the variable to zero. Resetting the variable + to zero is necessary to avoid counting the value twice. + + \snippet examples/widgets/calculator/calculator.cpp 22 + + The \c pointClicked() slot adds a decimal point to the content in + \c display. + + \snippet examples/widgets/calculator/calculator.cpp 24 + + The \c changeSignClicked() slot changes the sign of the value in + \c display. If the current value is positive, we prepend a minus + sign; if the current value is negative, we remove the first + character from the value (the minus sign). + + \snippet examples/widgets/calculator/calculator.cpp 26 + + The \c backspaceClicked() removes the rightmost character in the + display. If we get an empty string, we show "0" and set \c + waitingForOperand to \c true. + + \snippet examples/widgets/calculator/calculator.cpp 28 + + The \c clear() slot resets the current operand to zero. It is + equivalent to clicking \gui Backspace enough times to erase the + entire operand. + + \snippet examples/widgets/calculator/calculator.cpp 30 + + The \c clearAll() slot resets the calculator to its initial state. + + \snippet examples/widgets/calculator/calculator.cpp 32 + + The \c clearMemory() slot erases the sum kept in memory, \c + readMemory() displays the sum as an operand, \c setMemory() + replace the sum in memory with the current sum, and \c + addToMemory() adds the current value to the value in memory. For + \c setMemory() and \c addToMemory(), we start by calling \c + equalClicked() to update \c sumSoFar and the value in the + display. + + \snippet examples/widgets/calculator/calculator.cpp 34 + + The private \c createButton() function is called from the + constructor to create calculator buttons. + + \snippet examples/widgets/calculator/calculator.cpp 36 + + The private \c abortOperation() function is called whenever a + calculation fails. It resets the calculator state and displays + "####". + + \snippet examples/widgets/calculator/calculator.cpp 38 + + The private \c calculate() function performs a binary operation. + The right operand is given by \c rightOperand. For additive + operators, the left operand is \c sumSoFar; for multiplicative + operators, the left operand is \c factorSoFar. The function + return \c false if a division by zero occurs. + + \section1 Button Class Definition + + Let's now take a look at the \c Button class: + + \snippet examples/widgets/calculator/button.h 0 + + The \c Button class has a convenience constructor that takes a + text label and a parent widget, and it reimplements QWidget::sizeHint() + to provide more space around the text than the amount QToolButton + normally provides. + + \section1 Button Class Implementation + + \snippet examples/widgets/calculator/button.cpp 0 + + The buttons' appearance is determined by the layout of the + calculator widget through the size and + \l{QWidget::sizePolicy}{size policy} of the layout's child + widgets. The call to the + \l{QWidget::setSizePolicy()}{setSizePolicy()} function in the + constructor ensures that the button will expand horizontally to + fill all the available space; by default, \l{QToolButton}s don't + expand to fill available space. Without this call, the different + buttons in a same column would have different widths. + + \snippet examples/widgets/calculator/button.cpp 1 + \snippet examples/widgets/calculator/button.cpp 2 + + In \l{QWidget::sizeHint()}{sizeHint()}, we try to return a size + that looks good for most buttons. We reuse the size hint of the + base class (QToolButton) but modify it in the following ways: + + \list + \o We add 20 to the \l{QSize::height()}{height} component of the size hint. + \o We make the \l{QSize::width()}{width} component of the size + hint at least as much as the \l{QSize::width()}{height}. + \endlist + + This ensures that with most fonts, the digit and operator buttons + will be square, without truncating the text on the + \gui{Backspace}, \gui{Clear}, and \gui{Clear All} buttons. + + The screenshot below shows how the \c Calculator widget would + look like if we \e didn't set the horizontal size policy to + QSizePolicy::Expanding in the constructor and if we didn't + reimplement QWidget::sizeHint(). + + \image calculator-ugly.png The Calculator example with default size policies and size hints + +*/ diff --git a/doc/src/examples/calculatorbuilder.qdoc b/doc/src/examples/calculatorbuilder.qdoc new file mode 100644 index 0000000..c63267e --- /dev/null +++ b/doc/src/examples/calculatorbuilder.qdoc @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example designer/calculatorbuilder + \title Calculator Builder Example + + The Calculator Builder example shows how to create a user interface from + a \QD form at run-time, using the QUiLoader class. + + \image calculatorbuilder-example.png + + We use the form created in the \l{designer/calculatorform}{Calculator Form} + example to show that the same user interface can be generated when the + application is executed or defined when the application is built. + + \section1 Preparation + + The \l{designer/calculatorform}{Calculator Form} example defines a user + interface that we can use without modification. In this example, we use a + \l{The Qt Resource System}{resource file} to contain the \c{calculatorform.ui} + file created in the previous example, but it could be stored on disk instead. + + To generate a form at run time, we need to link the example against the + \c QtUiTools module library. The project file we use contains all the + necessary information to do this: + + \snippet examples/designer/calculatorbuilder/calculatorbuilder.pro 0 + + All the other necessary files are declared as usual. + + \section1 CalculatorForm Class Definition + + The \c CalculatorForm class defines the widget used to host the form's + user interface: + + \snippet examples/designer/calculatorbuilder/calculatorform.h 0 + + Note that we do not need to include a header file to describe the user + interface. We only define two public slots, using the auto-connection + naming convention required by \c uic, and declare private variables + that we will use to access widgets provided by the form after they are + constructed. + + \section1 CalculatorForm Class Implementation + + We will need to use the QUiLoader class that is provided by the + \c libQtUiTools library, so we first ensure that we include the header + file for the module: + + \snippet examples/designer/calculatorbuilder/calculatorform.cpp 0 + + The constructor uses a form loader object to construct the user + interface that we retrieve, via a QFile object, from the example's + resources: + + \snippet examples/designer/calculatorbuilder/calculatorform.cpp 1 + + By including the user interface in the example's resources, we ensure + that it will be present when the example is run. The \c{loader.load()} + function takes the user interface description contained in the file + and constructs the form widget as a child widget of the \c{CalculatorForm}. + + We are interested in three widgets in the generated user interface: + two spin boxes and a label. For convenience, we retrieve pointers to + these widgets from the widget that was constructed by the \c FormBuilder, + and we record them for later use. The \c qFindChild() template function + allows us to query widgets in order to find named child widgets. + + \snippet examples/designer/calculatorbuilder/calculatorform.cpp 2 + + The widgets created by the form loader need to be connected to the + specially-named slots in the \c CalculatorForm object. We use Qt's + meta-object system to enable these connections: + + \snippet examples/designer/calculatorbuilder/calculatorform.cpp 3 + + The form widget is added to a layout, and the window title is set: + + \snippet examples/designer/calculatorbuilder/calculatorform.cpp 4 + + The two slots that modify widgets provided by the form are defined + in a similar way to those in the \l{designer/calculatorform}{Calculator + Form} example, except that we read the values from the spin boxes and + write the result to the output widget via the pointers we recorded in + the constructor: + + \snippet examples/designer/calculatorbuilder/calculatorform.cpp 5 + \codeline + \snippet examples/designer/calculatorbuilder/calculatorform.cpp 7 + + The advantage of this approach is that we can replace the form when the + application is run, but we can still manipulate the widgets it contains + as long as they are given appropriate names. +*/ diff --git a/doc/src/examples/calculatorform.qdoc b/doc/src/examples/calculatorform.qdoc new file mode 100644 index 0000000..a8e891e --- /dev/null +++ b/doc/src/examples/calculatorform.qdoc @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example designer/calculatorform + \title Calculator Form Example + + The Calculator Form Example shows how to use a form created with + \QD in an application by using the user interface information from + a QWidget subclass. We use \l{Using a Designer .ui File in Your Application} + {uic's auto-connection} feature to automatically connect signals + from widgets on the form to slots in our code. + + \image calculatorform-example.png Screenshot of the Calculator Form example + + The example presents two spin boxes that are used to input integer values + and a label that shows their sum. Whenever either of the spin boxes are + updated, the signal-slot connections between the widgets and the form + ensure that the label is also updated. + + \section1 Preparation + + The user interface for this example is designed completely using \QD. The + result is a .ui file describing the form, the widgets used, any signal-slot + connections between them, and other standard user interface properties. + + To ensure that the example can use this file, we need to include a \c FORMS + declaration in the example's project file: + + \snippet examples/designer/calculatorform/calculatorform.pro 1 + + When the project is built, \c uic will create a header file that lets us + construct the form. + + \section1 CalculatorForm Class Definition + + The \c CalculatorForm class uses the user interface described in the + \c calculatorform.ui file. To access the form and its contents, we need + to include the \c ui_calculatorform.h header file created by \c uic + during the build process: + + \snippet examples/designer/calculatorform/calculatorform.h 0 + + We define the \c CalculatorForm class by subclassing QWidget because the + form itself is based on QWidget: + + \snippet examples/designer/calculatorform/calculatorform.h 1 + + Apart from the constructor, the class contains two private slots that + are named according to the auto-connection naming convention required + by \c uic. + The private \c ui member variable refers to the form, and is used to + access the contents of the user interface. + + \section1 CalculatorForm Class Implementation + + The constructor simply calls the base class's constructor and + sets up the form's user interface. + + \snippet examples/designer/calculatorform/calculatorform.cpp 0 + + The user interface is set up with the \c setupUI() function. We pass + \c this as the argument to this function to use the \c CalculatorForm + widget itself as the container for the user interface. + + To automatically connect signals from the spin boxes defined in the + user interface, we use the naming convention that indicates which + widgets and their signals in the user interface should be connected + to each slot. The first slot is called whenever the spin box called + "inputSpinBox1" in the user interface emits the + \l{QSpinBox::valueChanged()}{valueChanged()} signal: + + \snippet examples/designer/calculatorform/calculatorform.cpp 1 + + When this occurs, we use the value supplied by the signal to update the + output label by setting its new text directly. We access the output label + and the other spin box via the class's private \c ui variable. + + The second slot is called whenever the second spin box, called + "inputSpinBox2", emits the \l{QSpinBox::valueChanged()}{valueChanged()} + signal: + + \snippet examples/designer/calculatorform/calculatorform.cpp 2 + + In this case, the value from the first spin box is read and combined + with the value supplied by the signal. Again, the output label is + updated directly via the \c ui variable. +*/ diff --git a/doc/src/examples/calendar.qdoc b/doc/src/examples/calendar.qdoc new file mode 100644 index 0000000..e6beef4 --- /dev/null +++ b/doc/src/examples/calendar.qdoc @@ -0,0 +1,237 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example richtext/calendar + \title Calendar Example + + The Calendar example shows how to create rich text content and display it using + a rich text editor. + + \image calendar-example.png + + Specifically, the example demonstrates the following: + + \list + \o Use of a text editor with a text document + \o Insertion of tables and frames into a document + \o Navigation within a table + \o Insert text in different styles + \endlist + + The rich text editor used to display the document is used within a main window + application. + + \section1 MainWindow Class Definition + + The \c MainWindow class provides a text editor widget and some controls to + allow the user to change the month and year shown. The font size used for the + text can also be adjusted. + + \snippet examples/richtext/calendar/mainwindow.h 0 + + The private \c insertCalendar() function performs most of the work, relying on + the \c fontSize and \c selectedDate variables to write useful information to + the \c editor. + + \section1 MainWindow Class Implementation + + The \c MainWindow constructor sets up the user interface and initializes + variables used to generate a calendar for each month. + + \snippet examples/richtext/calendar/mainwindow.cpp 0 + + We begin by setting default values for the selected date that will be highlighted + in the calendar and the font size to be used. Since we are using a QMainWindow + for the user interface, we construct a widget for use as the central widget. + + The user interface will include a line of controls above the generated calendar; + we construct a label and a combobox to allow the month to be selected, and a + spin box for the year. These widgets are configured to provide a reasonable range + of values for the user to try: + + \snippet examples/richtext/calendar/mainwindow.cpp 1 + + We use the \c selectedDate object to obtain the current month and year, and we + set these in the combobox and spin box: + + The font size is displayed in a spin box which we restrict to a sensible range + of values: + + \snippet examples/richtext/calendar/mainwindow.cpp 2 + + We construct an editor and use the \c insertCalendar() function to create + a calendar for it. Each calendar is displayed in the same text editor; in + this example we use a QTextBrowser since we do not allow the calendar to be + edited. + + The controls used to set the month, year, and font size will not have any + effect on the appearance of the calendar unless we make some signal-slot + connections: + + \snippet examples/richtext/calendar/mainwindow.cpp 3 + + The signals are connected to some simple slots in the \c MainWindow class + which we will describe later. + + We create layouts to manage the widgets we constructed: + + \snippet examples/richtext/calendar/mainwindow.cpp 4 + + Finally, the central widget is set for the window. + + Each calendar is created for the editor by the \c insertCalendar() function + which uses the date and font size, defined by the private \a selectedDate + and \c fontSize variables, to produce a suitable plan for the specified + month and year. + + \snippet examples/richtext/calendar/mainwindow.cpp 5 + + We begin by clearing the editor's rich text document, and obtain a text + cursor from the editor that we will use to add content. We also create a + QDate object based on the currently selected date. + + The calendar is made up of a table with a gray background color that contains + seven columns: one for each day of the week. It is placed in the center of the + page with equal space to the left and right of it. All of these properties are + set in a QTextTableFormat object: + + \snippet examples/richtext/calendar/mainwindow.cpp 6 + + Each cell in the table will be padded and spaced to make the text easier to + read. + + We want the columns to have equal widths, so we provide a vector containing + percentage widths for each of them and set the constraints in the + QTextTableFormat: + + \snippet examples/richtext/calendar/mainwindow.cpp 7 + + The constraints used for the column widths are only useful if the table has + an appropriate number of columns. With the format for the table defined, we + construct a new table with one row and seven columns at the current cursor + position: + + \snippet examples/richtext/calendar/mainwindow.cpp 8 + + We only need one row to start with; more can be added as we need them. Using + this approach means that we do not need to perform any date calculations + until we add cells to the table. + + When inserting objects into a document with the cursor's insertion functions, + the cursor is automatically moved inside the newly inserted object. This means + that we can immediately start modifying the table from within: + + \snippet examples/richtext/calendar/mainwindow.cpp 9 + + Since the table has an outer frame, we obtain the frame and its format so that + we can customize it. After making the changes we want, we set the frame's format + using the modified format object. We have given the table an outer border one + pixel wide. + + \snippet examples/richtext/calendar/mainwindow.cpp 10 + + In a similar way, we obtain the cursor's current character format and + create customized formats based on it. + + We do not set the format on the cursor because this would change the default + character format; instead, we use the customized formats explicitly when we + insert text. The following loop inserts the days of the week into the table + as bold text: + + \snippet examples/richtext/calendar/mainwindow.cpp 11 + + For each day of the week, we obtain an existing table cell in the first row + (row 0) using the table's \l{QTextTable::cellAt()}{cellAt()} function. Since + we start counting the days of the week at day 1 (Monday), we subtract 1 from + \c weekDay to ensure that we obtain the cell for the correct column of the + table. + + Before text can be inserted into a cell, we must obtain a cursor with the + correct position in the document. The cell provides a function for this + purpose, and we use this cursor to insert text using the \c boldFormat + character format that we created earlier: + + \snippet examples/richtext/calendar/mainwindow.cpp 12 + + Inserting text into document objects usually follows the same pattern. + Each object can provide a new cursor that corresponds to the first valid + position within itself, and this can be used to insert new content. We + continue to use this pattern as we insert the days of the month into the + table. + + Since every month has more than seven days, we insert a single row to begin + and add days until we reach the end of the month. If the current date is + encountered, it is inserted with a special format (created earlier) that + makes it stand out: + + \snippet examples/richtext/calendar/mainwindow.cpp 13 + + We add a new row to the table at the end of each week only if the next week + falls within the currently selected month. + + For each calendar that we create, we change the window title to reflect the + currently selected month and year: + + \snippet examples/richtext/calendar/mainwindow.cpp 14 + + The \c insertCalendar() function relies on up-to-date values for the month, + year, and font size. These are set in the following slots: + + \snippet examples/richtext/calendar/mainwindow.cpp 15 + + The \c setFontSize() function simply changes the private \c fontSize variable + before updating the calendar. + + \snippet examples/richtext/calendar/mainwindow.cpp 16 + + The \c setMonth slot is called when the QComboBox used to select the month is + updated. The value supplied is the currently selected row in the combobox. + We add 1 to this value to obtain a valid month number, and create a new QDate + based on the existing one. The calendar is then updated to use this new date. + + \snippet examples/richtext/calendar/mainwindow.cpp 17 + + The \c setYear() slot is called when the QDateTimeEdit used to select the + year is updated. The value supplied is a QDate object; this makes + the construction of a new value for \c selectedDate simple. We update the + calendar afterwards to use this new date. +*/ diff --git a/doc/src/examples/calendarwidget.qdoc b/doc/src/examples/calendarwidget.qdoc new file mode 100644 index 0000000..f4417c2 --- /dev/null +++ b/doc/src/examples/calendarwidget.qdoc @@ -0,0 +1,305 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \title Calendar Widget Example + \example widgets/calendarwidget + + The Calendar Widget example shows use of \c QCalendarWidget. + + \image calendarwidgetexample.png + + QCalendarWidget displays one calendar month + at a time and lets the user select a date. + The calendar consists of four components: a navigation + bar that lets the user change the month that is + displayed, a grid where each cell represents one day + in the month, and two headers that display weekday names + and week numbers. + + The Calendar Widget example displays a QCalendarWidget and lets the user + configure its appearance and behavior using + \l{QComboBox}es, \l{QCheckBox}es, and \l{QDateEdit}s. In + addition, the user can influence the formatting of individual dates + and headers. + + The properties of the QCalendarWidget are summarized in the table + below. + + \table + \header \o Property + \o Description + \row \o \l{QCalendarWidget::}{selectedDate} + \o The currently selected date. + \row \o \l{QCalendarWidget::}{minimumDate} + \o The earliest date that can be selected. + \row \o \l{QCalendarWidget::}{maximumDate} + \o The latest date that can be selected. + \row \o \l{QCalendarWidget::}{firstDayOfWeek} + \o The day that is displayed as the first day of the week + (usually Sunday or Monday). + \row \o \l{QCalendarWidget::}{gridVisible} + \o Whether the grid should be shown. + \row \o \l{QCalendarWidget::}{selectionMode} + \o Whether the user can select a date or not. + \row \o \l{QCalendarWidget::}{horizontalHeaderFormat} + \o The format of the day names in the horizontal header + (e.g., "M", "Mon", or "Monday"). + \row \o \l{QCalendarWidget::}{verticalHeaderFormat} + \o The format of the vertical header. + \row \o \l{QCalendarWidget::}{navigationBarVisible} + \o Whether the navigation bar at the top of the calendar + widget is shown. + \endtable + + The example consists of one class, \c Window, which creates and + lays out the QCalendarWidget and the other widgets that let the + user configure the QCalendarWidget. + + \section1 Window Class Definition + + Here is the definition of the \c Window class: + + \snippet examples/widgets/calendarwidget/window.h 0 + \dots + \snippet examples/widgets/calendarwidget/window.h 1 + + As is often the case with classes that represent self-contained + windows, most of the API is private. We will review the private + members as we stumble upon them in the implementation. + + \section1 Window Class Implementation + + Let's now review the class implementation, starting with the constructor: + + \snippet examples/widgets/calendarwidget/window.cpp 0 + + We start by creating the four \l{QGroupBox}es and their child + widgets (including the QCalendarWidget) using four private \c + create...GroupBox() functions, described below. Then we arrange + the group boxes in a QGridLayout. + + We set the grid layout's resize policy to QLayout::SetFixedSize to + prevent the user from resizing the window. In that mode, the + window's size is set automatically by QGridLayout based on the + size hints of its contents widgets. + + To ensure that the window isn't automatically resized every time + we change a property of the QCalendarWidget (e.g., hiding the + navigation bar, trhe vertical header, or the grid), we set the + minimum height of row 0 and the minimum width of column 0 to the + initial size of the QCalendarWidget. + + Let's move on to the \c createPreviewGroupBox() function: + + \snippet examples/widgets/calendarwidget/window.cpp 9 + + The \gui Preview group box contains only one widget: the + QCalendarWidget. We set it up, connect its + \l{QCalendarWidget::}{currentPageChanged()} signal to our \c + reformatCalendarPage() slot to make sure that every new page gets + the formatting specified by the user. + + The \c createGeneralOptionsGroupBox() function is somewhat large + and several widgets are set up the same way; we look at parts of + its implementation here and skip the rest: + + \snippet examples/widgets/calendarwidget/window.cpp 10 + \dots + + We start with the setup of the \gui{Week starts on} combobox. + This combobox controls which day should be displayed as the first + day of the week. + + The QComboBox class lets us attach user data as a QVariant to + each item. The data can later be retrieved with QComboBox's + \l{QComboBox::}{itemData()} function. QVariant doesn't directly + support the Qt::DayOfWeek data type, but it supports \c int, and + C++ will happily convert any enum value to \c int. + + \dots + \snippet examples/widgets/calendarwidget/window.cpp 11 + \dots + + After creating the widgets, we connect the signals and slots. We + connect the comboboxes to private slots of \c Window or to + public slots provided by QComboBox. + + \dots + \snippet examples/widgets/calendarwidget/window.cpp 12 + + At the end of the function, we call the slots that update the calendar to ensure + that the QCalendarWidget is synchronized with the other widgets on startup. + + Let's now take a look at the \c createDatesGroupBox() private function: + + \snippet examples/widgets/calendarwidget/window.cpp 13 + + In this function, we create the \gui {Minimum Date}, \gui {Maximum Date}, + and \gui {Current Date} editor widgets, + which control the calendar's minimum, maximum, and selected dates. + The calendar's minimum and maximum dates have already been + set in \c createPrivewGroupBox(); we can then set the widgets + default values to the calendars values. + + \snippet examples/widgets/calendarwidget/window.cpp 14 + \dots + \snippet examples/widgets/calendarwidget/window.cpp 15 + + We connect the \c currentDateEdit's + \l{QDateEdit::}{dateChanged()} signal directly to the calendar's + \l{QCalendarWidget::}{setSelectedDate()} slot. When the calendar's + selected date changes, either as a result of a user action or + programmatically, our \c selectedDateChanged() slot updates + the \gui {Current Date} editor. We also need to react when the user + changes the \gui{Minimum Date} and \gui{Maximum Date} editors. + + Here is the \c createTextFormatsGroup() function: + + \snippet examples/widgets/calendarwidget/window.cpp 16 + + We set up the \gui {Weekday Color} and \gui {Weekend Color} comboboxes + using \c createColorCombo(), which instantiates a QComboBox and + populates it with colors ("Red", "Blue", etc.). + + \snippet examples/widgets/calendarwidget/window.cpp 17 + + The \gui {Header Text Format} combobox lets the user change the + text format (bold, italic, or plain) used for horizontal and + vertical headers. The \gui {First Friday in blue} and \gui {May 1 + in red} check box affect the rendering of specific dates. + + \snippet examples/widgets/calendarwidget/window.cpp 18 + + We connect the check boxes and comboboxes to various private + slots. The \gui {First Friday in blue} and \gui {May 1 in red} + check boxes are both connected to \c reformatCalendarPage(), + which is also called when the calendar switches month. + + \dots + \snippet examples/widgets/calendarwidget/window.cpp 19 + + At the end of \c createTextFormatsGroupBox(), we call private + slots to synchronize the QCalendarWidget with the other widgets. + + We're now done reviewing the four \c create...GroupBox() + functions. Let's now take a look at the other private functions + and slots. + + \snippet examples/widgets/calendarwidget/window.cpp 20 + + In \c createColorCombo(), we create a combobox and populate it with + standard colors. The second argument to QComboBox::addItem() + is a QVariant storing user data (in this case, QColor objects). + + This function was used to set up the \gui {Weekday Color} + and \gui {Weekend Color} comboboxes. + + \snippet examples/widgets/calendarwidget/window.cpp 1 + + When the user changes the \gui {Week starts on} combobox's + value, \c firstDayChanged() is invoked with the index of the + combobox's new value. We retrieve the custom data item + associated with the new current item using + \l{QComboBox::}{itemData()} and cast it to a Qt::DayOfWeek. + + \c selectionModeChanged(), \c horizontalHeaderChanged(), and \c + verticalHeaderChanged() are very similar to \c firstDayChanged(), + so they are omitted. + + \snippet examples/widgets/calendarwidget/window.cpp 2 + + The \c selectedDateChanged() updates the \gui{Current Date} + editor to reflect the current state of the QCalendarWidget. + + \snippet examples/widgets/calendarwidget/window.cpp 3 + + When the user changes the minimum date, we tell the + QCalenderWidget. We also update the \gui {Maximum Date} editor, + because if the new minimum date is later than the current maximum + date, QCalendarWidget will automatically adapt its maximum date + to avoid a contradicting state. + + \snippet examples/widgets/calendarwidget/window.cpp 4 + + \c maximumDateChanged() is implemented similarly to \c + minimumDateChanged(). + + \snippet examples/widgets/calendarwidget/window.cpp 5 + + Each combobox item has a QColor object as user data corresponding to the + item's text. After fetching the colors from the comboboxes, we + set the text format of each day of the week. + + The text format of a column in the calendar is given as a + QTextCharFormat, which besides the foreground color lets us + specify various character formatting information. In this + example, we only show a subset of the possibilities. + + \snippet examples/widgets/calendarwidget/window.cpp 6 + + \c weekendFormatChanged() is the same as \c + weekdayFormatChanged(), except that it affects Saturday and + Sunday instead of Monday to Friday. + + \snippet examples/widgets/calendarwidget/window.cpp 7 + + The \c reformatHeaders() slot is called when the user + changes the text format of + the headers. We compare the current text of the \gui {Header Text Format} + combobox to determine which format to apply. (An alternative would + have been to store \l{QTextCharFormat} values alongside the combobox + items.) + + \snippet examples/widgets/calendarwidget/window.cpp 8 + + In \c reformatCalendarPage(), we set the text format of the first + Friday in the month and May 1 in the current year. The text + formats that are actually used depend on which check boxes are + checked. + + QCalendarWidget lets us set the text format of individual dates + with the \l{QCalendarWidget::}{setDateTextFormat()}. We chose to + set the dates when the calendar page changes, i.e., a new month is + displayed. We check which of the \c mayFirstCheckBox and \c + firstDayCheckBox, if any, are checked + and set the text formats accordingly. +*/ diff --git a/doc/src/examples/capabilitiesexample.qdoc b/doc/src/examples/capabilitiesexample.qdoc new file mode 100644 index 0000000..9d62c71 --- /dev/null +++ b/doc/src/examples/capabilitiesexample.qdoc @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example phonon/capabilities + \title Capabilities Example + + The Backend Capabilities example shows how to check which MIME + types, audio devices, and audio effects are available. + + \image capabilitiesexample.png + + Phonon does not implement the multimedia functionality itself, but + relies on a backend to manage this. The backends do not manage the + hardware directly, but use intermediate technologies: QuickTime on + Mac, GStreamer on Linux, and DirectShow (which requires DirectX) + on Windows. + + The user may add support for new MIME types and effects to these + systems, and the systems abilities may also be different. The + support for multimedia MIME types, and audio effects in Phonon + will therefore vary from system to system. + + Backends informs the programmer about current capabilities through + an implementation of the Phonon::BackendCapabilities namespace. + The backend reports which MIME types can be played back, which + audio effects are available, and which sound devices are available + on the system. When the capabilities of a backend changes, it will + emit the + \l{Phonon::BackendCapabilities::Notifier::}{capabilitiesChanged()} + signal. + + The example consists of one class, \c Window, which displays + capabilities information from the current backend used by Phonon. + + See the \l{Phonon Overview} for a high-level introduction to + Phonon. + + \section1 Window Class Definition + + The \c Window class queries the Phonon backend for its + capabilities. The results are presented in a GUI consisting of + standard Qt widgets. We will now take a tour of the Phonon related + parts of both the definition and implementation of the \c Window + class. + + \snippet examples/phonon/capabilities/window.h windowMembers + + We need the slot to notice changes in the backends capabilities. + + \c mimeListWidget and \c devicesListView lists MIME types and + audio devices. The \c effectsTreeWidget lists audio effects, and + expands to show their parameters. + + The \c setupUi() and \c setupBackendBox() private utility + functions create the widgets and lays them out. We skip these + functions while discussing the implementation because they do not + contain Phonon relevant code. + + \section1 Window Class Implementation + + Our examination starts with a look at the constructor: + + \snippet examples/phonon/capabilities/window.cpp constructor + + After creating the user interface, we call \c updateWidgets(), + which will fill the widgets with the information we get from the + backend. We then connect the slot to the + \l{Phonon::BackendCapabilities::Notifier::}{capabilitiesChanged()} + and + \l{Phonon::BackendCapabilities::Notifier::availableAudioOutputDevicesChanged()}{availableAudioOutputDevicesChanged()} + signals in case the backend's abilities changes while the example + is running. The signal is emitted by a + Phonon::BackendCapabilities::Notifier object, which listens for + changes in the backend. + + In the \c updateWidgets() function, we query the backend for + information it has about its abilities and present it in the GUI + of \c Window. We dissect it here: + + \snippet examples/phonon/capabilities/window.cpp outputDevices + + The + \l{Phonon::BackendCapabilities::Notifier::}{availableAudioOutputDevicesChanged()} + function is a member of the Phonon::BackendCapabilities namespace. + It returns a list of \l{Phonon::}{AudioOutputDevice}s, which gives + us information about a particular device, e.g., a sound card or a + USB headset. + + Note that \l{Phonon::}{AudioOutputDevice} and also + \l{Phonon::}{EffectDescription}, which is described shortly, are + typedefs of \l{Phonon::}{ObjectDescriptionType}. + + \omit + ### + The \l{Phonon::}{ObjectDescriptionModel} is a convenience + model that displays the names of the devices. Their + descriptions are shown as tooltips and disabled devices are + shown in gray. + \endomit + + \snippet examples/phonon/capabilities/window.cpp mimeTypes + + The MIME types supported are given as strings in a QStringList. We + can therefore create a list widget item with the string, and + append it to the \c mimeListWidget, which displays the available + MIME types. + + \snippet examples/phonon/capabilities/window.cpp effects + + As before we add the description and name to our widget, which in + this case is a QTreeWidget. A particular effect may also have + parameters, which are inserted in the tree as child nodes of their + effect. + + \snippet examples/phonon/capabilities/window.cpp effectsParameters + + The parameters are only accessible through an instance of the + \l{Phonon::}{Effect} class. Notice that an effect is created + with the effect description. + + The \l{Phonon::}{EffectParameter} contains information about one + of an effects parameters. We pick out some of the information to + describe the parameter in the tree widget. + + \section1 The main() function + + Because Phonon uses D-Bus on Linux, it is necessary to give the + application a name. You do this with + \l{QCoreApplication::}{setApplicationName()}. + + \snippet examples/phonon/capabilities/main.cpp everything +*/ diff --git a/doc/src/examples/charactermap.qdoc b/doc/src/examples/charactermap.qdoc new file mode 100644 index 0000000..64c00db --- /dev/null +++ b/doc/src/examples/charactermap.qdoc @@ -0,0 +1,288 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\example widgets/charactermap +\title Character Map Example + +The Character Map example shows how to create a custom widget that can +both display its own content and respond to user input. + +The example displays an array of characters which the user can click on +to enter text in a line edit. The contents of the line edit can then be +copied into the clipboard, and pasted into other applications. The +purpose behind this sort of tool is to allow users to enter characters +that may be unavailable or difficult to locate on their keyboards. + +\image charactermap-example.png Screenshot of the Character Map example + +The example consists of the following classes: + +\list +\i \c CharacterWidget displays the available characters in the current + font and style. +\i \c MainWindow provides a standard main window that contains font and + style information, a view onto the characters, a line edit, and a push + button for submitting text to the clipboard. +\endlist + +\section1 CharacterWidget Class Definition + +The \c CharacterWidget class is used to display an array of characters in +a user-specified font and style. For flexibility, we subclass QWidget and +reimplement only the functions that we need to provide basic rendering +and interaction features. + +The class definition looks like this: + +\snippet examples/widgets/charactermap/characterwidget.h 0 + +The widget does not contain any other widgets, so it must provide its own +size hint to allow its contents to be displayed correctly. +We reimplement \l{QWidget::paintEvent()} to draw custom content. We also +reimplement \l{QWidget::mousePressEvent()} to allow the user to interact +with the widget. + +The updateFont() and updateStyle() slots are used to update the font and +style of the characters in the widget whenever the user changes the +settings in the application. +The class defines the characterSelected() signal so that other parts +of the application are informed whenever the user selects a character in +the widget. +As a courtesy, the widget provides a tooltip that shows the current +character value. We reimplement the \l{QWidget::mouseMoveEvent()} event +handler and define showToolTip() to enable this feature. + +The \c columns, \c displayFont and \c currentKey private data members +are used to record the number of columns to be shown, the current font, +and the currently highlighted character in the widget. + +\section1 CharacterWidget Class Implementation + +Since the widget is to be used as a simple canvas, the constructor just +calls the base class constructor and defines some default values for +private data members. + +\snippet examples/widgets/charactermap/characterwidget.cpp 0 + +We initialize \c currentKey with a value of -1 to indicate +that no character is initially selected. We enable mouse tracking to +allow us to follow the movement of the cursor across the widget. + +The class provides two functions to allow the font and style to be set up. +Each of these modify the widget's display font and call update(): + +\snippet examples/widgets/charactermap/characterwidget.cpp 1 +\codeline +\snippet examples/widgets/charactermap/characterwidget.cpp 2 + +We use a fixed size font for the display. Similarly, a fixed size hint is +provided by the sizeHint() function: + +\snippet examples/widgets/charactermap/characterwidget.cpp 3 + +Three standard event functions are implemented so that the widget +can respond to clicks, provide tooltips, and render the available +characters. The paintEvent() shows how the contents of the widget are +arranged and displayed: + +\snippet examples/widgets/charactermap/characterwidget.cpp 6 + +A QPainter is created for the widget and, in all cases, we ensure that the +widget's background is painted. The painter's font is set to the +user-specified display font. + +The area of the widget that needs to be redrawn is used to determine which +characters need to be displayed: + +\snippet examples/widgets/charactermap/characterwidget.cpp 7 + +Using integer division, we obtain the row and column numbers of each +characters that should be displayed, and we draw a square on the widget +for each character displayed. + +\snippet examples/widgets/charactermap/characterwidget.cpp 8 +\snippet examples/widgets/charactermap/characterwidget.cpp 9 + +The symbols for each character in the array are drawn within each square, +with the symbol for the most recently selected character displayed in red: + +\snippet examples/widgets/charactermap/characterwidget.cpp 10 + +We do not need to take into account the difference between the area +displayed in the viewport and the area we are drawing on because +everything outside the visible area will be clipped. + +The mousePressEvent() defines how the widget responds to mouse clicks. + +\snippet examples/widgets/charactermap/characterwidget.cpp 5 + +We are only interested when the user clicks with the left mouse button +over the widget. When this happens, we calculate which character was +selected and emit the characterSelected() signal. +The character's number is found by dividing the x and y-coordinates of +the click by the size of each character's grid square. Since the number +of columns in the widget is defined by the \c columns variable, we +simply multiply the row index by that value and add the column number +to obtain the character number. + +If any other mouse button is pressed, the event is passed on to the +QWidget base class. This ensures that the event can be handled properly +by any other interested widgets. + +The mouseMoveEvent() maps the mouse cursor's position in global +coordinates to widget coordinates, and determines the character that +was clicked by performing the calculation + +\snippet examples/widgets/charactermap/characterwidget.cpp 4 + +The tooltip is given a position defined in global coordinates. + +\section1 MainWindow Class Definition + +The \c MainWindow class provides a minimal user interface for the example, +with only a constructor, slots that respond to signals emitted by standard +widgets, and some convenience functions that are used to set up the user +interface. + +The class definition looks like this: + +\snippet examples/widgets/charactermap/mainwindow.h 0 + +The main window contains various widgets that are used to control how +the characters will be displayed, and defines the findFonts() function +for clarity and convenience. The findStyles() slot is used by the widgets +to determine the styles that are available, insertCharacter() inserts +a user-selected character into the window's line edit, and +updateClipboard() synchronizes the clipboard with the contents of the +line edit. + +\section1 MainWindow Class Implementation + +In the constructor, we set up the window's central widget and fill it with +some standard widgets (two comboboxes, a line edit, and a push button). +We also construct a CharacterWidget custom widget, and add a QScrollArea +so that we can view its contents: + +\snippet examples/widgets/charactermap/mainwindow.cpp 0 + +QScrollArea provides a viewport onto the \c CharacterWidget when we set +its widget and handles much of the work needed to provide a scrolling +viewport. + +The font combo box is automatically popuplated with a list of available +fonts. We list the available styles for the current font in the style +combobox using the following function: + +\snippet examples/widgets/charactermap/mainwindow.cpp 1 + +The line edit and push button are used to supply text to the clipboard: + +\snippet examples/widgets/charactermap/mainwindow.cpp 2 + +We also obtain a clipboard object so that we can send text entered by the +user to other applications. + +Most of the signals emitted in the example come from standard widgets. +We connect these signals to slots in this class, and to the slots provided +by other widgets. + +\snippet examples/widgets/charactermap/mainwindow.cpp 4 + +The font combobox's +\l{QFontComboBox::currentFontChanged()}{currentFontChanged()} signal is +connected to the findStyles() function so that the list of available styles +can be shown for each font that is used. Since both the font and the style +can be changed by the user, the font combobox's currentFontChanged() signal +and the style combobox's +\l{QComboBox::currentIndexChanged()}{currentIndexChanged()} are connected +directly to the character widget. + +The final two connections allow characters to be selected in the character +widget, and text to be inserted into the clipboard: + +\snippet examples/widgets/charactermap/mainwindow.cpp 5 + +The character widget emits the characterSelected() custom signal when +the user clicks on a character, and this is handled by the insertCharacter() +function in this class. The clipboard is changed when the push button emits +the clicked() signal, and we handle this with the updateClipboard() function. + +The remaining code in the constructor sets up the layout of the central widget, +and provides a window title: + +\snippet examples/widgets/charactermap/mainwindow.cpp 6 + +The font combobox is automatically populated with a list of available font +families. The styles that can be used with each font are found by the +findStyles() function. This function is called whenever the user selects a +different font in the font combobox. + +\snippet examples/widgets/charactermap/mainwindow.cpp 7 + +We begin by recording the currently selected style, and we clear the +style combobox so that we can insert the styles associated with the +current font family. + +\snippet examples/widgets/charactermap/mainwindow.cpp 8 + +We use the font database to collect the styles that are available for the +current font, and insert them into the style combobox. The current item is +reset if the original style is not available for this font. + +The last two functions are slots that respond to signals from the character +widget and the main window's push button. The insertCharacter() function is +used to insert characters from the character widget when the user clicks a +character: + +\snippet examples/widgets/charactermap/mainwindow.cpp 9 + +The character is inserted into the line edit at the current cursor position. + +The main window's "To clipboard" push button is connected to the +updateClipboard() function so that, when it is clicked, the clipboard is +updated to contain the contents of the line edit: + +\snippet examples/widgets/charactermap/mainwindow.cpp 10 + +We copy all the text from the line edit to the clipboard, but we do not clear +the line edit. +*/ diff --git a/doc/src/examples/chart.qdoc b/doc/src/examples/chart.qdoc new file mode 100644 index 0000000..22f8a51 --- /dev/null +++ b/doc/src/examples/chart.qdoc @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/chart + \title Chart Example + + The Chart example shows how to create a custom view for the model/view framework. + + \image chart-example.png + + In this example, the items in a table model are represented as slices in a pie chart, + relying on the flexibility of the model/view architecture to handle custom editing + and selection features. + + \bold{Note that you only need to create a new view class if your data requires a + specialized representation.} You should first consider using a standard QListView, + QTableView, or QTreeView with a custom QItemDelegate subclass if you need to + represent data in a special way. + + \omit + \section1 PieView Class Definition + + The \c PieView class is a subclass of QAbstractItemView. The base class provides + much of the functionality required by view classes, so we only need to provide + implementations for three public functions: visualRect(), scrollTo(), and + indexAt(). However, the view needs to maintain strict control over its look and + feel, so we also provide implementations for a number of other functions: + + \snippet examples/itemviews/chart/pieview.h 0 + + + + \section1 PieView Class Implementation + + The paint event renders the data from the standard item model as a pie chart. + We interpret the data in the following way: + + \list + \o Column 0 contains data in two different roles: + The \l{Qt::ItemDataRole}{DisplayRole} contains a label, and the + \l{Qt::ItemDataRole}{DecorationRole} contains the color of the pie slice. + \o Column 1 contains a quantity which we will convert to the angular extent of + the slice. + \endlist + + The figure is always drawn with the chart on the left and the key on + the right. This means that we must try and obtain an area that is wider + than it is tall. We do this by imposing a particular aspect ratio on + the chart and applying it to the available vertical space. This ensures + that we always obtain the maximum horizontal space for the aspect ratio + used. + We also apply fixed size margin around the figure. + + We use logical coordinates to draw the chart and key, and position them + on the view using viewports. + \endomit +*/ diff --git a/doc/src/examples/classwizard.qdoc b/doc/src/examples/classwizard.qdoc new file mode 100644 index 0000000..a36edf7 --- /dev/null +++ b/doc/src/examples/classwizard.qdoc @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example dialogs/classwizard + \title Class Wizard Example + + The License Wizard example shows how to implement linear + wizards using QWizard. + + \image classwizard.png Screenshot of the Class Wizard example + + Most wizards have a linear structure, with page 1 followed by + page 2 and so on until the last page. Some wizards are more + complex in that they allow different traversal paths based on the + information provided by the user. The + \l{dialogs/licensewizard}{License Wizard} example shows how to + create such wizards. + + The Class Wizard example consists of the following classes: + + \list + \o \c ClassWizard inherits QWizard and provides a + three-step wizard that generates the skeleton of a C++ class + based on the user's input. + \o \c IntroPage, \c ClassInfoPage, \c CodeStylePage, \c + OutputFilesPage, and \c ConclusionPage are QWizardPage + subclasses that implement the wizard pages. + \endlist + + \section1 ClassWizard Class Definition + + \image classwizard-flow.png The Class Wizard pages + + We will see how to subclass QWizard to implement our own wizard. + The concrete wizard class is called \c ClassWizard and provides + five pages: + + \list + \o The first page is an introduction page, telling the user what + the wizard is going to do. + \o The second page asks for a class name and a base class, and + allows the user to specify whether the class should have a \c + Q_OBJECT macro and what constructors it should provide. + \o The third page allows the user to set some options related to the code + style, such as the macro used to protect the header file from + multiple inclusion (e.g., \c MYDIALOG_H). + \o The fourth page allows the user to specify the names of the + output files. + \o The fifth page is a conclusion page. + \endlist + + Although the program is just an example, if you press \gui Finish + (\gui Done on Mac OS X), actual C++ source files will actually be + generated. + + \section1 The ClassWizard Class + + Here's the \c ClassWizard definition: + + \snippet examples/dialogs/classwizard/classwizard.h 0 + + The class reimplements QDialog's \l{QDialog::}{accept()} slot. + This slot is called when the user clicks \gui{Finish}. + + Here's the constructor: + + \snippet examples/dialogs/classwizard/classwizard.cpp 1 + + We instantiate the five pages and insert them into the wizard + using QWizard::addPage(). The order in which they are inserted + is also the order in which they will be shown later on. + + We call QWizard::setPixmap() to set the banner and the + background pixmaps for all pages. The banner is used as a + background for the page header when the wizard's style is + \l{QWizard::}{ModernStyle}; the background is used as the + dialog's background in \l{QWizard::}{MacStyle}. (See \l{Elements + of a Wizard Page} for more information.) + + \snippet examples/dialogs/classwizard/classwizard.cpp 3 + \snippet examples/dialogs/classwizard/classwizard.cpp 4 + \dots + \snippet examples/dialogs/classwizard/classwizard.cpp 5 + \snippet examples/dialogs/classwizard/classwizard.cpp 6 + + If the user clicks \gui Finish, we extract the information from + the various pages using QWizard::field() and generate the files. + The code is long and tedious (and has barely anything to do with + noble art of designing wizards), so most of it is skipped here. + See the actual example in the Qt distribution for the details if + you're curious. + + \section1 The IntroPage Class + + The pages are defined in \c classwizard.h and implemented in \c + classwizard.cpp, together with \c ClassWizard. We will start with + the easiest page: + + \snippet examples/dialogs/classwizard/classwizard.h 1 + \codeline + \snippet examples/dialogs/classwizard/classwizard.cpp 7 + + A page inherits from QWizardPage. We set a + \l{QWizardPage::}{title} and a + \l{QWizard::WatermarkPixmap}{watermark pixmap}. By not setting + any \l{QWizardPage::}{subTitle}, we ensure that no header is + displayed for this page. (On Windows, it is customary for wizards + to display a watermark pixmap on the first and last pages, and to + have a header on the other pages.) + + Then we create a QLabel and add it to a layout. + + \section1 The ClassInfoPage Class + + The second page is defined and implemented as follows: + + \snippet examples/dialogs/classwizard/classwizard.h 2 + \codeline + \snippet examples/dialogs/classwizard/classwizard.cpp 9 + \dots + \snippet examples/dialogs/classwizard/classwizard.cpp 12 + \dots + \snippet examples/dialogs/classwizard/classwizard.cpp 13 + + First, we set the page's \l{QWizardPage::}{title}, + \l{QWizardPage::}{subTitle}, and \l{QWizard::LogoPixmap}{logo + pixmap}. The logo pixmap is displayed in the page's header in + \l{QWizard::}{ClassicStyle} and \l{QWizard::}{ModernStyle}. + + Then we create the child widgets, create \l{Registering and Using + Fields}{wizard fields} associated with them, and put them into + layouts. The \c className field is created with an asterisk (\c + *) next to its name. This makes it a \l{mandatory field}, that + is, a field that must be filled before the user can press the + \gui Next button (\gui Continue on Mac OS X). The fields' values + can be accessed from any other page using QWizardPage::field(), + or from the wizard code using QWizard::field(). + + \section1 The CodeStylePage Class + + The third page is defined and implemented as follows: + + \snippet examples/dialogs/classwizard/classwizard.h 3 + \codeline + \snippet examples/dialogs/classwizard/classwizard.cpp 14 + \dots + \snippet examples/dialogs/classwizard/classwizard.cpp 15 + \codeline + \snippet examples/dialogs/classwizard/classwizard.cpp 16 + + The code in the constructor is very similar to what we did for \c + ClassInfoPage, so we skipped most of it. + + The \c initializePage() function is what makes this class + interesting. It is reimplemented from QWizardPage and is used to + initialize some of the page's fields with values from the + previous page (namely, \c className and \c baseClass). For + example, if the class name on page 2 is \c SuperDuperWidget, the + default macro name on page 3 is \c SUPERDUPERWIDGET_H. + + The \c OutputFilesPage and \c ConclusionPage classes are very + similar to \c CodeStylePage, so we won't review them here. + + \sa QWizard, {License Wizard Example}, {Trivial Wizard Example} +*/ diff --git a/doc/src/examples/codecs.qdoc b/doc/src/examples/codecs.qdoc new file mode 100644 index 0000000..cb38cbe --- /dev/null +++ b/doc/src/examples/codecs.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/codecs + \title Codecs Example + + The Codecs example demonstrates the principles behind importing and exporting text + using codecs to ensure that characters are encoded properly, avoiding loss of data + and retaining the correct symbols used in various scripts. + + \image codecs-example.png +*/ diff --git a/doc/src/examples/codeeditor.qdoc b/doc/src/examples/codeeditor.qdoc new file mode 100644 index 0000000..669ab45 --- /dev/null +++ b/doc/src/examples/codeeditor.qdoc @@ -0,0 +1,209 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/codeeditor + \title Code Editor Example + + The Code Editor example shows how to create a simple editor that + has line numbers and that highlights the current line. + + \image codeeditor-example.png + + As can be seen from the image, the editor displays the line + numbers in an area to the left of the area for editing. The editor + will highlight the line containing the cursor. + + We implement the editor in \c CodeEditor, which is a widget that + inherits QPlainTextEdit. We keep a separate widget in \c + CodeEditor (\c LineNumberArea) onto which we draw the line + numbers. + + QPlainTextEdit inherits from QAbstractScrollArea, and editing + takes place within its \l{QAbstractScrollArea::}{viewport()}'s + margins. We make room for our line number area by setting the left + margin of the viewport to the size we need to draw the line + numbers. + + When it comes to editing code, we prefer QPlainTextEdit over + QTextEdit because it is optimized for handling plain text. See + the QPlainTextEdit class description for details. + + QPlainTextEdit lets us add selections in addition to the the + selection the user can make with the mouse or keyboard. We use + this functionality to highlight the current line. More on this + later. + + We will now move on to the definitions and implementations of \c + CodeEditor and \c LineNumberArea. Let's start with the \c + LineNumberArea class. + + \section1 The LineNumberArea Class + + We paint the line numbers on this widget, and place it over the \c + CodeEditor's \l{QAbstractScrollArea::}{viewport()}'s left margin + area. + + We need to use protected functions in QPlainTextEdit while + painting the area. So to keep things simple, we paint the area in + the \c CodeEditor class. The area also asks the editor to + calculate its size hint. + + Note that we could simply paint the line numbers directly on the + code editor, and drop the LineNumberArea class. However, the + QWidget class helps us to \l{QWidget::}{scroll()} its contents. + Also, having a separate widget is the right choice if we wish to + extend the editor with breakpoints or other code editor features. + The widget would then help in the handling of mouse events. + + \snippet widgets/codeeditor/codeeditor.h extraarea + + \section1 CodeEditor Class Definition + + Here is the code editor's class definition: + + \snippet widgets/codeeditor/codeeditor.h codeeditordefinition + + In the editor we resize and draw the line numbers on the \c + LineNumberArea. We need to do this when the number of lines in the + editor changes, and when the editor's viewport() is scrolled. Of + course, it is also done when the editor's size changes. We do + this in \c updateLineNumberWidth() and \c updateLineNumberArea(). + + Whenever, the cursor's position changes, we highlight the current + line in \c highlightCurrentLine(). + + \section1 CodeEditor Class Implementation + + We will now go through the code editors implementation, starting + off with the constructor. + + \snippet widgets/codeeditor/codeeditor.cpp constructor + + In the constructor we connect our slots to signals in + QPlainTextEdit. It is necessary to calculate the line number area + width and highlight the first line when the editor is created. + + \snippet widgets/codeeditor/codeeditor.cpp extraAreaWidth + + The \c lineNumberAreaWidth() function calculates the width of the + \c LineNumberArea widget. We take the number of digits in the last + line of the editor and multiply that with the maximum width of a + digit. + + \snippet widgets/codeeditor/codeeditor.cpp slotUpdateExtraAreaWidth + + When we update the width of the line number area, we simply call + QAbstractScrollArea::setViewportMargins(). + + \snippet widgets/codeeditor/codeeditor.cpp slotUpdateRequest + + This slot is invoked when the editors viewport has been scrolled. + The QRect given as argument is the part of the editing area that + is do be updated (redrawn). \c dy holds the number of pixels the + view has been scrolled vertically. + + \snippet widgets/codeeditor/codeeditor.cpp resizeEvent + + When the size of the editor changes, we also need to resize the + line number area. + + \snippet widgets/codeeditor/codeeditor.cpp cursorPositionChanged + + When the cursor position changes, we highlight the current line, + i.e., the line containing the cursor. + + QPlainTextEdit gives the possibility to have more than one + selection at the same time. we can set the character format + (QTextCharFormat) of these selections. We clear the cursors + selection before setting the new new + QPlainTextEdit::ExtraSelection, else several lines would get + highlighted when the user selects multiple lines with the mouse. + \omit ask someone how this works \endomit + + One sets the selection with a text cursor. When using the + FullWidthSelection property, the current cursor text block (line) + will be selected. If you want to select just a portion of the text + block, the cursor should be moved with QTextCursor::movePosition() + from a position set with \l{QTextCursor::}{setPosition()}. + + \snippet widgets/codeeditor/codeeditor.cpp extraAreaPaintEvent_0 + + The \c lineNumberAreaPaintEvent() is called from \c LineNumberArea + whenever it receives a paint event. We start off by painting the + widget's background. + + \snippet widgets/codeeditor/codeeditor.cpp extraAreaPaintEvent_1 + + We will now loop through all visible lines and paint the line + numbers in the extra area for each line. Notice that in a plain + text edit each line will consist of one QTextBlock; though, if + line wrapping is enabled, a line may span several rows in the text + edit's viewport. + + We get the top and bottom y-coordinate of the first text block, + and adjust these values by the height of the current text block in + each iteration in the loop. + + \snippet widgets/codeeditor/codeeditor.cpp extraAreaPaintEvent_2 + + Notice that we check if the block is visible in addition to check + if it is in the areas viewport - a block can, for example, be + hidden by a window placed over the text edit. + + \section1 Suggestions for Extending the Code Editor + + No self-respecting code editor is without a syntax + highligther; the \l{Syntax Highlighter Example} shows how to + create one. + + In addition to line numbers, you can add more to the extra area, + for instance, break points. + + QSyntaxHighlighter gives the possibility to add user data to each + text block with + \l{QSyntaxHighlighter::}{setCurrentBlockUserData()}. This can be + used to implement parenthesis matching. In the \c + highlightCurrentLine(), the data of the currentBlock() can be + fetched with QTextBlock::userData(). Matching parentheses can be + highlighted with an extra selection. + +*/ diff --git a/doc/src/examples/collidingmice-example.qdoc b/doc/src/examples/collidingmice-example.qdoc new file mode 100644 index 0000000..7ea2ca2 --- /dev/null +++ b/doc/src/examples/collidingmice-example.qdoc @@ -0,0 +1,279 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example graphicsview/collidingmice + \title Colliding Mice Example + + The Colliding Mice example shows how to use the Graphics View + framework to implement animated items and detect collision between + items. + + \image collidingmice-example.png + + Graphics View provides the QGraphicsScene class for managing and + interacting with a large number of custom-made 2D graphical items + derived from the QGraphicsItem class, and a QGraphicsView widget + for visualizing the items, with support for zooming and rotation. + + The example consists of an item class and a main function: + the \c Mouse class represents the individual mice extending + QGraphicsItem, and the \c main() function provides the main + application window. + + We will first review the \c Mouse class to see how to animate + items and detect item collision, and then we will review the \c + main() function to see how to put the items into a scene and how to + implement the corresponding view. + + \section1 Mouse Class Definition + + The \c mouse class inherits both QObject and QGraphicsItem. The + QGraphicsItem class is the base class for all graphical items in + the Graphics View framework, and provides a light-weight + foundation for writing your own custom items. + + \snippet examples/graphicsview/collidingmice/mouse.h 0 + + When writing a custom graphics item, you must implement + QGraphicsItem's two pure virtual public functions: \l + {QGraphicsItem::}{boundingRect()}, which returns an estimate of + the area painted by the item, and \l {QGraphicsItem::}{paint()}, + which implements the actual painting. In addition, we reimplement + the \l {QGraphicsItem::}{shape()} function to return an accurate + shape of our mouse item; the default implementation simply returns + the item's bounding rectangle. + + The rationale for deriving from QObject in addition to + QGraphicsItem is to be able to animate our items by reimplementing + QObject's \l {QObject::}{timerEvent()} function and use + QObject::startTimer() to generate timer events. + + \section1 Mouse Class Definition + + When constructing a mouse item, we first ensure that all the item's + private variables are properly initialized: + + \snippet examples/graphicsview/collidingmice/mouse.cpp 0 + + To calculate the various components of the mouse's color, we use + the global qrand() function which is a thread-safe version of the + standard C++ rand() function. + + Then we call the \l {QGraphicsItem::rotate()}{rotate()} function + inherited from QGraphicsItem. Items live in their own local + coordinate system. Their coordinates are usually centered around + (0, 0), and this is also the center for all transformations. By + calling the item's \l {QGraphicsItem::rotate()}{rotate()} function + we alter the direction in which the mouse will start moving. + + In the end we call QObject's \l {QObject::}{startTimer()} + function, emitting a timer event every 1000/33 millisecond. This + enables us to animate our mouse item using our reimplementation of + the \l {QObject::}{timerEvent()} function; whenever a mouse + receives a timer event it will trigger \l + {QObject::}{timerEvent()}: + + \snippet examples/graphicsview/collidingmice/mouse.cpp 4 + \snippet examples/graphicsview/collidingmice/mouse.cpp 5 + \snippet examples/graphicsview/collidingmice/mouse.cpp 6 + + First we ensure that the mice stays within a circle with a radius + of 150 pixels. + + Note the \l {QGraphicsItem::mapFromScene()}{mapFromScene()} + function provided by QGraphicsItem. This function maps a position + given in \e scene coordinates, to the item's coordinate system. + + \snippet examples/graphicsview/collidingmice/mouse.cpp 7 + \snippet examples/graphicsview/collidingmice/mouse.cpp 8 + \snippet examples/graphicsview/collidingmice/mouse.cpp 9 + \codeline + \snippet examples/graphicsview/collidingmice/mouse.cpp 10 + + Then we try to avoid colliding with other mice. + + \snippet examples/graphicsview/collidingmice/mouse.cpp 11 + + Finally, we calculate the mouse's speed and its eye direction (for + use when painting the mouse), and set its new position. + + The position of an item describes its origin (local coordinate (0, + 0)) in the parent coordinates. The \l {QGraphicsItem::setPos()} + function sets the position of the item to the given position in + the parent's coordinate system. For items with no parent, the + given position is interpreted as scene coordinates. QGraphicsItem + also provides a \l {QGraphicsItem::}{mapToParent()} function to + map a position given in item coordinates, to the parent's + coordinate system. If the item has no parent, the position will be + mapped to the scene's coordinate system instead. + + Then it is time to provide an implementation for the pure virtual + functions inherited from QGraphicsItem. Let's first take a look at + the \l {QGraphicsItem::}{boundingRect()} function: + + \snippet examples/graphicsview/collidingmice/mouse.cpp 1 + + The \l {QGraphicsItem::boundingRect()}{boundingRect()} function + defines the outer bounds of the item as a rectangle. Note that the + Graphics View framework uses the bounding rectangle to determine + whether the item requires redrawing, so all painting must be + restricted inside this rectangle. + + \snippet examples/graphicsview/collidingmice/mouse.cpp 3 + + The Graphics View framework calls the \l + {QGraphicsItem::paint()}{paint()} function to paint the contents + of the item; the function paints the item in local coordinates. + + Note the painting of the ears: Whenever a mouse item collides with + other mice items its ears are filled with red; otherwise they are + filled with dark yellow. We use the + QGraphicsScene::collidingItems() function to check if there are + any colliding mice. The actual collision detection is handled by + the Graphics View framework using shape-shape intersection. All we + have to do is to ensure that the QGraphicsItem::shape() function + returns an accurate shape for our item: + + \snippet examples/graphicsview/collidingmice/mouse.cpp 2 + + Because the complexity of arbitrary shape-shape intersection grows + with an order of magnitude when the shapes are complex, this + operation can be noticably time consuming. An alternative approach + is to reimplement the \l + {QGraphicsItem::collidesWithItem()}{collidesWithItem()} function + to provide your own custom item and shape collision algorithm. + + This completes the \c Mouse class implementation, it is now ready + for use. Let's take a look at the \c main() function to see how to + implement a scene for the mice and a view for displaying the + contents of the scene. + + \section1 The Main() Function + + In this example we have chosen to let the \c main() function + provide the main application window, creating the items and the + scene, putting the items into the scene and creating a + corresponding view. + + \snippet examples/graphicsview/collidingmice/main.cpp 0 + + First, we create an application object and call the global + qsrand() function to specify the seed used to generate a new + random number sequence of pseudo random integers with the + previously mentioned qrand() function. + + Then it is time to create the scene: + + \snippet examples/graphicsview/collidingmice/main.cpp 1 + + The QGraphicsScene class serves as a container for + QGraphicsItems. It also provides functionality that lets you + efficiently determine the location of items as well as determining + which items that are visible within an arbitrary area on the + scene. + + When creating a scene it is recommended to set the scene's + rectangle, i.e., the rectangle that defines the extent of the + scene. It is primarily used by QGraphicsView to determine the + view's default scrollable area, and by QGraphicsScene to manage + item indexing. If not explicitly set, the scene's default + rectangle will be the largest bounding rectangle of all the items + on the scene since the scene was created (i.e., the rectangle will + grow when items are added or moved in the scene, but it will never + shrink). + + \snippet examples/graphicsview/collidingmice/main.cpp 2 + + The item index function is used to speed up item discovery. \l + {QGraphicsScene::NoIndex}{NoIndex} implies that item location is + of linear complexity, as all items on the scene are + searched. Adding, moving and removing items, however, is done in + constant time. This approach is ideal for dynamic scenes, where + many items are added, moved or removed continuously. The + alternative is \l {QGraphicsScene::BspTreeIndex}{BspTreeIndex} + which makes use of binary search resulting in item location + algorithms that are of an order closer to logarithmic complexity. + + \snippet examples/graphicsview/collidingmice/main.cpp 3 + + Then we add the mice to the scene. + + \snippet examples/graphicsview/collidingmice/main.cpp 4 + + To be able to view the scene we must also create a QGraphicsView + widget. The QGraphicsView class visualizes the contents of a scene + in a scrollable viewport. We also ensure that the contents is + rendered using antialiasing, and we create the cheese background + by setting the view's background brush. + + The image used for the background is stored as a binary file in + the application's executable using Qt's \l {The Qt Resource + System}{resource system}. The QPixmap constructor accepts both + file names that refer to actual files on disk and file names that + refer to the application's embedded resources. + + \snippet examples/graphicsview/collidingmice/main.cpp 5 + + Then we set the cache mode; QGraphicsView can cache pre-rendered + content in a pixmap, which is then drawn onto the viewport. The + purpose of such caching is to speed up the total rendering time + for areas that are slow to render, e.g., texture, gradient and + alpha blended backgrounds. The \l + {QGraphicsView::CacheMode}{CacheMode} property holds which parts + of the view that are cached, and the \l + {QGraphicsView::CacheBackground}{CacheBackground} flag enables + caching of the view's background. + + By setting the \l {QGraphicsView::dragMode}{dragMode} property we + define what should happen when the user clicks on the scene + background and drags the mouse. The \l + {QGraphicsView::ScrollHandDrag}{ScrollHandDrag} flag makes the + cursor change into a pointing hand, and dragging the mouse around + will scroll the scrollbars. + + \snippet examples/graphicsview/collidingmice/main.cpp 6 + + In the end, we set the application window's title and size before + we enter the main event loop using the QApplication::exec() + function. +*/ + diff --git a/doc/src/examples/coloreditorfactory.qdoc b/doc/src/examples/coloreditorfactory.qdoc new file mode 100644 index 0000000..768bb51 --- /dev/null +++ b/doc/src/examples/coloreditorfactory.qdoc @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/coloreditorfactory + \title Color Editor Factory Example + + This example shows how to create an editor that can be used by + a QItemDelegate. + + \image coloreditorfactoryimage.png + + When editing data in a QListView, QTableView, or QTreeView, + editors are created and displayed by a \l{Delegate + Classes}{delegate}. QItemDelegate, which is the default delegate + used by Qt's \l{View Classes}{item views}, uses a + QItemEditorFactory to create editors for it. A unique instance + provided by QItemEditorFactory is by default installed on all + item delegates. + + An item editor factory contains a collection of + QItemEditorCreatorBase instances, which are specialized factories + that produce editors for one particular QVariant data type (all + models in Qt store their data in \l{QVariant}s). An editor can be any + Qt or custom widget. + + In this example, we will create an editor (implemented in the \c + ColorListEditor class) that can edit the QColor data type and be + used by \l{QItemDelegate}s. We do this by creating a new + QItemEditorCreatorBase that produces \c ColorListEditors and + register it with a new factory, which we set as the default editor + item factory (the unique factory instance). To test our editor, we + have implemented the \c Window class, which displays a + QTableWidget in which \l{QColor}s can be edited. + + \section1 Window Class Implementation + + In the Window class, we create the item editor creator + base for our color editor and add it to the default factory. + We also create a QTableWidget in which our editor can be + tested. It is filled with some data and displayed in a window. + + We take a closer look at the constructor: + + \snippet examples/itemviews/coloreditorfactory/window.cpp 0 + + The QStandardItemEditorCreator is a convenience class that + inherits QItemEditorCreatorBase. Its constructor takes a template + class, of which instances are returned from + \l{QItemEditorCreatorBase::}{createWidget()}. The creator uses a + constructor that takes a QWidget as its only parameter; the + template class must provide this. This way, there is no need to + subclass QStandardItemEditorCreator. + + After the new factory has been set, all standard item delegates + will use it (i.e, also delegates that were created before the new + default factory was set). + + The \c createGUI() function sets up the table and fills it + with data. + + \section1 ColorListEditor Definition + + The ColorListEditor inherits QComboBox and lets the user + select a QColor from its popup list. + + \snippet examples/itemviews/coloreditorfactory/colorlisteditor.h 0 + + QItemDelegate manages the interaction between the editor and + the model, i.e., it retrieves data to edit from the model and + store data from the editor in the model. The data that is edited + by an editor is stored in the editor's user data property, and the + delegate uses Qt's \l{Qt's Property System}{property system} to + access it by name. We declare our user data property with the + Q_PROPERTY macro. The property is set to be the user type with the + USER keyword. + + \section1 ColorListEditor Implementation + + The constructor of \c ColorListEditor simply calls \c + populateList(), which we will look at later. We move on to the + \c color() function: + + \snippet examples/itemviews/coloreditorfactory/colorlisteditor.cpp 0 + + We return the data that is selected in the combobox. The data + is stored in the Qt::DecorationRole as the color is then also + displayed in the popup list (as shown in the image above). + + \snippet examples/itemviews/coloreditorfactory/colorlisteditor.cpp 1 + + The \c findData() function searches the items in the combobox + and returns the index of the item that has \c color in the + Qt::Decoration role. + + \snippet examples/itemviews/coloreditorfactory/colorlisteditor.cpp 2 + + Qt knows some predefined colors by name. We simply loop + through these to fill our editor with items. + + \section1 Further Customization of Item View Editors + + You can customize Qt's \l{Model/View Programming}{model view + framework} in many ways. The procedure shown in this example is + usually sufficient to provide custom editors. Further + customization is achieved by subclassing QItemEditorFactory + and QItemEditorCreatorBase. It is also possible to subclass + QItemDelegate if you don't wish to use a factory at all. + + Possible suggestions are: + + \list + \o If the editor widget has no user property defined, the delegate + asks the factory for the property name, which it in turn + asks the item editor creator for. In this case, you can use + the QItemEditorCreator class, which takes the property + name to use for editing as a constructor argument. + \o If the editor requires other constructors or other + initialization than provided by QItemEditorCreatorBase, you + must reimplement + QItemEditorCreatorBase::createWidget(). + \o You could also subclass QItemEditorFactory if you only want + to provide editors for certain kinds of data or use another + method of creating the editors than using creator bases. + \endlist + + In this example, we use a standard QVariant data type. You can + also use custom types. In the \l{Star Delegate Example}, we + show how to store a custom data type in a QVariant and paint + and edit it in a class that inherits QItemDelegate. +*/ diff --git a/doc/src/examples/combowidgetmapper.qdoc b/doc/src/examples/combowidgetmapper.qdoc new file mode 100644 index 0000000..cf44bdb --- /dev/null +++ b/doc/src/examples/combowidgetmapper.qdoc @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/combowidgetmapper + \title Combo Widget Mapper Example + + The Delegate Widget Mapper example shows how to use a custom delegate to + map information from a model to specific widgets on a form. + + \image combo-widget-mapper.png + + In the \l{Simple Widget Mapper Example}, we showed the basic use of a + widget mapper to relate data exposed by a model to simple input widgets + in a user interface. However, sometimes we want to use input widgets that + expose data as choices to the user, such as QComboBox, and we need a way + to relate their input to the values stored in the model. + + This example is very similar to the \l{Simple Widget Mapper Example}. + Again, we create a \c Window class with an almost identical user interface, + except that, instead of providing a spin box so that each person's age + can be entered, we provide a combo box to allow their addresses to be + classified as "Home", "Work" or "Other". + + \section1 Window Class Definition + + The class provides a constructor, a slot to keep the buttons up to date, + and a private function to set up the model: + + \snippet examples/itemviews/combowidgetmapper/window.h Window definition + + In addition to the QDataWidgetMapper object and the controls used to make + up the user interface, we use a QStandardItemModel to hold our data and + a QStringListModel to hold information about the types of address that + can be applied to each person's data. + + \section1 Window Class Implementation + + The constructor of the \c Window class can be explained in three parts. + In the first part, we set up the widgets used for the user interface: + + \snippet examples/itemviews/combowidgetmapper/window.cpp Set up widgets + + Note that we set up the mapping the combo box in the same way as for other + widgets, but that we apply its own model to it so that it will display + data from its own model, the \c typeModel, rather than from the model + containing data about each person. + + Next, we set up the widget mapper, relating each input widget to a column + in the model specified by the call to \l{QDataWidgetMapper::}{setModel()}: + + \snippet examples/itemviews/combowidgetmapper/window.cpp Set up the mapper + + For the combo box, we pass an extra argument to tell the widget mapper + which property to relate to values from the model. As a result, the user + is able to select an item from the combo box, and the corresponding + value stored in the widget's \c currentIndex property will be stored in + the model. + + \omit + However, we also set a delegate on the mapper. As with \l{Delegate Classes}, + this changes the way that data is presented to the user. In this case, the + delegate acts as a proxy between the mapper and the input widgets, + translating the data into a suitable form for the combo box but not + interfering with the other input widgets. The implementation is shown later. + \endomit + + The rest of the constructor is very similar to that of the + \l{Simple Widget Mapper Example}: + + \snippet examples/itemviews/combowidgetmapper/window.cpp Set up connections and layouts + + The model is initialized in the window's \c{setupModel()} function. Here, + we create a standard model with 5 rows and 3 columns. In each row, we + insert a name, address, and a value that indicates the type of address. + The address types are stored in a string list model. + + \snippet examples/itemviews/combowidgetmapper/window.cpp Set up the model + + As we insert each row into the model, like a record in a database, we + store values that correspond to items in \c typeModel for each person's + address type. When the widget mapper reads these values from the final + column of each row, it will need to use them as references to values in + \c typeModel, as shown in the following diagram. This is where the + delegate is used. + + \image widgetmapper-combo-mapping.png + + We show the implementation of the \c{updateButtons()} slot for + completeness: + + \snippet examples/itemviews/combowidgetmapper/window.cpp Slot for updating the buttons + + \omit + \section1 Delegate Class Definition and Implementation + + The delegate we use to mediate interaction between the widget mapper and + the input widgets is a small QItemDelegate subclass: + + \snippet examples/itemviews/combowidgetmapper/delegate.h Delegate class definition + + This provides implementations of the two standard functions used to pass + data between editor widgets and the model (see the \l{Delegate Classes} + documentation for a more general description of these functions). + + Since we only provide an empty implementation of the constructor, we + concentrate on the other two functions. + + The \l{QItemDelegate::}{setEditorData()} implementation takes the data + referred to by the model index supplied and processes it according to + the presence of a \c currentIndex property in the editor widget: + + \snippet examples/itemviews/combowidgetmapper/delegate.cpp setEditorData implementation + + If, like QComboBox, the editor widget has this property, it is set using + the value from the model. Since we are passing around QVariant values, + the strings stored in the model are automatically converted to the integer + values needed for the \c currentIndex property. + + As a result, instead of showing "0", "1" or "2" in the combo box, one of + its predefined set of items is shown. We call QItemDelegate::setEditorData() + for widgets without the \c currentIndex property. + + The \l{QItemDelegate::}{setModelData()} implementation performs the reverse + process, taking the value stored in the widget's \c currentIndex property + and storing it back in the model: + + \snippet examples/itemviews/combowidgetmapper/delegate.cpp setModelData implementation + \endomit + + \section1 Summary and Further Reading + + The use of a separate model for the combo box provides a menu of choices + that are separate from the data stored in the main model. Using a named + mapping that relates the combo box's \c currentIndex property to a column + in the model effectively allows us to store a look-up value in the model. + + However, when reading the model outside the context of the widget mapper, + we need to know about the \c typeModel to make sense of these look-up + values. It would be useful to be able to store both the data and the + choices held by the \c typeModel in one place. + This is covered by the \l{SQL Widget Mapper Example}. +*/ diff --git a/doc/src/examples/completer.qdoc b/doc/src/examples/completer.qdoc new file mode 100644 index 0000000..f47ba07 --- /dev/null +++ b/doc/src/examples/completer.qdoc @@ -0,0 +1,255 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/completer + \title Completer Example + + The Completer example shows how to provide string-completion facilities + for an input widget based on data provided by a model. + + \image completer-example.png + + This example uses a custom item model, \c DirModel, and a QCompleter object. + QCompleter is a class that provides completions based on an item model. The + type of model, the completion mode, and the case sensitivity can be + selected using combo boxes. + + \section1 The Resource File + + The Completer example requires a resource file in order to store the + \e{countries.txt} and \e{words.txt}. The resource file contains the + following code: + + \quotefile examples/tools/completer/completer.qrc + + \section1 DirModel Class Definition + + The \c DirModel class is a subclass of QDirModel, which provides a data + model for the local filesystem. + + \snippet examples/tools/completer/dirmodel.h 0 + + This class only has a constructor and a \c data() function as it is only + created to enable \c data() to return the entire file path for the + display role, unlike \l{QDirModel}'s \c data() function that only returns + the folder and not the drive label. This is further explained in + \c DirModel's implementation. + + \section1 DirModel Class Implementation + + The constructor for the \c DirModel class is used to pass \a parent to + QDirModel. + + \snippet examples/tools/completer/dirmodel.cpp 0 + + As mentioned earlier, the \c data() function is reimplemented in order to + get it to return the entire file parth for the display role. For example, + with a QDirModel, you will see "Program Files" in the view. However, with + \c DirModel, you will see "C:\\Program Files". + + \snippet examples/tools/completer/dirmodel.cpp 1 + + The screenshots below illustrate this difference: + + \table + \row \o \inlineimage completer-example-qdirmodel.png + \o \inlineimage completer-example-dirmodel.png + \endtable + + The Qt::EditRole, which QCompleter uses to look for matches, is left + unchanged. + + \section1 MainWindow Class Definition + + The \c MainWindow class is a subclass of QMainWindow and implements four + private slots - \c about(), \c changeCase(), \c changeMode(), and + \c changeModel(). + + \snippet examples/tools/completer/mainwindow.h 0 + + Within the \c MainWindow class, we have two private functions: + \c createMenu() and \c modelFromFile(). We also declare the private widgets + needed - three QComboBox objects, a QCheckBox, a QCompleter, a QLabel, and + a QLineEdit. + + \snippet examples/tools/completer/mainwindow.h 1 + + \section1 MainWindow Class Implementation + + The constructor of \c MainWindow constructs a \c MainWindow with a parent + widget and initializes the private members. The \c createMenu() function + is then invoked. + + We set up three QComboBox objects, \c modelComb, \c modeCombo and + \c caseCombo. By default, the \c modelCombo is set to QDirModel, + the \c modeCombo is set to "Filtered Popup" and the \c caseCombo is set + to "Case Insensitive". + + \snippet examples/tools/completer/mainwindow.cpp 0 + + The \c wrapCheckBox is then set up. This \c checkBox determines if the + \c{completer}'s \l{QCompleter::setWrapAround()}{setWrapAround()} property + is enabled or disabled. + + \snippet examples/tools/completer/mainwindow.cpp 1 + + We instantiate \c contentsLabel and set its size policy to + \l{QSizePolicy::Fixed}{fixed}. The combo boxes' \l{QComboBox::activated()} + {activated()} signals are then connected to their respective slots. + + \snippet examples/tools/completer/mainwindow.cpp 2 + + The \c lineEdit is set up and then we arrange all the widgets using a + QGridLayout. The \c changeModel() function is called, to initialize the + \c completer. + + \snippet examples/tools/completer/mainwindow.cpp 3 + + The \c createMenu() function is used to instantiate the QAction objects + needed to fill the \c fileMenu and \c helpMenu. The actions' + \l{QAction::triggered()}{triggered()} signals are connected to their + respective slots. + + \snippet examples/tools/completer/mainwindow.cpp 4 + + The \c modelFromFile() function accepts the \a fileName of a file and + processes it depending on its contents. + + We first validate the \c file to ensure that it can be opened in + QFile::ReadOnly mode. If this is unsuccessful, the function returns an + empty QStringListModel. + + \snippet examples/tools/completer/mainwindow.cpp 5 + + The mouse cursor is then overriden with Qt::WaitCursor before we fill + a QStringList object, \c words, with the contents of \c file. Once this + is done, we restore the mouse cursor. + + \snippet examples/tools/completer/mainwindow.cpp 6 + + As mentioned earlier, the resources file contains two files - + \e{countries.txt} and \e{words.txt}. If the \c file read is \e{words.txt}, + we return a QStringListModel with \c words as its QStringList and + \c completer as its parent. + + \snippet examples/tools/completer/mainwindow.cpp 7 + + If the \c file read is \e{countries.txt}, then we require a + QStandardItemModel with \c words.count() rows, 2 columns, and \c completer + as its parent. + + \snippet examples/tools/completer/mainwindow.cpp 8 + + A standard line in \e{countries.txt} is: + \quotation + Norway NO + \endquotation + + Hence, to populate the QStandardItemModel object, \c m, we have to + split the country name and its symbol. Once this is done, we return + \c m. + + \snippet examples/tools/completer/mainwindow.cpp 9 + + The \c changeMode() function sets the \c{completer}'s mode, depending on + the value of \c index. + + \snippet examples/tools/completer/mainwindow.cpp 10 + + The \c changeModel() function changes the item model used based on the + model selected by the user. + + A \c switch statement is used to change the item model based on the index + of \c modelCombo. If \c case is 0, we use an unsorted QDirModel, providing + us with a file path excluding the drive label. + + \snippet examples/tools/completer/mainwindow.cpp 11 + + Note that we create the model with \c completer as the parent as this + allows us to replace the model with a new model. The \c completer will + ensure that the old one is deleted the moment a new model is assigned + to it. + + If \c case is 1, we use the \c DirModel we defined earlier, resulting in + full paths for the files. + + \snippet examples/tools/completer/mainwindow.cpp 12 + + When \c case is 2, we attempt to complete names of countries. This requires + a QTreeView object, \c treeView. The country names are extracted from + \e{countries.txt} and set the popup used to display completions to + \c treeView. + + \snippet examples/tools/completer/mainwindow.cpp 13 + + The screenshot below shows the Completer with the country list model. + + \image completer-example-country.png + + If \c case is 3, we attempt to complete words. This is done using a + QStringListModel that contains data extracted from \e{words.txt}. The + model is sorted \l{QCompleter::CaseInsensitivelySortedModel} + {case insensitively}. + + The screenshot below shows the Completer with the word list model. + + \image completer-example-word.png + + Once the model type is selected, we call the \c changeMode() function and + the \c changeCase() function and set the wrap option accordingly. The + \c{wrapCheckBox}'s \l{QCheckBox::clicked()}{clicked()} signal is connected + to the \c{completer}'s \l{QCompleter::setWrapAround()}{setWrapAround()} + slot. + + \snippet examples/tools/completer/mainwindow.cpp 14 + + The \c about() function provides a brief description about the example. + + \snippet examples/tools/completer/mainwindow.cpp 15 + + \section1 \c main() Function + + The \c main() function instantiates QApplication and \c MainWindow and + invokes the \l{QWidget::show()}{show()} function. + + \snippet examples/tools/completer/main.cpp 0 + */ diff --git a/doc/src/examples/complexpingpong.qdoc b/doc/src/examples/complexpingpong.qdoc new file mode 100644 index 0000000..dd05a41 --- /dev/null +++ b/doc/src/examples/complexpingpong.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example dbus/complexpingpong + \title Complex Ping Pong Example + + The Complex Ping Pong example improves on the \l{D-Bus Ping Pong Example} by providing + a more useful demonstration of D-Bus interfaces. + + \quotefile doc/src/snippets/complexpingpong-example.qdoc +*/ diff --git a/doc/src/examples/concentriccircles.qdoc b/doc/src/examples/concentriccircles.qdoc new file mode 100644 index 0000000..7c36b0d --- /dev/null +++ b/doc/src/examples/concentriccircles.qdoc @@ -0,0 +1,245 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example painting/concentriccircles + \title Concentric Circles Example + + The Concentric Circles example shows the improved rendering + quality that can be obtained using floating point precision and + anti-aliasing when drawing custom widgets. The example also shows + how to do simple animations. + + The application's main window displays several widgets which are + drawn using the various combinations of precision and + anti-aliasing. + + \image concentriccircles-example.png + + Anti-aliasing is one of QPainter's render hints. The + QPainter::RenderHints are used to specify flags to QPainter that + may, or may not, be respected by any given + engine. QPainter::Antialiasing indicates that the engine should + anti-alias the edges of primitives if possible, i.e. put + additional pixels around the original ones to smooth the edges. + + The difference between floating point precision and integer + precision is a matter of accuracy, and is visible in the + application's main window: Even though the logic that is + calculating the circles' geometry is the same, floating points + ensure that the white spaces between each circle are of the same + size, while integers make two and two circles appear as if they + belong together. The reason is that the integer based precision + rely on rounding off non-integer calculations. + + The example consists of two classes: + + \list + \o \c CircleWidget is a custom widget which renders several animated + concentric circles. + \o \c Window is the application's main window displaying four \c + {CircleWidget}s drawn using different combinations of precision + and aliasing. + \endlist + + First we will review the CircleWidget class, then we will take a + look at the Window class. + + \section1 CircleWidget Class Definition + + The CircleWidget class inherits QWidget, and is a custom widget + which renders several animated concentric circles. + + \snippet examples/painting/concentriccircles/circlewidget.h 0 + + We declare the \c floatBased and \c antialiased variables to hold + whether an instance of the class should be rendered with integer + or float based precision, and whether the rendering should be + anti-aliased or not. We also declare functions setting each of + these variables. + + In addition we reimplement the QWidget::paintEvent() function to + apply the various combinations of precision and anti-aliasing when + rendering, and to support the animation. We reimplement the + QWidget::minimumSizeHint() and QWidget::sizeHint() functions to + give the widget a reasonable size within our application. + + We declare the private \c nextAnimationFrame() slot, and the + associated \c frameNo variable holding the number of "animation + frames" for the widget, to facilitate the animation. + + \section1 CircleWidget Class Implementation + + In the constructor we make the widget's rendering integer based + and aliased by default: + + \snippet examples/painting/concentriccircles/circlewidget.cpp 0 + + We initialize the widget's \c frameNo variable, and set the + widget's background color using the QWidget::setBackgroundColor() + function which takes a \l {QPalette::ColorRole}{color role} as + argument; the QPalette::Base color role is typically white. + + Then we set the widgets size policy using the + QWidget::setSizePolicy() function. QSizePolicy::Expanding means + that the widget's \l {QWidget::sizeHint()}{sizeHint()} is a + sensible size, but that the widget can be shrunk and still be + useful. The widget can also make use of extra space, so it should + get as much space as possible. + + \snippet examples/painting/concentriccircles/circlewidget.cpp 1 + \codeline + \snippet examples/painting/concentriccircles/circlewidget.cpp 2 + + The public \c setFloatBased() and \c setAntialiased() functions + update the widget's rendering preferences, i.e. whether the widget + should be rendered with integer or float based precision, and + whether the rendering should be anti-aliased or not. + + The functions also generate a paint event by calling the + QWidget::update() function, forcing a repaint of the widget with + the new rendering preferences. + + \snippet examples/painting/concentriccircles/circlewidget.cpp 3 + \codeline + \snippet examples/painting/concentriccircles/circlewidget.cpp 4 + + The default implementations of the QWidget::minimumSizeHint() and + QWidget::sizeHint() functions return invalid sizes if there is no + layout for the widget, otherwise they return the layout's minimum and + preferred size, respectively. + + We reimplement the functions to give the widget minimum and + preferred sizes which are reasonable within our application. + + \snippet examples/painting/concentriccircles/circlewidget.cpp 5 + + The nextAnimationFrame() slot simply increments the \c frameNo + variable's value, and calls the QWidget::update() function which + schedules a paint event for processing when Qt returns to the main + event loop. + + \snippet examples/painting/concentriccircles/circlewidget.cpp 6 + + A paint event is a request to repaint all or part of the + widget. The \c paintEvent() function is an event handler that can + be reimplemented to receive the widget's paint events. We + reimplement the event handler to apply the various combinations of + precision and anti-aliasing when rendering the widget, and to + support the animation. + + First, we create a QPainter for the widget, and set its + antialiased flag to the widget's preferred aliasing. We also + translate the painters coordinate system, preparing to draw the + widget's cocentric circles. The translation ensures that the + center of the circles will be equivalent to the widget's center. + + \snippet examples/painting/concentriccircles/circlewidget.cpp 7 + + When painting a circle, we use the number of "animation frames" to + determine the alpha channel of the circle's color. The alpha + channel specifies the color's transparency effect, 0 represents a + fully transparent color, while 255 represents a fully opaque + color. + + \snippet examples/painting/concentriccircles/circlewidget.cpp 8 + + If the calculated alpha channel is fully transparent, we don't + draw anything since that would be equivalent to drawing a white + circle on a white background. Instead we skip to the next circle + still creating a white space. If the calculated alpha channel is + fully opaque, we set the pen (the QColor passed to the QPen + constructor is converted into the required QBrush by default) and + draw the circle. If the widget's preferred precision is float + based, we specify the circle's bounding rectangle using QRectF and + double values, otherwise we use QRect and integers. + + The animation is controlled by the public \c nextAnimationFrame() + slot: Whenever the \c nextAnimationFrame() slot is called the + number of frames is incremented and a paint event is + scheduled. Then, when the widget is repainted, the alpha-blending + of the circles' colors change and the circles appear as animated. + + \section1 Window Class Definition + + The Window class inherits QWidget, and is the application's main + window rendering four \c {CircleWidget}s using different + combinations of precision and aliasing. + + \snippet examples/painting/concentriccircles/window.h 0 + + We declare the various components of the main window, i.e the text + labels and a double array that will hold reference to the four \c + {CircleWidget}s. In addition we declare the private \c + createLabel() function to simplify the constructor. + + \section1 Window Class Implementation + + \snippet examples/painting/concentriccircles/window.cpp 0 + + In the constructor, we first create the various labels and put + them in a QGridLayout. + + \snippet examples/painting/concentriccircles/window.cpp 1 + + Then we create a QTimer. The QTimer class is a high-level + programming interface for timers, and provides repetitive and + single-shot timers. + + We create a timer to facilitate the animation of our concentric + circles; when we create the four CircleWidget instances (and add + them to the layout), we connect the QTimer::timeout() signal to + each of the widgets' \c nextAnimationFrame() slots. + + \snippet examples/painting/concentriccircles/window.cpp 2 + + Before we set the layout and window title for our main window, we + make the timer start with a timeout interval of 100 milliseconds, + using the QTimer::start() function. That means that the + QTimer::timeout() signal will be emitted, forcing a repaint of the + four \c {CircleWidget}s, every 100 millisecond which is the reason + the circles appear as animated. + + \snippet examples/painting/concentriccircles/window.cpp 3 + + The private \c createLabel() function is implemented to simlify + the constructor. +*/ diff --git a/doc/src/examples/configdialog.qdoc b/doc/src/examples/configdialog.qdoc new file mode 100644 index 0000000..afb1c5f --- /dev/null +++ b/doc/src/examples/configdialog.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example dialogs/configdialog + \title Config Dialog Example + + The Config Dialog examples shows how a configuration dialog can be created by + using an icon view with a stacked widget. + + \image configdialog-example.png +*/ diff --git a/doc/src/examples/containerextension.qdoc b/doc/src/examples/containerextension.qdoc new file mode 100644 index 0000000..a4fbcea --- /dev/null +++ b/doc/src/examples/containerextension.qdoc @@ -0,0 +1,518 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example designer/containerextension + \title Container Extension Example + + The Container Extension example shows how to create a custom + multi-page plugin for Qt Designer using the + QDesignerContainerExtension class. + + \image containerextension-example.png + + To provide a custom widget that can be used with \QD, we need to + supply a self-contained implementation. In this example we use a + custom multi-page widget designed to show the container extension + feature. + + An extension is an object which modifies the behavior of \QD. The + QDesignerContainerExtension enables \QD to manage and manipulate a + custom multi-page widget, i.e. adding and deleting pages to the + widget. + + There are four available types of extensions in \QD: + + \list + \o QDesignerMemberSheetExtension provides an extension that allows + you to manipulate a widget's member functions which is displayed + when configuring connections using Qt Designer's mode for editing + signals and slots. + \o QDesignerPropertySheetExtension provides an extension that + allows you to manipulate a widget's properties which is displayed + in Qt Designer's property editor. + \o QDesignerTaskMenuExtension provides an extension that allows + you to add custom menu entries to \QD's task menu. + \o QDesignerContainerExtension provides an extension that allows + you to add (and delete) pages to a multi-page container plugin + in \QD. + \endlist + + You can use all the extensions following the same pattern as in + this example, only replacing the respective extension base + class. For more information, see the \l {QtDesigner Module}. + + The Container Extension example consists of four classes: + + \list + \o \c MultiPageWidget is a custom container widget that lets the user + manipulate and populate its pages, and navigate among these + using a combobox. + \o \c MultiPageWidgetPlugin exposes the \c MultiPageWidget class + to \QD. + \o \c MultiPageWidgetExtensionFactory creates a + \c MultiPageWidgetContainerExtension object. + \o \c MultiPageWidgetContainerExtension provides the container + extension. + \endlist + + The project file for custom widget plugins needs some additional + information to ensure that they will work within \QD. For example, + custom widget plugins rely on components supplied with \QD, and + this must be specified in the project file that we use. We will + first take a look at the plugin's project file. + + Then we will continue by reviewing the \c MultiPageWidgetPlugin + class, and take a look at the \c MultiPageWidgetExtensionFactory + and \c MultiPageWidgetContainerExtension classes. Finally, we will + take a quick look at the \c MultiPageWidget class definition. + + \section1 The Project File: containerextension.pro + + The project file must contain some additional information to + ensure that the plugin will work as expected: + + \snippet examples/designer/containerextension/containerextension.pro 0 + \snippet examples/designer/containerextension/containerextension.pro 1 + + The \c TEMPLATE variable's value makes \c qmake create the custom + widget as a library. Later, we will ensure that the widget will be + recognized as a plugin by Qt by using the Q_EXPORT_PLUGIN2() macro + to export the relevant widget information. + + The \c CONFIG variable contains two values, \c designer and \c + plugin: + + \list + \o \c designer: Since custom widgets plugins rely on components + supplied with \QD, this value ensures that our plugin links against + \QD's library (\c libQtDesigner.so). + + \o \c plugin: We also need to ensure that \c qmake considers the + custom widget a \e plugin library. + \endlist + + When Qt is configured to build in both debug and release modes, + \QD will be built in release mode. When this occurs, it is + necessary to ensure that plugins are also built in release + mode. For that reason we add a \c debug_and_release value to the + \c CONFIG variable. Otherwise, if a plugin is built in a mode that + is incompatible with \QD, it won't be loaded and installed. + + The header and source files for the widget are declared in the + usual way: + + \snippet examples/designer/containerextension/containerextension.pro 2 + + We provide an implementation of the plugin interface so that \QD + can use the custom widget. In this particular example we also + provide implementations of the container extension interface and + the extension factory. + + It is important to ensure that the plugin is installed in a + location that is searched by \QD. We do this by specifying a + target path for the project and adding it to the list of items to + install: + + \snippet doc/src/snippets/code/doc_src_examples_containerextension.qdoc 0 + + The container extension is created as a library, and will be + installed alongside the other \QD plugins when the project is + installed (using \c{make install} or an equivalent installation + procedure). + + Note that if you want the plugins to appear in a Visual Studio + integration, the plugins must be built in release mode and their + libraries must be copied into the plugin directory in the install + path of the integration (for an example, see \c {C:/program + files/trolltech as/visual studio integration/plugins}). + + For more information about plugins, see the \l {How to Create Qt + Plugins} documentation. + + \section1 MultiPageWidgetPlugin Class Definition + + The \c MultiPageWidgetPlugin class exposes the \c MultiPageWidget + class to \QD. Its definition is similar to the \l + {designer/customwidgetplugin}{Custom Widget Plugin} example's + plugin class which is explained in detail. The parts of the class + definition that is specific to this particular custom widget is + the class name and a couple of private slots: + + \snippet examples/designer/containerextension/multipagewidgetplugin.h 0 + + The plugin class provides \QD with basic information about our + plugin, such as its class name and its include file. Furthermore + it knows how to create instances of the \c MultiPageWidget widget. + \c MultiPageWidgetPlugin also defines the \l + {QDesignerCustomWidgetInterface::initialize()}{initialize()} + function which is called after the plugin is loaded into \QD. The + function's QDesignerFormEditorInterface parameter provides the + plugin with a gateway to all of \QD's API's. + + In the case of a multipage widget such as ours, we must also implement + two private slots, currentIndexChanged() and pageTitleChanged(), + to be able to update \QD's property editor whenever the user views + another page or changes one of the page titles. To be able to give + each page their own title, we have chosen to use the + QWidget::windowTitle property to store the page title (for more + information see the MultiPageWidget class \l + {designer/containerextension/multipagewidget.cpp}{implementation}). Note + that currently there is no way of adding a custom property (e.g., + a page title) to the pages without using a predefined property as + placeholder. + + The \c MultiPageWidgetPlugin class inherits from both QObject and + QDesignerCustomWidgetInterface. It is important to remember, when + using multiple inheritance, to ensure that all the interfaces + (i.e. the classes that doesn't inherit Q_OBJECT) are made known to + the meta object system using the Q_INTERFACES() macro. This + enables \QD to use \l qobject_cast() to query for supported + interfaces using nothing but a QObject pointer. + + \section1 MultiPageWidgetPlugin Class Implementation + + The MultiPageWidgetPlugin class implementation is in most parts + equivalent to the \l {designer/customwidgetplugin}{Custom Widget + Plugin} example's plugin class: + + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 0 + \codeline + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 3 + + One of the functions that differ is the isContainer() function + which returns true in this example since our custom widget is + intended to be used as a container. + + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 1 + + Another function that differ is the function creating our custom widget: + + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 2 + + In addition to create and return the widget, we connect our custom + container widget's currentIndexChanged() signal to the plugin's + currentIndexChanged() slot to ensure that \QD's property editor is + updated whenever the user views another page. We also connect the + widget's pageTitleChanged() signal to the plugin's + pageTitleChanged() slot. + + The currentIndexChanged() slot is called whenever our custom + widget's currentIndexChanged() \e signal is emitted, i.e. whenever + the user views another page: + + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 8 + + First, we retrieve the object emitting the signal using the + QObject::sender() and qobject_cast() functions. If it's called in + a slot activated by a signal, QObject::sender() returns a pointer + to the object that sent the signal; otherwise it returns 0. + + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 9 + + Once we have the widget we can update the property editor. \QD + uses the QDesignerPropertySheetExtension class to feed its + property editor, and whenever a widget is selected in its + workspace, Qt Designer will query for the widget's property sheet + extension and update the property editor. + + So what we want to achieve is to notify \QD that our widget's \e + internal selection has changed: First we use the static + QDesignerFormWindowInterface::findFormWindow() function to + retrieve the QDesignerFormWindowInterface object containing the + widget. The QDesignerFormWindowInterface class allows you to query + and manipulate form windows appearing in Qt Designer's + workspace. Then, all we have to do is to emit its \l + {QDesignerFormWindowInterface::emitSelectionChanged()}{emitSelectionChanged()} + signal, forcing an update of the property editor. + + When changing a page title a generic refresh of the property + editor is not enough because it is actually the page's property + extension that needs to be updated. For that reason we need to + access the QDesignerPropertySheetExtension object for the page + which title we want to change. The QDesignerPropertySheetExtension + class also allows you to manipulate a widget's properties, but to + get hold of the extension we must first retrieve access to \QD's + extension manager: + + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 10 + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 11 + + Again we first retrieve the widget emitting the signal, using the + QObject::sender() and qobject_cast() functions. Then we retrieve + the current page from the widget that emitted the signal, and we + use the static QDesignerFormWindowInterface::findFormWindow() + function to retrieve the form containing our widget. + + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 12 + + Now that we have the form window, the QDesignerFormWindowInterface + class provides the \l + {QDesignerFormWindowInterface::core()}{core()} function which + returns the current QDesignerFormEditorInterface object. The + QDesignerFormEditorInterface class allows you to access Qt + Designer's various components. In particular, the + QDesignerFormEditorInterface::extensionManager() function returns + a reference to the current extension manager. + + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 13 + + Once we have the extension manager we can update the extension + sheet: First we retrieve the property extension for the page which + title we want to change, using the qt_extension() function. Then + we retrieve the index for the page title using the + QDesignerPropertySheetExtension::indexOf() function. As previously + mentioned, we have chosen to use the QWidget::windowTitle property + to store the page title (for more information see the + MultiPageWidget class \l + {designer/containerextension/multipagewidget.cpp}{implementation}). + Finally, we implicitly force an update of the page's property + sheet by calling the the + QDesignerPropertySheetExtension::setChanged() function. + + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 4 + + Note also the initialize() function: The \c initialize() function + takes a QDesignerFormEditorInterface object as argument. + + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 5 + + When creating extensions associated with custom widget plugins, we + need to access \QD's current extension manager which we retrieve + from the QDesignerFormEditorInterface parameter. + + In addition to allowing you to manipulate a widget's properties, + the QExtensionManager class provides extension management + facilities for \QD. Using \QD's current extension manager you can + retrieve the extension for a given object. You can also register + and unregister an extension for a given object. Remember that an + extension is an object which modifies the behavior of \QD. + + When registrering an extension, it is actually the associated + extension factory that is registered. In \QD, extension factories + are used to look up and create named extensions as they are + required. So, in this example, the container extension itself is + not created until \QD must know whether the associated widget is a + container, or not. + + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 6 + + We create a \c MultiPageWidgetExtensionFactory object that we + register using \QD's current \l {QExtensionManager}{extension + manager} retrieved from the QDesignerFormEditorInterface + parameter. The first argument is the newly created factory and the + second argument is an extension identifier which is a string. The + \c Q_TYPEID() macro simply convert the string into a + QLatin1String. + + The \c MultiPageWidgetExtensionFactory class is a subclass of + QExtensionFactory. When \QD must know whether a widget is a + container, or not, \QD's extension manager will run through all + its registered factories invoking the first one which is able to + create a container extension for that widget. This factory will in + turn create a \c MultiPageWidgetExtension object. + + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 7 + + Finally, take a look at the \c domXml() function. This function + includes default settings for the widget in the standard XML + format used by \QD. In this case, we specify the container's first + page; any inital pages of a multi-page widget must be specified + within this function. + + \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 14 + + Remember to use the Q_EXPORT_PLUGIN2() macro to export the + MultiPageWidgetPlugin class for use with Qt's plugin handling + classes: This macro ensures that \QD can access and construct the + custom widget. Without this macro, there is no way for \QD to use + the widget. + + \section1 MultiPageWidgetExtensionFactory Class Definition + + The \c MultiPageWidgetExtensionFactory class inherits QExtensionFactory + which provides a standard extension factory for \QD. + + \snippet examples/designer/containerextension/multipagewidgetextensionfactory.h 0 + + The subclass's purpose is to reimplement the + QExtensionFactory::createExtension() function, making it able to + create a \c MultiPageWidget container extension. + + + \section1 MultiPageWidgetExtensionFactory Class Implementation + + The class constructor simply calls the QExtensionFactory base + class constructor: + + \snippet examples/designer/containerextension/multipagewidgetextensionfactory.cpp 0 + + As described above, the factory is invoked when \QD must know + whether the associated widget is a container, or not. + + \snippet examples/designer/containerextension/multipagewidgetextensionfactory.cpp 1 + + \QD's behavior is the same whether the requested extension is + associated with a container, a member sheet, a property sheet or a + task menu: Its extension manager runs through all its registered + extension factories calling \c createExtension() for each until + one responds by creating the requested extension. + + So the first thing we do in \c + MultiPageWidgetExtensionFactory::createExtension() is to check if + the QObject, for which the extension is requested, is in fact a \c + MultiPageWidget object. Then we check if the requested extension + is a container extension. + + If the object is a MultiPageWidget requesting a container + extension, we create and return a \c MultiPageWidgetExtension + object. Otherwise, we simply return a null pointer, allowing \QD's + extension manager to continue its search through the registered + factories. + + + \section1 MultiPageWidgetContainerExtension Class Definition + + The \c MultiPageWidgetContainerExtension class inherits + QDesignerContainerExtension which allows you to add (and delete) + pages to a multi-page container plugin in \QD. + + \snippet examples/designer/containerextension/multipagewidgetcontainerextension.h 0 + + It is important to recognize that the QDesignerContainerExtension + class only is intended to provide \QD access to your custom + multi-page widget's functionality; your custom multi-page widget + must implement functionality corresponding to the extension's + functions. + + Note also that we implement a constructor that takes \e two + arguments: the parent widget, and the \c MultiPageWidget object + for which the task menu is requested. + + QDesignerContainerExtension provides a couple of menu entries in + \QD's task menu by default, enabling the user to add or delete + pages to the associated custom multi-page widget in \QD's + workspace. + + \section1 MultiPageWidgetContainerExtension Class Implementation + + In the constructor we save the reference to the \c MultiPageWidget + object sent as parameter, i.e the widget associated with the + extension. We will need this later to access the custom multi-page + widget performing the requested actions. + + \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 0 + + To fully enable \QD to manage and manipulate your custom + multi-page widget, you must reimplement all the functions of + QDesignerContainerExtension: + + \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 1 + \codeline + \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 2 + \codeline + \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 3 + + You must reimplement \l + {QDesignerContainerExtension::addWidget()}{addWidget()} adding a + given page to the container, \l + {QDesignerContainerExtension::count()}{count()} returning the + number of pages in the container, and \l + {QDesignerContainerExtension::currentIndex()}{currentIndex()} + returning the index of the currently selected page. + + \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 4 + \codeline + \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 5 + \codeline + \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 6 + \codeline + \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 7 + + You must reimplement \l + {QDesignerContainerExtension::insertWidget()}{insertWidget()} + adding a given page to the container at a given index, \l + {QDesignerContainerExtension::remove()}{remove()} deleting the + page at a given index, \l + {QDesignerContainerExtension::setCurrentIndex()}{setCurrentIndex()} + setting the index of the currently selected page, and finally \l + {QDesignerContainerExtension::widget()}{widget()} returning the + page at a given index. + + \section1 MultiPageWidget Class Definition + + The MultiPageWidget class is a custom container widget that lets + the user manipulate and populate its pages, and navigate among + these using a combobox. + + \snippet examples/designer/containerextension/multipagewidget.h 0 + + The main detail to observe is that your custom multi-page widget + must implement functionality corresponding to the + QDesignerContainerExtension's member functions since the + QDesignerContainerExtension class only is intended to provide Qt + Designer access to your custom multi-page widget's functionality. + + In addition, we declare the \c currentIndex and \c pageTitle + properties, and their associated set and get functions. By + declaring these attributes as properties, we allow \QD to manage + them in the same way it manages the properties the MultiPageWidget + widget inherits from QWidget and QObject, for example featuring + the property editor. + + Note the \c STORED attribute in the declaration of the \c + pageTitle property: The \c STORED attribute indicates persistence, + i.e. it declares whether the property's value must be remembered + when storing an object's state. As mentioned above, we have chosen + to store the page title using the QWidget::windowTitle property to + be able to give each page their own title. For that reason the \c + pageTitle property is a "fake" property, provided for editing + purposes, and doesn't need to be stored. + + We must also implement and emit the currentIndexChanged() and + pageTitleChanged() signals to ensure that \QD's property editor is + updated whenever the user views another page or changes one of the + page titles. + + See the MultiPageWidget class \l + {designer/containerextension/multipagewidget.cpp}{implementation} + for more details. +*/ diff --git a/doc/src/examples/context2d.qdoc b/doc/src/examples/context2d.qdoc new file mode 100644 index 0000000..a45b8bb --- /dev/null +++ b/doc/src/examples/context2d.qdoc @@ -0,0 +1,353 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example script/context2d + \title Context2D Example + + This Qt Script example is an implementation of the Context2D API. + + \image context2d-example.png + + Context2D is part of the specification for the HTML \c{<canvas>} + element. It can be used to draw graphics via scripting. A good + resource for learning more about the HTML \c{<canvas>} element is + the \l{http://developer.mozilla.org/en/docs/HTML:Canvas}{Mozilla Developer Center}. + + \section1 Using The HTML Canvas Element in a Web Browser + + First, let's look at how the \c{<canvas>} element is typically + used in a web browser. The following HTML snippet defines a + canvas of size 400x400 pixels with id \c{mycanvas}: + + \code + <canvas width="400" height="400" id="mycanvas">Fallback content goes here.</canvas> + \endcode + + To draw on the canvas, we must first obtain a reference to the + DOM element corresponding to the \c{<canvas>} tag and then call + the element's getContext() function. The resulting object + implements the Context2D API that we use to draw. + + \code + <script> + var canvas = document.getElementById("mycanvas"); + var ctx = canvas.getContext("2d"); + + // Draw a face + ctx.beginPath(); + ctx.arc(75,75,50,0,Math.PI*2,true); // Outer circle + ctx.moveTo(110,75); + ctx.arc(75,75,35,0,Math.PI,false); // Mouth + ctx.moveTo(65,65); + ctx.arc(60,65,5,0,Math.PI*2,true); // Left eye + ctx.moveTo(95,65); + ctx.arc(90,65,5,0,Math.PI*2,true); // Right eye + ctx.stroke(); + </script> + \endcode + + When the page is rendered by a browser that supports the + \c{<canvas>} tag, this would be the result: + + \image context2d-example-smileysmile.png + + \section1 Using Qt Script to script a Canvas + + The goal of this example is to be able to evaluate scripts + that use the Context2D API, and render the results. Basic + interaction (mouse, keyboard) should also be supported. + In other words, we want to present scripts with an execution + environment that very much resembles that of a web browser. Of + course, our environment is only a small subset of what a browser + provides; i.e. we don't provide a full DOM API, only what is + needed to run "self-contained" Context2D scripts (i.e. scripts + that don't depend on other parts of the DOM document). + + Our "Context2D-browser" is set up through the following steps: + \list + \o Create an Environment. + \o Create a Context2D, and a QContext2DCanvas widget to render it. + \o Add the canvas object to the environment; this will enable + scripts to obtain a reference to it. + \o Evaluate scripts in the environment. + \endlist + + Once a script has been evaluated, the application handles any + timer events and input events that occur subsequently + (i.e. forwards events to their associated script targets). + + \section1 The Context2D Class + + The "heart" of this example is the Context2D C++ class that implements + the drawing API. Its interface is defined in terms of properties + and slots. Note that this class isn't tied to Qt Script in any + way. + + \snippet examples/script/context2d/context2d.h 0 + + The properties define various aspects of the Context2D + configuration. + + \snippet examples/script/context2d/context2d.h 1 + + The slots define the operations that can be performed. + + \snippet examples/script/context2d/context2d.h 2 + + The changed() signal is emitted when the contents of the drawing + area has changed, so that clients associated with the Context2D + object (i.e. the canvas widget that renders it) are notified. + + \section2 Implementation + + Conveniently enough, the concepts, data structures and operations + of the Context2D API map more or less directly to Qt's painting + API. Conceptually, all we have to do is initialize a QPainter + according to the Context2D properties, and use functions like + QPainter::strokePath() to do the painting. Painting is done on a + QImage. + + \snippet examples/script/context2d/context2d.cpp 0 + + The property accessors and most of the slots manipulate the + internal Context2D state in some way. For the \c{lineCap} + property, Context2D uses a string representation; we therefore + have to map it from/to a Qt::PenCapStyle. The \c{lineJoin} + property is handled in the same fashion. All the property setters + also set a \e{dirty flag} for the property; this is used to + decide which aspects of the QPainter that need to be updated + before doing the next painting operation. + + \snippet examples/script/context2d/context2d.cpp 3 + + The implementation of the \c{fillStyle} property is interesting, + since the value can be either a string or a \c{CanvasGradient}. + We handle this by having the property be of type QVariant, + and check the actual type of the value to see how to handle the + write. + + \snippet examples/script/context2d/context2d.cpp 1 + + Context2D does not have a concept of a paint event; painting + operations can happen at any time. We would like to be efficient, + and not have to call QPainter::begin() and QPainter::end() for + every painting operation, since typically many painting operations + will follow in quick succession. The implementations of the + painting operations use a helper function, beginPainting(), that + activates the QPainter if it isn't active already, and updates + the state of the QPainter (brush, pen, etc.) so that it reflects + the current Context2D state. + + \snippet examples/script/context2d/context2d.cpp 2 + + The implementation of each painting operation ends by calling + scheduleChange(), which will post a zero-timer event if one is + not already pending. When the application returns to the event + loop later (presumably after all the drawing operations have + finished), the timer will trigger, QPainter::end() will be + called, and the changed() signal is emitted with the new + image as argument. The net effect is that there will typically + be only a single (QPainter::begin(), QPainter::end()) pair + executed for the full sequence of painting operations. + + \section1 The Canvas Widget + + \snippet examples/script/context2d/qcontext2dcanvas.h 0 + + The QContext2DCanvas class provides a widget that renders + the contents of a Context2D object. It also provides a + minimal scripting API, most notably the getContext() function. + + \snippet examples/script/context2d/qcontext2dcanvas.cpp 3 + + The constructor connects to the changed() signal of the + Context2D object, so that the widget can update itself + when it needs to do so. Mouse tracking is enabled so that + mouse move events will be received even when no mouse + buttons are depressed. + + \snippet examples/script/context2d/qcontext2dcanvas.cpp 0 + + The getContext() function asks the environment to wrap the + Context2D object; the resulting proxy object makes the + Context2D API available to scripts. + + \snippet examples/script/context2d/qcontext2dcanvas.cpp 1 + + The paintEvent() function simply paints the contents that + was last received from the Context2D object. + + \snippet examples/script/context2d/qcontext2dcanvas.cpp 2 + + The canvas widget reimplements mouse and key event handlers, and + forwards these events to the scripting environment. The + environment will take care of delivering the event to the proper + script target, if any. + + \section1 The Environment + + \snippet examples/script/context2d/environment.h 0 + + The Environment class provides a scripting environment where a + Canvas C++ object can be registered, looked up by ID (name), + and where scripts can be evaluated. The environment has a + \c{document} property, just like the scripting environment of a + web browser, so that scripts can call + \c{document.getElementById()} to obtain a reference to a canvas. + + \snippet examples/script/context2d/environment.h 1 + + The Environment class provides the timer attributes of the DOM + Window Object interface. This enables us to support scripts that + do animation, for example. + + \snippet examples/script/context2d/environment.h 2 + + The scriptError() signal is emitted when evaluation of a script + causes a script exception. For example, if a mouse press handler + or timeout handler causes an exception, the environment's client(s) + will be notified of this and can report the error. + + \snippet examples/script/context2d/environment.cpp 0 + + The constructor initializes the environment. First it creates + the QScriptEngine that will be used to evaluate scripts. It + creates the Document object that provides the getElementById() + function. Note that the QScriptEngine::ExcludeSuperClassContents + flag is specified to avoid the wrapper objects from exposing properties + and methods inherited from QObject. Next, the environment wraps + a pointer to \e{itself}; this is to prepare for setting this object + as the script engine's Global Object. The properties of the standard + Global Object are copied, so that these will also be available in + our custom Global Object. We also create two self-references to the + object; again, this is to provide a minimal level of compabilitity + with the scripting environment that web browsers provide. + + \snippet examples/script/context2d/environment.cpp 5 + + The addCanvas() function adds the given canvas to the list of + registered canvas objects. The canvasByName() function looks up + a canvas by QObject::objectName(). This function is used to + implement the \c{document.getElementById()} script function. + + \snippet examples/script/context2d/environment.cpp 1 + + The setInterval() and clearInterval() implementations use a QHash + to map from timer ID to the QScriptValue that holds the expression + to evaluate when the timer is triggered. A helper function, + maybeEmitScriptError(), is called after invoking the script handler; + it will emit the scriptError() signal if the script engine has an + uncaught exception. + + \snippet examples/script/context2d/environment.cpp 2 + + The toWrapper() functions creates a QScriptValue that wraps the + given QObject. Note that the QScriptEngine::PreferExistingWrapperObject + flag is specified; this guarantees that a single, unique wrapper + object will be returned, even if toWrapper() is called several times + with the same argument. This is important, since it is possible that + a script can set new properties on the resulting wrapper object (e.g. + event handlers like \c{onmousedown}), and we want these to persist. + + \snippet examples/script/context2d/environment.cpp 3 + + The handleEvent() function determines if there exists a handler + for the given event in the environment, and if so, invokes that + handler. Since the script expects a DOM event, the Qt C++ event + must be converted to a DOM event before it is passed to the + script. This mapping is relatively straightforward, but again, + we only implement a subset of the full DOM API; just enough to + get most scripts to work. + + \snippet examples/script/context2d/environment.cpp 4 + + The newFakeDomEvent() function is a helper function that creates + a new script object and initializes it with default values for + the attributes defined in the DOM Event and DOM UIEvent + interfaces. + + \snippet examples/script/context2d/environment.h 3 + + The Document class defines two slots that become available to + scripts: getElementById() and getElementsByTagName(). + When the tag name is "canvas", getElementsByTagName() will + return a list of all canvas objects that are registered in + the environment. + + \section1 The Application Window + + \snippet examples/script/context2d/window.cpp 0 + + The Window constructor creates an Environment object and + connects to its scriptError() signal. It then creates a + Context2D object, and a QContext2DCanvas widget to hold it. + The canvas widget is given the name \c{tutorial}, and added to the + environment; scripts can access the canvas by e.g. + \c{document.getElementById('tutorial')}. + + \snippet examples/script/context2d/window.cpp 1 + + The window contains a list widget that is populated with + available scripts (read from a \c{scripts/} folder). + + \snippet examples/script/context2d/window.cpp 2 + + When an item is selected, the corresponding script is + evaluated in the environment. + + \snippet examples/script/context2d/window.cpp 3 + + When the "Run in Debugger" button is clicked, the Qt Script debugger will + automatically be invoked when the first statement of the script is + reached. This enables the user to inspect the scripting environment and + control further execution of the script; e.g. he can single-step through + the script and/or set breakpoints. It is also possible to enter script + statements in the debugger's console widget, e.g. to perform custom + Context2D drawing operations, interactively. + + \snippet examples/script/context2d/window.cpp 4 + + If the evaluation of a script causes an uncaught exception, the Qt Script + debugger will automatically be invoked; this enables the user to get an + idea of what went wrong. + +*/ diff --git a/doc/src/examples/customcompleter.qdoc b/doc/src/examples/customcompleter.qdoc new file mode 100644 index 0000000..8d0404a --- /dev/null +++ b/doc/src/examples/customcompleter.qdoc @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/customcompleter + \title Custom Completer Example + + The Custom Completer example shows how to provide string-completion + facilities for an input widget based on data provided by a model. The + completer pops up suggestions for possible words based on the first three + characters input by the user and the user's choice of word is inserted + into the \c TextEdit using QTextCursor. + + \image customcompleter-example.png + + \section1 Setting Up The Resource File + + The Custom Completer example requires a resource file, \e wordlist.txt, + that has a list of words to help QCompleter complete words. This file + contains the following: + + \quotefile examples/tools/customcompleter/customcompleter.qrc + + \section1 TextEdit Class Definition + + The \c TextEdit class is a subclass of QTextEdit with a custom + \c insertCompletion() slot and it reimplements the + \l{QAbstractScrollArea::keyPressEvent()}{keyPressEvent()} and the + \l{QWidget::focusInEvent()}{focusInEvent()} functions. \c TextEdit also + contains a private function \c textUnderCursor() and a private instance + of QCompleter, \c c. + + \snippet examples/tools/customcompleter/textedit.h 0 + + \section1 TextEdit Class Implementation + + The constructor for \c TextEdit constructs a \c TextEdit with a parent and + initializes \c c. The instructions to use the completer is displayed on + the \c TextEdit object, using the + \l{QTextEdit::setPlainText()}{setPlainText()} function. + + \snippet examples/tools/customcompleter/textedit.cpp 0 + + In addition, \c TextEdit also includes a default destructor: + + \snippet examples/tools/customcompleter/textedit.cpp 1 + + The \c setCompleter() function accepts a \a completer and sets it up. + We use \c{if (c)} to check if \c c has been initialized. If it has been + initialized, the QObject::disconnect() function is invoked to disconnect + the signal from the slot. This is to ensure that no previous completer + object is still connected to the slot. + + \snippet examples/tools/customcompleter/textedit.cpp 2 + + We then instantiate \c c with \a completer and set it as \c{TextEdit}'s + widget. The completion mode and case sensitivity are also set and then + we connect the \l{QCompleter::activated()}{activated()} signal to the + \c insertCompletion() slot. + + The \c completer() function is a getter function that returns \c c. + + \snippet examples/tools/customcompleter/textedit.cpp 3 + + The completer pops up the options available, based on the contents of + \e wordlist.txt, but the text cursor is responsible for filling in the + missing characters, according to the user's choice of word. + + Suppose the user inputs "ACT" and accepts the completer's suggestion of + "ACTUAL". The \c completion string is then sent to \c insertCompletion() + by the completer's \l{QCompleter::activated()}{activated()} signal. + + The \c insertCompletion() function is responsible for completing the word + using a QTextCursor object, \c tc. It validates to ensure that the + completer's widget is \c TextEdit before using \c tc to insert the extra + characters to complete the word. + + \snippet examples/tools/customcompleter/textedit.cpp 4 + + The figure below illustrates this process: + + \image customcompleter-insertcompletion.png + + \c{completion.length()} = 6 + + \c{c->completionPrefix().length()}=3 + + The difference between these two values is \c extra, which is 3. This + means that the last three characters from the right, "U", "A", and "L", + will be inserted by \c tc. + + The \c textUnderCursor() function uses a QTextCursor, \c tc, to select a + word under the cursor and return it. + + \snippet examples/tools/customcompleter/textedit.cpp 5 + + The \c TextEdit class reimplements \l{QWidget::focusInEvent()} + {focusInEvent()} function, which is an event handler used to receive + keyboard focus events for the widget. + + \snippet examples/tools/customcompleter/textedit.cpp 6 + + The \l{QAbstractScrollArea::keyPressEvent()}{keyPressEvent()} is + reimplemented to ignore key events like Qt::Key_Enter, Qt::Key_Return, + Qt::Key_Escape, Qt::Key_Tab, and Qt::Key_Backtab so the completer can + handle them. + + If there is an active completer, we cannot process the shortcut, Ctrl+E. + + \snippet examples/tools/customcompleter/textedit.cpp 7 + + We also handle other modifiers and shortcuts for which we do not want the + completer to respond to. + + \snippet examples/tools/customcompleter/textedit.cpp 8 + + Finally, we pop up the completer. + + \section1 MainWindow Class Definition + + The \c MainWindow class is a subclass of QMainWindow and implements a + private slot, \c about(). This class also has two private functions, + \c createMenu() and \c modelFromFile() as well as private instances of + QCompleter and \c TextEdit. + + \snippet examples/tools/customcompleter/mainwindow.h 0 + + \section1 MainWindow Class Implementation + + The constructor constructs a \c MainWindow with a parent and initializes + the \c completer. It also instantiates a \c TextEdit and sets its + completer. A QStringListModel, obtained from \c modelFromFile(), is used + to populate the \c completer. The \c{MainWindow}'s central widget is set + to \c TextEdit and its size is set to 500 x 300. + + \snippet examples/tools/customcompleter/mainwindow.cpp 0 + + The \c createMenu() function creates the necessary QAction objects needed + for the "File" and "Help" menu and their \l{QAction::triggered()} + {triggered()} signals are connected to the \c quit(), \c about(), and + \c aboutQt() slots respectively. + + \snippet examples/tools/customcompleter/mainwindow.cpp 1 + + The \c modelFromFile() function accepts a \a fileName and attempts to + extract the contents of this file into a QStringListModel. We display the + Qt::WaitCursor when we are populating the QStringList, \c words, and + restore the mouse cursor when we are done. + + \snippet examples/tools/customcompleter/mainwindow.cpp 2 + + The \c about() function provides a brief description about the Custom + Completer example. + + \snippet examples/tools/customcompleter/mainwindow.cpp 3 + + \section1 \c main() Function + + The \c main() function instantiates \c MainWindow and invokes the + \l{QWidget::show()}{show()} function. + + \snippet examples/tools/customcompleter/main.cpp 0 +*/ diff --git a/doc/src/examples/customsortfiltermodel.qdoc b/doc/src/examples/customsortfiltermodel.qdoc new file mode 100644 index 0000000..5778581 --- /dev/null +++ b/doc/src/examples/customsortfiltermodel.qdoc @@ -0,0 +1,303 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/customsortfiltermodel + \title Custom Sort/Filter Model Example + + The Custom Sort/Filter Model example illustrates how to subclass + QSortFilterProxyModel to perform advanced sorting and filtering. + + \image customsortfiltermodel-example.png Screenshot of the Custom Sort/Filter Model Example + + The QSortFilterProxyModel class provides support for sorting and + filtering data passed between another model and a view. + + The model transforms the structure of a source model by mapping + the model indexes it supplies to new indexes, corresponding to + different locations, for views to use. This approach allows a + given source model to be restructured as far as views are + concerned, without requiring any transformations on the underlying + data and without duplicating the data in memory. + + The Custom Sort/Filter Model example consists of two classes: + + \list + + \o The \c MySortFilterProxyModel class provides a custom proxy + model. + + \o The \c Window class provides the main application window, + using the custom proxy model to sort and filter a standard + item model. + + \endlist + + We will first take a look at the \c MySortFilterProxyModel class + to see how the custom proxy model is implemented, then we will + take a look at the \c Window class to see how the model is + used. Finally we will take a quick look at the \c main() function. + + \section1 MySortFilterProxyModel Class Definition + + The \c MySortFilterProxyModel class inherits the + QSortFilterProxyModel class. + + Since QAbstractProxyModel and its subclasses are derived from + QAbstractItemModel, much of the same advice about subclassing + normal models also applies to proxy models. + + On the other hand, it is worth noting that many of + QSortFilterProxyModel's default implementations of functions are + written so that they call the equivalent functions in the relevant + source model. This simple proxying mechanism may need to be + overridden for source models with more complex behavior; in this + example we derive from the QSortFilterProxyModel class to ensure + that our filter can recognize a valid range of dates, and to + control the sorting behavior. + + \snippet examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.h 0 + + We want to be able to filter our data by specifying a given period + of time. For that reason, we implement the custom \c + setFilterMinimumDate() and \c setFilterMaximumDate() functions as + well as the corresponding \c filterMinimumDate() and \c + filterMaximumDate() functions. We reimplement + QSortFilterProxyModel's \l + {QSortFilterProxyModel::filterAcceptsRow()}{filterAcceptsRow()} + function to only accept rows with valid dates, and + QSortFilterProxyModel::lessThan() to be able to sort the senders + by their email adresses. Finally, we implement a \c dateInRange() + convenience function that we will use to determine if a date is + valid. + + \section1 MySortFilterProxyModel Class Implementation + + The \c MySortFilterProxyModel constructor is trivial, passing the + parent parameter on to the base class constructor: + + \snippet examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp 0 + + The most interesting parts of the \c MySortFilterProxyModel + implementation are the reimplementations of + QSortFilterProxyModel's \l + {QSortFilterProxyModel::filterAcceptsRow()}{filterAcceptsRow()} + and \l {QSortFilterProxyModel::lessThan()}{lessThan()} + functions. Let's first take a look at our customized \c lessThan() + function. + + \snippet examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp 4 + + We want to sort the senders by their email adresses. The \l + {QSortFilterProxyModel::}{lessThan()} function is used as the < + operator when sorting. The default implementation handles a + collection of types including QDateTime and String, but in order + to be able to sort the senders by their email adresses we must + first identify the adress within the given string: + + \snippet examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp 6 + + We use QRegExp to define a pattern for the adresses we are looking + for. The QRegExp::indexIn() function attempts to find a match in + the given string and returns the position of the first match, or + -1 if there was no match. If the given string contains the + pattern, we use QRegExp's \l {QRegExp::cap()}{cap()} function to + retrieve the actual adress. The \l {QRegExp::cap()}{cap()} + function returns the text captured by the \e nth + subexpression. The entire match has index 0 and the parenthesized + subexpressions have indexes starting from 1 (excluding + non-capturing parentheses). + + \snippet examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp 3 + + The \l + {QSortFilterProxyModel::filterAcceptsRow()}{filterAcceptsRow()} + function, on the other hand, is expected to return true if the + given row should be included in the model. In our example, a row + is accepted if either the subject or the sender contains the given + regular expression, and the date is valid. + + \snippet examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp 7 + + We use our custom \c dateInRange() function to determine if a date + is valid. + + To be able to filter our data by specifying a given period of + time, we also implement functions for getting and setting the + minimum and maximum dates: + + \snippet examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp 1 + \codeline + \snippet examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp 2 + + The get functions, \c filterMinimumDate() and \c + filterMaximumDate(), are trivial and implemented as inline + function in the header file. + + This completes our custom proxy model. Let's see how we can use it + in an application. + + \section1 Window Class Definition + + The \c CustomFilter class inherits QWidget, and provides this + example's main application window: + + \snippet examples/itemviews/customsortfiltermodel/window.h 0 + + We implement two private slots, \c textFilterChanged() and \c + dateFilterChanged(), to respond to the user changing the filter + pattern, case sensitivity or any of the dates. In addition, we + implement a public \c setSourceModel() convenience function to set + up the model/ view relation. + + \section1 Window Class Implementation + + In this example, we have chosen to create and set the source model + in the \c main () function (which we will come back to later). So + when constructing the main application window, we assume that a + source model already exists and start by creating an instance of + our custom proxy model: + + \snippet examples/itemviews/customsortfiltermodel/window.cpp 0 + + We set the \l + {QSortFilterProxyModel::dynamicSortFilter}{dynamicSortFilter} + property that holds whether the proxy model is dynamically sorted + and filtered. By setting this property to true, we ensure that the + model is sorted and filtered whenever the contents of the source + model change. + + The main application window shows views of both the source model + and the proxy model. The source view is quite simple: + + \snippet examples/itemviews/customsortfiltermodel/window.cpp 1 + + The QTreeView class provides a default model/view implementation + of a tree view; our view implements a tree representation of items + in the application's source model. + + \snippet examples/itemviews/customsortfiltermodel/window.cpp 2 + + The QTreeView class provides a default model/view implementation + of a tree view; our view implements a tree representation of items + in the application's source model. We add our view widget to a + layout that we install on a corresponding group box. + + The proxy model view, on the other hand, contains several widgets + controlling the various aspects of transforming the source model's + data structure: + + \snippet examples/itemviews/customsortfiltermodel/window.cpp 3 + \snippet examples/itemviews/customsortfiltermodel/window.cpp 4 + + Note that whenever the user changes one of the filtering options, + we must explicitly reapply the filter. This is done by connecting + the various editors to functions that update the proxy model. + + \snippet examples/itemviews/customsortfiltermodel/window.cpp 5 + + The sorting will be handled by the view. All we have to do is to + enable sorting for our proxy view by setting the + QTreeView::sortingEnabled property (which is false by + default). Then we add all the filtering widgets and the proxy view + to a layout that we install on a corresponding group box. + + \snippet examples/itemviews/customsortfiltermodel/window.cpp 6 + + Finally, after putting our two group boxes into another layout + that we install on our main application widget, we customize the + application window. + + As mentioned above, we create the source model in the \c main () + function, calling the \c Window::setSourceModel() function to make + the application use it: + + \snippet examples/itemviews/customsortfiltermodel/window.cpp 7 + + The QSortFilterProxyModel::setSourceModel() function makes the + proxy model process the data in the given model, in this case out + mail model. The \l {QAbstractItemView::}{setModel()} that the + view widget inherits from the QAbstractItemModel class, sets the + model for the view to present. Note that the latter function will + also create and set a new selection model. + + \snippet examples/itemviews/customsortfiltermodel/window.cpp 8 + + The \c textFilterChanged() function is called whenever the user + changes the filter pattern or the case sensitivity. + + We first retrieve the preferred syntax (the QRegExp::PatternSyntax + enum is used to interpret the meaning of the given pattern), then + we determine the preferred case sensitivity. Based on these + preferences and the current filter pattern, we set the proxy + model's \l {QSortFilterProxyModel::}{filterRegExp} property. The + \l {QSortFilterProxyModel::}{filterRegExp} property holds the + regular expression used to filter the contents of the source + model. Note that calling QSortFilterProxyModel's \l + {QSortFilterProxyModel::}{setFilterRegExp()} function also updates + the model. + + \snippet examples/itemviews/customsortfiltermodel/window.cpp 9 + + The \c dateFilterChanged() function is called whenever the user + modifies the range of valid dates. We retrieve the new dates from + the user interface, and call the corresponding functions (provided + by our custom proxy model) to set the proxy model's minimum and + maximum dates. As we explained above, calling these functions also + updates the model. + + \section1 The Main() Function + + In this example, we have separated the application from the source + model by creating the model in the \c main () function. First we + create the application, then we create the source model: + + \snippet examples/itemviews/customsortfiltermodel/main.cpp 0 + + The \c createMailModel() function is a convenience function + provided to simplify the constructor. All it does is to create and + return a model describing a collection of emails. The model is an + instance of the QStandardItemModel class, i.e., a generic model + for storing custom data typically used as a repository for + standard Qt data types. Each mail description is added to the + model using \c addMail(), another convenience function. See \l + {itemviews/customsortfiltermodel/main.cpp}{main.cpp} for details. +*/ diff --git a/doc/src/examples/customtype.qdoc b/doc/src/examples/customtype.qdoc new file mode 100644 index 0000000..ffeccc3 --- /dev/null +++ b/doc/src/examples/customtype.qdoc @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/customtype + \title Custom Type Example + + The Custom Type example shows how to integrate a custom type into Qt's + meta-object system. + + Contents: + + \tableofcontents + + \section1 Overview + + Qt provides a range of standard value types that are used to provide + rich and meaningful APIs. These types are integrated with the meta-object + system, enabling them to be stored in QVariant objects, written out in + debugging information and sent between components in signal-slot + communication. + + Custom types can also be integrated with the meta-object system as long as + they are written to conform to some simple guidelines. In this example, we + introduce a simple \c Message class, we describe how we make it work with + QVariant, and we show how it can be extended to generate a printable + representation of itself for use in debugging output. + + \section1 The Message Class Definition + + The \c Message class is a simple value class that contains two pieces + of information (a QString and a QStringList), each of which can be read + using trivial getter functions: + + \snippet examples/tools/customtype/message.h custom type definition + + The default constructor, copy constructor and destructor are + all required, and must be public, if the type is to be integrated into the + meta-object system. Other than this, we are free to implement whatever we + need to make the type do what we want, so we also include a constructor + that lets us set the type's data members. + + To enable the type to be used with QVariant, we declare it using the + Q_DECLARE_METATYPE() macro: + + \snippet examples/tools/customtype/message.h custom type meta-type declaration + + We do not need to write any additional code to accompany this macro. + + To allow us to see a readable description of each \c Message object when it + is sent to the debug output stream, we define a streaming operator: + + \snippet examples/tools/customtype/message.h custom type streaming operator + + This facility is useful if you need to insert tracing statements in your + code for debugging purposes. + + \section1 The Message Class Implementation + + The implementation of the default constructor, copy constructor and destructor + are straightforward for the \c Message class: + + \snippet examples/tools/customtype/message.cpp Message class implementation + + The streaming operator is implemented in the following way: + + \snippet examples/tools/customtype/message.cpp custom type streaming operator + + Here, we want to represent each value depending on how many lines are stored + in the message body. We stream text to the QDebug object passed to the + operator and return the QDebug object obtained from its maybeSpace() member + function; this is described in more detail in the + \l{Creating Custom Qt Types#Making the Type Printable}{Creating Custom Qt Types} + document. + + We include the code for the getter functions for completeness: + + \snippet examples/tools/customtype/message.cpp getter functions + + With the type fully defined, implemented, and integrated with the + meta-object system, we can now use it. + + \section1 Using the Message + + In the example's \c{main()} function, we show how a \c Message object can + be printed to the console by sending it to the debug stream: + + \snippet examples/tools/customtype/main.cpp printing a custom type + + You can use the type with QVariant in exactly the same way as you would + use standard Qt value types. Here's how to store a value using the + QVariant::setValue() function: + + \snippet examples/tools/customtype/main.cpp storing a custom value + + Alternatively, the qVariantFromValue() and qVariantSetValue() functions + can be used if you are using a compiler without support for member template + functions. + + The value can be retrieved using the QVariant::value() member template + function: + + \snippet examples/tools/customtype/main.cpp retrieving a custom value + + Alternatively, the qVariantValue() template function can be used if + you are using a compiler without support for member template functions. + + \section1 Further Reading + + The custom \c Message type can also be used with direct signal-slot + connections; see the \l{Custom Type Sending Example} for a demonstration + of this. + To register a custom type for use with queued signals and slots, such as + those used in cross-thread communication, see the + \l{Queued Custom Type Example}. + + More information on using custom types with Qt can be found in the + \l{Creating Custom Qt Types} document. +*/ diff --git a/doc/src/examples/customtypesending.qdoc b/doc/src/examples/customtypesending.qdoc new file mode 100644 index 0000000..d335c28 --- /dev/null +++ b/doc/src/examples/customtypesending.qdoc @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/customtypesending + \title Custom Type Sending Example + + The Custom Type Sending example shows how to use a custom type with signals + and slots. + + \image customtypesending-example.png + + Contents: + + \tableofcontents + + \section1 Overview + + In the \l{Custom Type Example}, we showed how to integrate custom types + with the meta-object system, enabling them to be stored in QVariant + objects, written out in debugging information and used in signal-slot + communication. + + In this example, we demonstrate that the preparations made to the + \c Message class and its declaration with Q_DECLARE_METATYPE() enable it + to be used with direct signal-slot connections. We do this by creating + a \c Window class containing signals and slots whose signatures include + \c Message arguments. + + \section1 The Window Class Definition + + We define a simple \c Window class with a signal and public slot that + allow a \c Message object to be sent via a signal-slot connection: + + \snippet examples/tools/customtypesending/window.h Window class definition + + The window will contain a text editor to show the contents of a message + and a push button that the user can click to send a message. To facilitate + this, we also define the \c sendMessage() slot. We also keep a \c Message + instance in the \c thisMessage private variable which holds the actual + message to be sent. + + \section1 The Window Class Implementation + + The \c Window constructor sets up a user interface containing a text + editor and a push button. + + \snippet examples/tools/customtypesending/window.cpp Window constructor + + The button's \l{QPushButton::}{clicked()} signal is connected to the + window's \c{sendMessage()} slot, which emits the \c{messageSent(Message)} + signal with the \c Message held by the \c thisMessage variable: + + \snippet examples/tools/customtypesending/window.cpp sending a message + + We implement a slot to allow the message to be received, and this also + lets us set the message in the window programatically: + + \snippet examples/tools/customtypesending/window.cpp receiving a message + + In this function, we simply assign the new message to \c thisMessage + and update the text in the editor. + + \section1 Making the Connection + + In the example's \c{main()} function, we perform the connection between + two instances of the \c Window class: + + \snippet examples/tools/customtypesending/main.cpp main function + + We set the message for the first window and connect the + \c{messageSent(Message)} signal from each window to the other's + \c{setMessage(Message)} slot. Since the signals and slots mechanism is only + concerned with the type, we can simplify the signatures of both the + signal and slot when we make the connection. + + When the user clicks on the \gui{Send message} button in either window, + the message shown will be emitted in a signal that the other window will + receive and display. + + \section1 Further Reading + + Although the custom \c Message type can be used with direct signals and + slots, an additional registration step needs to be performed if you want + to use it with queued signal-slot connections. See the + \l{Queued Custom Type Example} for details. + + More information on using custom types with Qt can be found in the + \l{Creating Custom Qt Types} document. +*/ diff --git a/doc/src/examples/customwidgetplugin.qdoc b/doc/src/examples/customwidgetplugin.qdoc new file mode 100644 index 0000000..31ad65b --- /dev/null +++ b/doc/src/examples/customwidgetplugin.qdoc @@ -0,0 +1,252 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example designer/customwidgetplugin + \title Custom Widget Plugin Example + + The Custom Widget example shows how to create a custom widget plugin for \QD. + + \image customwidgetplugin-example.png + + In this example, the custom widget used is based on the + \l{widgets/analogclock}{Analog Clock example}, and does not provide any custom + signals or slots. + + \section1 Preparation + + To provide a custom widget that can be used with \QD, we need to supply a + self-contained implementation and provide a plugin interface. In this + example, we reuse the \l{widgets/analogclock}{Analog Clock example} for + convenience. + + Since custom widgets plugins rely on components supplied with \QD, the + project file that we use needs to contain information about \QD's + library components: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.pro 2 + \snippet examples/designer/customwidgetplugin/customwidgetplugin.pro 0 + + The \c TEMPLATE variable's value makes \c qmake create the custom + widget as a library. Later, we will ensure that the widget will be + recognized as a plugin by Qt by using the Q_EXPORT_PLUGIN2() macro + to export the relevant widget information. + + The \c CONFIG variable contains two values, \c designer and \c + plugin: + + \list + + \o \c designer: Since custom widgets plugins rely on components + supplied with \QD, this value ensures that our plugin links + against \QD's library (\c libQtDesigner.so). + + \o \c plugin: We also need to ensure that \c qmake considers the + custom widget a plugin library. + + \endlist + + When Qt is configured to build in both debug and release modes, + \QD will be built in release mode. When this occurs, it is + necessary to ensure that plugins are also built in release + mode. For that reason we add the \c debug_and_release value to the + \c CONFIG variable. Otherwise, if a plugin is built in a mode that + is incompatible with \QD, it won't be loaded and + installed. + + The header and source files for the widget are declared in the usual way, + and we provide an implementation of the plugin interface so that \QD can + use the custom widget: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.pro 3 + + It is also important to ensure that the plugin is installed in a + location that is searched by \QD. We do this by specifying a + target path for the project and adding it to the list of items to + install: + + \snippet doc/src/snippets/code/doc_src_examples_customwidgetplugin.qdoc 0 + + The custom widget is created as a library, and will be installed + alongside the other \QD plugins when the project is installed + (using \c{make install} or an equivalent installation procedure). + Later, we will ensure that it is recognized as a plugin by \QD by + using the Q_EXPORT_PLUGIN2() macro to export the relevant widget + information. + + Note that if you want the plugins to appear in a Visual Studio + integration, the plugins must be built in release mode and their + libraries must be copied into the plugin directory in the install + path of the integration (for an example, see \c {C:/program + files/trolltech as/visual studio integration/plugins}). + + For more information about plugins, see the \l {How to + Create Qt Plugins} documentation. + + \section1 AnalogClock Class Definition and Implementation + + The \c AnalogClock class is defined and implemented in exactly the same + way as described in the \l{widgets/analogclock}{Analog Clock example}. + Since the class is self-contained, and does not require any external + configuration, it can be used without modification as a custom widget in + \QD. + + \section1 AnalogClockPlugin Class Definition + + The \c AnalogClock class is exposed to \QD through the \c + AnalogClockPlugin class. This class inherits from both QObject and + the QDesignerCustomWidgetInterface class, and implements an + interface defined by QDesignerCustomWidgetInterface: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.h 0 + + The functions provide information about the widget that \QD can use in + the \l{Getting to Know Qt Designer#WidgetBox}{widget box}. + The \c initialized private member variable is used to record whether + the plugin has been initialized by \QD. + + Note that the only part of the class definition that is specific to + this particular custom widget is the class name. + + \section1 AnalogClockPlugin Implementation + + The class constructor simply calls the QObject base class constructor + and sets the \c initialized variable to \c false. + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.cpp 0 + + \QD will initialize the plugin when it is required by calling the + \c initialize() function: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.cpp 1 + + In this example, the \c initialized private variable is tested, and only + set to \c true if the plugin is not already initialized. Although, this + plugin does not require any special code to be executed when it is + initialized, we could include such code after the test for initialization. + + The \c isInitialized() function lets \QD know whether the plugin is + ready for use: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.cpp 2 + + Instances of the custom widget are supplied by the \c createWidget() + function. The implementation for the analog clock is straightforward: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.cpp 3 + + In this case, the custom widget only requires a \c parent to be specified. + If other arguments need to be supplied to the widget, they can be + introduced here. + + The following functions provide information for \QD to use to represent + the widget in the widget box. + The \c name() function returns the name of class that provides the + custom widget: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.cpp 4 + + The \c group() function is used to describe the type of widget that the + custom widget belongs to: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.cpp 5 + + The widget plugin will be placed in a section identified by its + group name in \QD's widget box. The icon used to represent the + widget in the widget box is returned by the \c icon() function: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.cpp 6 + + In this case, we return a null icon to indicate that we have no icon + that can be used to represent the widget. + + A tool tip and "What's This?" help can be supplied for the custom widget's + entry in the widget box. The \c toolTip() function should return a short + message describing the widget: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.cpp 7 + + The \c whatsThis() function can return a longer description: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.cpp 8 + + The \c isContainer() function tells \QD whether the widget is supposed to + be used as a container for other widgets. If not, \QD will not allow the + user to place widgets inside it. + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.cpp 9 + + Most widgets in Qt can contain child widgets, but it only makes sense + to use dedicated container widgets for this purpose in \QD. By returning + \c false, we indicate that the custom widget cannot hold other widgets; + if we returned true, \QD would allow other widgets to be placed inside + the analog clock and a layout to be defined. + + The \c domXml() function provides a way to include default settings for + the widget in the standard XML format used by \QD. In this case, we only + specify the widget's geometry: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.cpp 10 + + If the widget provides a reasonable size hint, it is not necessary to + define it here. In addition, returning an empty string instead of a + \c{<widget>} element will tell \QD not to install the widget in the + widget box. + + To make the analog clock widget usable by applications, we implement + the \c includeFile() function to return the name of the header file + containing the custom widget class definition: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.cpp 12 + + Finally, we use the Q_EXPORT_PLUGIN2() macro to export the \c + AnalogClockPlugin class for use with \QD: + + \snippet examples/designer/customwidgetplugin/customwidgetplugin.cpp 13 + + This macro ensures that \QD can access and construct the custom widget. + Without this macro, there is no way for \QD to use the widget. + + It is important to note that you can only use the Q_EXPORT_PLUGIN2() + macro once in any implementation. If you have several custom widgets in + an implementation that you wish to make available to \QD, you will need + to implement \l{QDesignerCustomWidgetCollectionInterface}. +*/ diff --git a/doc/src/examples/dbscreen.qdoc b/doc/src/examples/dbscreen.qdoc new file mode 100644 index 0000000..88f6d51 --- /dev/null +++ b/doc/src/examples/dbscreen.qdoc @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example qws/dbscreen + \title Double Buffered Graphics Driver Example + + The Double Buffered Graphics Driver example shows how to write your own + double buffered graphics driver and add it to Qt for Embedded Linux. + + Similar to the \l{Accelerated Graphics Driver Example}, there are three steps + to writing and implementing this graphics driver: + + \list 1 + \o \l {Step 1: Creating a Custom Graphics Driver} + {Creating a Custom Graphics Driver} + + \o \l {Step 2: Implementing the Back Buffer} + {Implementing the Back Buffer} + + \o \l {Step 3: Creating the Driver Plugin} + {Creating the Driver Plugin} + + \endlist + + After compiling the example code, install the graphics driver plugin with + the command \c {make install}. To start an application using the graphics + driver, you can either set the environment variable \l QWS_DISPLAY and + then run the application, or you can just run the application using the + \c -display switch. + + Note that this is a minimal example and this driver will not work well + with widgets painting themself directly to the screen (e.g. widgets with + the Qt::WA_PaintOnScreen window attribute set). Also, the example requires + the Linux framebuffer to be set up correctly and with the correct device + permissions. For further information, refer to + \l{Testing the Linux Framebuffer}. + + \section1 Step 1: Creating a Custom Graphics Driver + + Usually, a custom graphics driver is created by subclassing the QScreen + class, the base class for implementing screen or graphics drivers in + Qt for Embedded Linux. In this example, however, we subclass the QLinuxFbScreen + class instead, to ensure that our driver uses the Linux framebuffer. + + For our graphics driver, the \c DBScreen class, we reimplement five + functions belonging to QScreen: + + \list + \o \l{QScreen::initDevice()}{initDevice()}, + \o \l{QScreen::shutdownDevice()}{shutdownDevice()}, + \o \l{QScreen::blit()}{blit()}, + \o \l{QScreen::solidFill()}{solidFill()}, and + \o \l{QScreen::exposeRegion()}{exposeRegion()}. + \endlist + + \snippet examples/qws/dbscreen/dbscreen.h 0 + + In addition to the abovementioned functions, there is a private instance + of QPainter and QImage - \c painter, used for drawing operations on + the back buffer, and \c image, the back buffer itself. + + \section1 Step 2: Implementing the Back Buffer + + The graphics driver must carry out three main functions: + + \list 1 + \o Allocate the back buffer on startup and deallocate it on shutdown. + \o Draw to the back buffer instead of directly to the screen + (which is what QLinuxFbScreen does). + \o Copy the back buffer to the screen whenever a screen update is + done. + \endlist + + \section2 Device initializing and shutdown + + We first reimplement \c initDevice() and \c shutdownDevice(). + + The \c initDevice() function initializes the framebuffer. We reimplement + this function to enable accelerated drivers to set up the graphic card. + For this example, we first call the super class' implementation to set up + the Linux framebuffer. If this call returns \c false, we return \c false. + Otherwise, we initialize the screen cursor with + QScreenCursor::initSoftwareCursor() as well as instantiate \c image and + \c painter. Then, we return \c true. + + \snippet examples/qws/dbscreen/dbscreen.cpp 0 + + The \c shutdownDevice() function's default implementation only hides the + mouse cursor. Hence, we reimplement it to carry out the necessary cleanup + before the Qt for Embedded Linux server exits. + + \snippet examples/qws/dbscreen/dbscreen.cpp 1 + + Again, we call the super class implementation to shutdown the Linux + framebuffer prior to deleting \c image and \c painter. + + \section2 Drawing to the back buffer + + We move on to the drawing functions - \c solidFill() and \c blit(). In + QLinuxFbScreen, these functions draw directly to the Linux framebuffer; + but in our driver we reimplement them to draw to the back buffer instead. + + \snippet examples/qws/dbscreen/dbscreen.cpp 2 + + The \c solidFill() function is called from \c exposeRegion() to fill the + given \c region of the screen with the specified \c color. In this + example, we use \c painter to fill rectangles in \c image, the back + buffer, according to the given region. + + \snippet examples/qws/dbscreen/dbscreen.cpp 3 + + The \c blit() function is also called from \c exposeRegion() to copy the + given QRegion object, \c region, in the given QImage object, \c image, to + the QPoint object specified by \c topLeft. Once again we use \c painter + to draw in the back buffer, \c image. + + \section2 Displaying the buffer on the screen + + The \c exposeRegion() function is called by the Qt for Embedded Linux server + whenever a screen update is required. The given \c region is the screen + region that needs to be updated and \c changing is is the index into + QWSServer::clientWindows() of the window that caused the update. + + \snippet examples/qws/dbscreen/dbscreen.cpp 4 + + In our implementation, we first call the super class implementation to + ensure that \c solidFill() and \c blit() will be called correctly. This + causes the changed areas to be updated in the back buffer. We then call + the super class' implementation of \c blit() to copy the updated region + from the back buffer into the Linux framebuffer. + + \section1 Step 3: Creating the Driver Plugin + + Qt provides a high level API for writing Qt extentions. One of the plugin + base classes provided is QScreenDriverPlugin, which we use in this example + to create our screen driver plugin. + + \snippet examples/qws/dbscreen/dbscreendriverplugin.cpp 0 + + There are only two functions to reimplement: + + \list + \o \l{QScreenDriverPlugin::create()}{create()} - creates a driver + matching the given key + \o \l{QScreenDriverPlugin::create()}{keys()} - returns a list of + valid keys representing the drivers supported by the plugin + \endlist + + \snippet examples/qws/dbscreen/dbscreendriverplugin.cpp 1 + \codeline + \snippet examples/qws/dbscreen/dbscreendriverplugin.cpp 2 + + Our plugin will only support one driver, \c dbscreen. + + Lastly, we export the plugin. + + \snippet examples/qws/dbscreen/dbscreendriverplugin.cpp 3 + + For detailed information about the Qt plugin system see + \l{How to Create Qt Plugins.} +*/ diff --git a/doc/src/examples/dbus-chat.qdoc b/doc/src/examples/dbus-chat.qdoc new file mode 100644 index 0000000..f062c23 --- /dev/null +++ b/doc/src/examples/dbus-chat.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example dbus/dbus-chat + \title D-Bus Chat Example + + The D-Bus Chat example shows how to use D-Bus to communicate between two + applications. + + \image dbus-chat-example.png +*/ diff --git a/doc/src/examples/dbus-listnames.qdoc b/doc/src/examples/dbus-listnames.qdoc new file mode 100644 index 0000000..5b13abe --- /dev/null +++ b/doc/src/examples/dbus-listnames.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example dbus/listnames + \title D-Bus List Names Example + + The D-Bus List Names examples shows how to query D-Bus for a list of service names. +*/ diff --git a/doc/src/examples/dbus-pingpong.qdoc b/doc/src/examples/dbus-pingpong.qdoc new file mode 100644 index 0000000..6b15978 --- /dev/null +++ b/doc/src/examples/dbus-pingpong.qdoc @@ -0,0 +1,9 @@ +/*! + \example dbus/pingpong + \title D-Bus Ping Pong Example + + The D-Bus Ping Pong example provides a basic demonstration of D-Bus + interfaces. + + \quotefile doc/src/snippets/dbus-pingpong-example.qdoc +*/ diff --git a/doc/src/examples/dbus-remotecontrolledcar.qdoc b/doc/src/examples/dbus-remotecontrolledcar.qdoc new file mode 100644 index 0000000..ef31bd2 --- /dev/null +++ b/doc/src/examples/dbus-remotecontrolledcar.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example dbus/remotecontrolledcar + \title D-Bus Remote Controlled Car Example + + The Remote Controlled Car example shows how to use D-Bus to control one + application using another. + + \image remotecontrolledcar-car-example.png +*/ diff --git a/doc/src/examples/defaultprototypes.qdoc b/doc/src/examples/defaultprototypes.qdoc new file mode 100644 index 0000000..dc65902 --- /dev/null +++ b/doc/src/examples/defaultprototypes.qdoc @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example script/defaultprototypes + \title Default Prototypes Example + + This Qt Script example shows how to use default prototypes + to make a non-QObject-based type scriptable. + + \image defaultprototypes-example.png + + With QScriptEngine::setDefaultPrototype() you can specify + a QtScript object that defines a scripting interface for + a C++ type; Qt Script operations on values of such types + will then be delegated to your prototype object. In this + example, a simple scripting interface for QListWidgetItem is + defined, so that the text of items can easily be accessed from + script code. + + To define a scripting API for QListWidgetItem in terms of + Qt properties and slots, we subclass QObject and QScriptable. + + \snippet examples/script/defaultprototypes/prototypes.h 0 + + A single property, \c{text}, is defined, along with a slot, + \c{toString}. + + \snippet examples/script/defaultprototypes/prototypes.cpp 0 + + The implementation of the property accessors use + the qscriptvalue_cast() function to cast the script object + to a QListWidgetItem pointer. The normal C++ QListWidgetItem + API is then used to implement the desired functionality. + + Although not shown here, it is possible to throw a script + exception from a prototype function; for example, you could throw + a TypeError exception if the qscriptvalue_cast() fails. + + QListWidgetItems are usually added to a QListWidget. While + QListWidget is a QObject-based class, not all the functionality + needed for this example are present. We can solve this by creating + a default prototype for the QListWidget class as well. The + prototype will augment the functionality already provided by the + Qt Script QObject integration; i.e. if a property or slot is not + found in the QListWidget object itself, the prototype will be used + as a fallback. + + \snippet examples/script/defaultprototypes/prototypes.h 1 + + The additional slots will make it possible to add items to + a QListWidget from script code, and to set the background + color of the widget from a string. + + \snippet examples/script/defaultprototypes/prototypes.cpp 1 + + Again, we use qscriptvalue_cast() to cast the script object + to the relevant C++ type, in this case a QListWidget pointer. + The addItem() and addItems() functions simply forward their + arguments to the corresponding functions in the QListWidget + class. setBackgroundColor() gets the widget's palette, creates + a QColor from the given string argument and changes the palette + accordingly. + + \snippet examples/script/defaultprototypes/main.cpp 0 + + The relevant C++ types must be made known to Qt's meta type + system. + + \snippet examples/script/defaultprototypes/main.cpp 1 + + For each type that we want to associate a prototype object with, + we create an instance of the prototype class, pass it to + QScriptEngine::newQObject(), and then create the link between + the C++ type and the resulting script object by calling + QScriptEngine::setDefaultPrototype(). + + \snippet examples/script/defaultprototypes/main.cpp 2 + + In this example, a single QListWidget object is added as + a global script variable, called \c{listWidget}. Script code + can add items to this widget by calling addItem() or addItems(). + + \snippet examples/script/defaultprototypes/code.js 0 + + Script code can connect to signals of the QListWidget object; + signal handlers can use the interface defined in + the QListWidgetItem prototype to manipulate item arguments. + + \snippet examples/script/defaultprototypes/code.js 1 + + Not shown in this example is how to make QListWidgetItem + constructible from Qt Script code, i.e. to be able to + write "new QListWidgetItem()" in a script. In order to do + this, you have to define your own script constructor for + the type. The constructor would just be a factory function + that constructs a new C++ QListWidgetItem and returns it + back to the script. See QScriptEngine::newFunction() for more + information. +*/ diff --git a/doc/src/examples/delayedencoding.qdoc b/doc/src/examples/delayedencoding.qdoc new file mode 100644 index 0000000..cd1c4ae --- /dev/null +++ b/doc/src/examples/delayedencoding.qdoc @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example draganddrop/delayedencoding + \title Delayed Encoding Example + + The Delayed Encoding example shows how to delay preparing of data + for drag and drop operations until a drop target is found. + + \image delayedecoding-example.png + + The \gui Export push button is pressed down to start the drag. + The data for the drag and drop operation is not processed until + the user of the application has found a valid drop target. This + removes redundant processing if the operation is aborted. In our + case, we have an SVG image that we wish to send as the \c { + "image/png" } MIME type. It is the conversion from SVG to PNG we + wish to delay - it can be quite expensive. + + The example is implemented in two classes: \c SourceWidget and \c + MimeData. The \c SourceWidget class sets up the GUI and starts the + drag operation on request. The \c MimeData class, which inherits + QMimeData, sends a signal when a drop target is found. This signal + is connected to a slot in \c SourceWidget, which does the + conversion from SVG to PNG. + + \section1 SourceWidget Class Definition + + The \c SourceWidget class starts drag and drop operations and also + does the image conversion. + + \snippet examples/draganddrop/delayedencoding/sourcewidget.h 0 + + The \gui Export push button is connected to the \c startDrag() + slot. The \c createData() slot will be invoked when data for the + drag and drop operation is to be created. + + \section1 SourceWidget Class Implementation + + Let's start our code tour with a look at the \c startDrag() slot. + + \snippet examples/draganddrop/delayedencoding/sourcewidget.cpp 0 + + We emit \c dataRequested() from \c MimeData when the operation has + found a valid drop target. + + We gallop along to \c createData(): + + \snippet examples/draganddrop/delayedencoding/sourcewidget.cpp 1 + + Fortunately, Qt provides QSvgRenderer, which can render the SVG + image to any QPaintDevice. Also, QImage has no problems saving to + the PNG format. + + Finally, we can give the data to \c MimeData. + + \section1 MimeData Class Definition + + The \c MimeData class inherits QMimeData and makes it possible to + delay preparing of the data for a drag and drop operation. + + \snippet examples/draganddrop/delayedencoding/mimedata.h 0 + + We will look closer at \c retrieveData() and \c formats() in the + next section. + + \section1 MimeData Class Implementation + + \snippet examples/draganddrop/delayedencoding/mimedata.cpp 0 + + In the \c formats() function, we return the format of the + data we provide. This is the \c { image/png } MIME type. + + \snippet examples/draganddrop/delayedencoding/mimedata.cpp 1 + + \c retrieveData() is reimplemented from QMimeData and is + called when the data is requested by the drag and drop + operation. Fortunately for us, this happens when the operation + is finishing, i.e., when a drop target has been found. + + We emit the \c dataRequested() signal, which is picked up by + \c SourceWidget. The \c SourceWidget (as already explained) + sets the data on \c MimeData with \l{QMimeData::}{setData()}. + +*/ + diff --git a/doc/src/examples/diagramscene.qdoc b/doc/src/examples/diagramscene.qdoc new file mode 100644 index 0000000..ebf93e2 --- /dev/null +++ b/doc/src/examples/diagramscene.qdoc @@ -0,0 +1,846 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example graphicsview/diagramscene + \title Diagram Scene Example + + This example shows use of Qt's graphics framework. + + \image diagramscene.png + + The Diagram Scene example is an application in which you can + create a flowchart diagram. It is possible to add flowchart shapes + and text and connect the shapes by arrows as shown in the image + above. The shapes, arrows, and text can be given different + colors, and it is possible to change the font, style, and + underline of the text. + + The Qt graphics view framework is designed to manage and + display custom 2D graphics items. The main classes of the + framework are QGraphicsItem, QGraphicsScene and QGraphicsView. The + graphics scene manages the items and provides a surface for them. + QGraphicsView is a widget that is used to render a scene on the + screen. See the \l{The Graphics View Framework}{overview document} + for a more detailed description of the framework. + + In this example we show how to create such custom graphics + scenes and items by implementing classes that inherit + QGraphicsScene and QGraphicsItem. + + In particular we show how to: + + \list + \o Create custom graphics items. + \o Handle mouse events and movement of items. + \o Implement a graphics scene that can manage our custom items. + \o Custom painting of items. + \o Create a movable and editable text item. + \endlist + + The example consists of the following classes: + \list + \o \c MainWindow creates the widgets and display + them in a QMainWindow. It also manages the interaction + between the widgets and the graphics scene, view and + items. + \o \c DiagramItem inherits QGraphicsPolygonItem and + represents a flowchart shape. + \o \c TextDiagramItem inherits QGraphicsTextItem and + represents text items in the diagram. The class adds + support for moving the item with the mouse, which is not + supported by QGraphicsTextItem. + \o \c Arrow inherits QGraphicsLineItem and is an arrow + that connect two DiagramItems. + \o \c DiagramScene inherits QGraphicsDiagramScene and + provides support for \c DiagramItem, \c Arrow and + \c DiagramTextItem (In addition to the support already + handled by QGraphicsScene). + \endlist + + \section1 MainWindow Class Definition + + \snippet examples/graphicsview/diagramscene/mainwindow.h 0 + + The \c MainWindow class creates and lays out the widgets in a + QMainWindow. The class forwards input from the widgets to the + DiagramScene. It also updates its widgets when the diagram + scene's text item changes, or a diagram item or a diagram text item + is inserted into the scene. + + The class also deletes items from the scene and handles the + z-ordering, which decides the order in which items are drawn when + they overlap each other. + + \section1 MainWindow Class Implementation + + + We start with a look at the constructor: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 0 + + In the constructor we call methods to create the widgets and + layouts of the example before we create the diagram scene. + The toolbars must be created after the scene as they connect + to its signals. We then lay the widgets out in the window. + + We connect to the \c itemInserted() and \c textInserted() slots of + the diagram scenes as we want to uncheck the buttons in the tool + box when an item is inserted. When an item is selected in + the scene we receive the \c itemSelected() signal. We use this to + update the widgets that display font properties if the item + selected is a \c DiagramTextItem. + + The \c createToolBox() function creates and lays out the widgets + of the \c toolBox QToolBox. We will not examine it with a + high level of detail as it does not deal with graphics framework + specific functionality. Here is its implementation: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 21 + + This part of the function sets up the tabbed widget item that + contains the flowchart shapes. An exclusive QButtonGroup always + keeps one button checked; we want the group to allow all buttons + to be unchecked. + We still use a button group since we can associate user + data, which we use to store the diagram type, with each button. + The \c createCellWidget() function sets up the buttons in the + tabbed widget item and is examined later. + + The buttons of the background tabbed widget item is set up in the + same way, so we skip to the creation of the tool box: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 22 + + We set the preferred size of the toolbox as its maximum. This + way, more space is given to the graphics view. + + Here is the \c createActions() function: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 23 + + We show an example of the creation of an action. The + functionality the actions trigger is discussed in the slots we + connect the actions to. You can see the \l{Application + Example}{application example} if you need a high-level + introduction to actions. + + The is the \c createMenus() function: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 24 + + We create the three menus' of the example. + + The \c createToolbars() function sets up the examples tool + bars. The three \l{QToolButton}s in the \c colorToolBar, the \c + fontColorToolButton, \c fillColorToolButton, and \c + lineColorToolButton, are interesting as we create icons for them + by drawing on a QPixmap with a QPainter. We show how the \c + fillColorToolButton is created. This button lets the user select a + color for the diagram items. + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 25 + \dots + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 26 + + We set the menu of the tool button with + \l{QToolButton::}{setMenu()}. We need the \c fillAction QAction + object to always be pointing to the selected action of the menu. + The menu is created with the \c createColorMenu() function and, as + we shall see later, contains one menu item for each color that the + items can have. When the user presses the button, which trigger + the \l{QToolButton::}{clicked()} signal, we can set the color of + the selected item to the color of \c fillAction. It is with \c + createColorToolButtonIcon() we create the icon for the button. + + \dots + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 27 + + Here is the \c createBackgroundCellWidget() function: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 28 + + This function creates \l{QWidget}s containing a tool button + and a label. The widgets created with this function are used for + the background tabbed widget item in the tool box. + + Here is the \c createCellWidget() function: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 29 + + This function returns a QWidget containing a QToolButton with + an image of one of the \c DiagramItems, i.e., flowchart shapes. + The image is created by the \c DiagramItem through the \c image() + function. The QButtonGroup class lets us attach a QVariant with + each button; we store the diagram's type, i.e., the + DiagramItem::DiagramType enum. We use the stored diagram type when + we create new diagram items for the scene. The widgets created + with this function is used in the tool box. + + Here is the \c createColorMenu() function: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 30 + + This function creates a color menu that is used as the + drop-down menu for the tool buttons in the \c colorToolBar. We + create an action for each color that we add to the menu. We fetch + the actions data when we set the color of items, lines, and text. + + Here is the \c createColorToolButtonIcon() function: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 31 + + This function is used to create the QIcon of the \c + fillColorToolButton, \c fontColorToolButton, and \c + lineColorToolButton. The \a imageFile string is either the text, + flood-fill, or line symbol that is used for the buttons. Beneath + the image we draw a filled rectangle using \a color. + + Here is the \c createColorIcon() function: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 32 + + This function creates an icon with a filled rectangle in the + color of \a color. It is used for creating icons for the color + menus in the \c fillColorToolButton, \c fontColorToolButton, and + \c lineColorToolButton. + + Here is the \c backgroundButtonGroupClicked() slot: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 1 + + In this function we set the QBrush that is used to draw the + background of the diagramscene. The background can be a grid of + squares of blue, gray, or white tiles, or no grid at all. We have + \l{QPixmap}s of the tiles from png files that we create the brush + with. + + When one of the buttons in the background tabbed widget item is + clicked we change the brush; we find out which button it is by + checking its text. + + Here is the implementation of \c buttonGroupClicked(): + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 2 + + This slot is called when a button in \c buttonGroup is checked. + When a button is checked the user can click on the graphics view + and a \c DiagramItem of the selected type will be inserted into + the \c DiagramScene. We must loop through the buttons in the group + to uncheck other buttons as only one button is allowed to be + checked at a time. + + \c QButtonGroup assigns an id to each button. We have set the id + of each button to the diagram type, as given by DiagramItem::DiagramType + that will be inserted into the scene when it is clicked. We can + then use the button id when we set the diagram type with + \c setItemType(). In the case of text we assigned an id that has a + value that is not in the DiagramType enum. + + Here is the implementation of \c deleteItem(): + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 3 + + This slot deletes the selected item, if any, from the scene. If + the item to be deleted is a \c DiagramItem, we also need to delete + arrows connected to it; we don't want arrows in the scene that + aren't connected to items in both ends. + + This is the implementation of pointerGroupClicked(): + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 4 + + The \c pointerTypeGroup decides whether the scene is in ItemMove + or InsertLine mode. This button group is exclusive, i.e., only + one button is checked at any time. As with the \c buttonGroup above + we have assigned an id to the buttons that matches values of the + DiagramScene::Mode enum, so that we can use the id to set the + correct mode. + + Here is the \c bringToFront() slot: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 5 + + Several items may collide, i.e., overlap, with each other in + the scene. This slot is called when the user requests that an + item should be placed on top of the items it collides with. + \l{QGraphicsItem}{QGrapicsItems} have a z-value that decides the + order in which items are stacked in the scene; you can think of it + as the z-axis in a 3D coordinate system. When items collide the + items with higher z-values will be drawn on top of items with + lower values. When we bring an item to the front we can loop + through the items it collides with and set a z-value that is + higher than all of them. + + Here is the \c sendToBack() slot: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 6 + + This slot works in the same way as \c bringToFront() described + above, but sets a z-value that is lower than items the item that + should be send to the back collides with. + + This is the implementation of \c itemInserted(): + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 7 + + This slot is called from the \c DiagramScene when an item has been + added to the scene. We set the mode of the scene back to the mode + before the item was inserted, which is ItemMove or InsertText + depending on which button is checked in the \c pointerTypeGroup. + We must also uncheck the button in the in the \c buttonGroup. + + Here is the implementation of \c textInserted(): + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 8 + + We simply set the mode of the scene back to the mode it had before + the text was inserted. + + Here is the \c currentFontChanged() slot: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 9 + + When the user requests a font change, by using one of the + widgets in the \c fontToolBar, we create a new QFont object and + set its properties to match the state of the widgets. This is done + in \c handleFontChange(), so we simply call that slot. + + Here is the \c fontSizeChanged() slot: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 10 + + When the user requests a font change, by using one of the + widgets in the \c fontToolBar, we create a new QFont object and + set its properties to match the state of the widgets. This is done + in \c handleFontChange(), so we simply call that slot. + + Here is the implementation of \c sceneScaleChanged(): + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 11 + + The user can increase or decrease the scale, with the \c + sceneScaleCombo, the scene is drawn in. + It is not the scene itself that changes its scale, but only the + view. + + Here is the \c textColorChanged() slot: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 12 + + This slot is called when an item in the drop-down menu of the \c + fontColorToolButton is pressed. We need to change the icon on + the button to the color of the selected QAction. We keep a pointer + to the selected action in \c textAction. It is in \c + textButtonTriggered() we change the text color to the color of \c + textAction, so we call that slot. + + Here is the \c itemColorChanged() implementation: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 13 + + This slot handles requests for changing the color of \c + DiagramItems in the same manner as \c textColorChanged() does for + \c DiagramTextItems. + + Here is the implementation of \c lineColorChanged(): + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 14 + + This slot handles requests for changing the color of \c Arrows in + the same manner that \c textColorChanged() does it for \c + DiagramTextItems. + + Here is the \c textButtonTriggered() slot: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 15 + + \c textAction points to the QAction of the currently selected menu item + in the \c fontColorToolButton's color drop-down menu. We have set + the data of the action to the QColor the action represents, so we + can simply fetch this when we set the color of text with \c + setTextColor(). + + Here is the \c fillButtonTriggered() slot: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 16 + + \c fillAction points to the selected menu item in the drop-down + menu of \c fillColorToolButton(). We can therefore use the data of + this action when we set the item color with \c setItemColor(). + + Here is the \c lineButtonTriggered() slot: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 17 + + \c lineAction point to the selected item in the drop-down menu of + \c lineColorToolButton. We use its data when we set the arrow + color with \c setLineColor(). + + Here is the \c handleFontChange() function: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 18 + + \c handleFontChange() is called when any of the widgets that show + font properties changes. We create a new QFont object and set its + properties based on the widgets. We then call the \c setFont() + function of \c DiagramScene; it is the scene that set the font of + the \c DiagramTextItems it manages. + + Here is the \c itemSelected() slot: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 19 + + This slot is called when an item in the \c DiagramScene is + selected. In the case of this example it is only text items that + emit signals when they are selected, so we do not need to check + what kind of graphics \a item is. + + We set the state of the widgets to match the properties of the + font of the selected text item. + + This is the \c about() slot: + + \snippet examples/graphicsview/diagramscene/mainwindow.cpp 20 + + This slot displays an about box for the example when the user + selects the about menu item from the help menu. + + \section1 DiagramScene Class Definition + + The \c DiagramScene class inherits QGraphicsScene and adds + functionality to handle \c DiagramItems, \c Arrows, and \c + DiagramTextItems in addition to the items handled by its super + class. + + + \snippet examples/graphicsview/diagramscene/diagramscene.h 0 + + In the \c DiagramScene a mouse click can give three different + actions: the item under the mouse can be moved, an item may be + inserted, or an arrow may be connected between to diagram items. + Which action a mouse click has depends on the mode, given by the + Mode enum, the scene is in. The mode is set with the \c setMode() + function. + + The scene also sets the color of its items and the font of its + text items. The colors and font used by the scene can be set with + the \c setLineColor(), \c setTextColor(), \c setItemColor() and \c + setFont() functions. The type of \c DiagramItem, given by the + DiagramItem::DiagramType function, to be created when an item is + inserted is set with the \c setItemType() slot. + + The \c MainWindow and \c DiagramScene share responsibility for + the examples functionality. \c MainWindow handles the following + tasks: the deletion of items, text, and arrows; moving diagram + items to the back and front; and setting the scale of the scene. + + \section1 DiagramScene Class Implementation + + + We start with the constructor: + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 0 + + The scene uses \c myItemMenu to set the context menu when it + creates \c DiagramItems. We set the default mode to \c + DiagramScene::MoveItem as this gives the default behavior of + QGraphicsScene. + + Here is the \c setLineColor() function: + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 1 + + The \c isItemChange function returns true if an \c Arrow item is + selected in the scene in which case we want to change its color. + When the \c DiagramScene creates and adds new arrows to the scene + it will also use the new \a color. + + Here is the \c setTextColor() function: + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 2 + + This function sets the color of \c DiagramTextItems equal to the + way \c setLineColor() sets the color of \c Arrows. + + Here is the \c setItemColor() function: + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 3 + + This function sets the color the scene will use when creating + \c DiagramItems. It also changes the color of a selected \c + DiagramItem. + + This is the implementation of \c setFont(): + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 4 + + Set the font to use for new and selected, if a text item is + selected, \c DiagramTextItems. + + This is the implementation of \c editorLostFocus() slot: + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 5 + + \c DiagramTextItems emit a signal when they loose focus, which is + connected to this slot. We remove the item if it has no text. + If not, we would leak memory and confuse the user as the items + will be edited when pressed on by the mouse. + + The \c mousePressEvent() function handles mouse press event's + different depending on which mode the \c DiagramScene is in. We + examine its implementation for each mode: + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 6 + + We simply create a new \c DiagramItem and add it to the scene at + the position the mouse was pressed. Note that the origin of its + local coordinate system will be under the mouse pointer position. + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 7 + + The user adds \c Arrows to the scene by stretching a line between + the items the arrow should connect. The start of the line is fixed + in the place the user clicked the mouse and the end follows the + mouse pointer as long as the button is held down. When the user + releases the mouse button an \c Arrow will be added to the scene + if there is a \c DiagramItem under the start and end of the line. + We will see how this is implemented later; here we simply add the + line. + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 8 + + The \c DiagramTextItem is editable when the + Qt::TextEditorInteraction flag is set, else it is movable by the + mouse. We always want the text to be drawn on top of the other + items in the scene, so we set the value to a number higher + than other items in the scene. + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 9 + + We are in MoveItem mode if we get to the default switch; we + can then call the QGraphicsScene implementation, which + handles movement of items with the mouse. We make this call even + if we are in another mode making it possible to add an item and + then keep the mouse button pressed down and start moving + the item. In the case of text items, this is not possible as they + do not propagate mouse events when they are editable. + + This is the \c mouseMoveEvent() function: + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 10 + + We must draw the line if we are in InsertMode and the mouse button + is pressed down (the line is not 0). As discussed in \c + mousePressEvent() the line is drawn from the position the mouse + was pressed to the current position of the mouse. + + If we are in MoveItem mode, we call the QGraphicsScene + implementation, which handles movement of items. + + In the \c mouseReleaseEvent() function we need to check if an arrow + should be added to the scene: + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 11 + + First we need to get the items (if any) under the line's start + and end points. The line itself is the first item at these points, + so we remove it from the lists. As a precaution, we check if the + lists are empty, but this should never happen. + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 12 + + Now we check if there are two different \c DiagramItems under + the lines start and end points. If there are we can create an \c + Arrow with the two items. The arrow is then added to each item and + finally the scene. The arrow must be updated to adjust its start + and end points to the items. We set the z-value of the arrow to + -1000.0 because we always want it to be drawn under the items. + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 13 + + Here is the \c isItemChange() function: + + \snippet examples/graphicsview/diagramscene/diagramscene.cpp 14 + + The scene has single selection, i.e., only one item can be + selected at any given time. The foreach will then loop one time + with the selected item or none if no item is selected. \c + isItemChange() is used to check whether a selected item exists + and also is of the specified diagram \a type. + + \section1 DiagramItem Class Definition + + + \snippet examples/graphicsview/diagramscene/diagramitem.h 0 + + The \c DiagramItem represents a flowchart shape in the \c + DiagramScene. It inherits QGraphicsPolygonItem and has a polygon + for each shape. The enum DiagramType has a value for each of the + flowchart shapes. + + The class has a list of the arrows that are connected to it. + This is necessary because only the item knows when it is being + moved (with the \c itemChanged() function) at which time the + arrows must be updated. The item can also draw itself onto a + QPixmap with the \c image() function. This is used for the tool + buttons in \c MainWindow, see \c createColorToolButtonIcon() in + \c MainWindow. + + The Type enum is a unique identifier of the class. It is used by + \c qgraphicsitem_cast(), which does dynamic casts of graphics + items. The UserType constant is the minimum value a custom + graphics item type can be. + + \section1 DiagramItem Class Implementation + + + We start with a look at the constructor: + + \snippet examples/graphicsview/diagramscene/diagramitem.cpp 0 + + In the constructor we create the items polygon according to + \a diagramType. \l{QGraphicsItem}s are not movable or selectable + by default, so we must set these properties. + + Here is the \c removeArrow() function: + + \snippet examples/graphicsview/diagramscene/diagramitem.cpp 1 + + \c removeArrow() is used to remove \c Arrow items when they + or \c DiagramItems they are connected to are removed from the + scene. + + Here is the \c removeArrows() function: + + \snippet examples/graphicsview/diagramscene/diagramitem.cpp 2 + + This function is called when the item is removed from the scene + and removes all arrows that are connected to this item. The arrow + must be removed from the \c arrows list of both its start and end + item. + + Here is the \c addArrow() function: + + \snippet examples/graphicsview/diagramscene/diagramitem.cpp 3 + + This function simply adds the \a arrow to the items \c arrows list. + + Here is the \c image() function: + + \snippet examples/graphicsview/diagramscene/diagramitem.cpp 4 + + This function draws the polygon of the item onto a QPixmap. In + this example we use this to create icons for the tool buttons in + the tool box. + + Here is the \c contextMenuEvent() function: + + \snippet examples/graphicsview/diagramscene/diagramitem.cpp 5 + + We show the context menu. As right mouse clicks, which shows the + menu, don't select items by default we set the item selected with + \l{QGraphicsItem::}{setSelected()}. This is necessary since an + item must be selected to change its elevation with the + \c bringToFront and \c sendToBack actions. + + This is the implementation of \c itemChange(): + + \snippet examples/graphicsview/diagramscene/diagramitem.cpp 6 + + If the item has moved, we need to update the positions of the + arrows connected to it. The implementation of QGraphicsItem does + nothing, so we just return \a value. + + \section1 DiagramTextItem Class Definition + + The \c TextDiagramItem class inherits QGraphicsTextItem and + adds the possibility to move editable text items. Editable + QGraphicsTextItems are designed to be fixed in place and editing + starts when the user single clicks on the item. With \c + DiagramTextItem the editing starts with a double click leaving + single click available to interact with and move it. + + \snippet examples/graphicsview/diagramscene/diagramtextitem.h 0 + + We use \c itemChange() and \c focusOutEvent() to notify the + \c DiagramScene when the text item loses focus and gets selected. + + Vi reimplement the functions that handle mouse events to make it + possible to alter the mouse behavior of QGraphicsTextItem. + + \section1 DiagramTextItem Implementation + + We start with the constructor: + + \snippet examples/graphicsview/diagramscene/diagramtextitem.cpp 0 + + We simply set the item movable and selectable, as these flags are + off by default. + + Here is the \c itemChange() function: + + \snippet examples/graphicsview/diagramscene/diagramtextitem.cpp 1 + + When the item is selected we emit the selectedChanged signal. The + \c MainWindow uses this signal to update the widgets that display + font properties to the font of the selected text item. + + Here is the \c focusOutEvent() function: + + \snippet examples/graphicsview/diagramscene/diagramtextitem.cpp 2 + + \c DiagramScene uses the signal emitted when the text item looses + remove the item if it is empty, i.e., it contains no text. + + This is the implementation of \c mouseDoubleClickEvent(): + + \snippet examples/graphicsview/diagramscene/diagramtextitem.cpp 5 + + When we receive a double click event, we make the item editable by calling + QGraphicsTextItem::setTextInteractionFlags(). We then forward the + double-click to the item itself. + + \section1 Arrow Class Definition + + The \c Arrow class is a graphics item that connects two \c + DiagramItems. It draws an arrow head to one of the items. To + achieve this the item needs to paint itself and also re implement + methods used by the graphics scene to check for collisions and + selections. The class inherits QGraphicsLine item, and draws the + arrowhead and moves with the items it connects. + + \snippet examples/graphicsview/diagramscene/arrow.h 0 + + The item's color can be set with \c setColor(). + + \c boundingRect() and \c shape() are reimplemented + from QGraphicsLineItem and are used by the scene + to check for collisions and selections. + + Calling \c updatePosition() causes the arrow to recalculate its + position and arrow head angle. \c paint() is reimplemented so that + we can paint an arrow rather than just a line between items. + + \c myStartItem and \c myEndItem are the diagram items that the + arrow connects. The arrow is drawn with its head to the end item. + \c arrowHead is a polygon with three vertices's we use to draw the + arrow head. + + \section1 Arrow Class Implementation + + The constructor of the \c Arrow class looks like this: + + \snippet examples/graphicsview/diagramscene/arrow.cpp 0 + + We set the start and end diagram items of the arrow. The arrow + head will be drawn where the line intersects the end item. + + Here is the \c boundingRect() function: + + \snippet examples/graphicsview/diagramscene/arrow.cpp 1 + + We need to reimplement this function because the arrow is + larger than the bounding rectangle of the QGraphicsLineItem. The + graphics scene uses the bounding rectangle to know which regions + of the scene to update. + + Here is the \c shape() function: + + \snippet examples/graphicsview/diagramscene/arrow.cpp 2 + + The shape function returns a QPainterPath that is the exact + shape of the item. The QGraphicsLineItem::shape() returns a path + with a line drawn with the current pen, so we only need to add + the arrow head. This function is used to check for collisions and + selections with the mouse. + + Here is the \c updatePosition() slot: + + \snippet examples/graphicsview/diagramscene/arrow.cpp 3 + + This slot updates the arrow by setting the start and end + points of its line to the center of the items it connects. + + Here is the \c paint() function: + + \snippet examples/graphicsview/diagramscene/arrow.cpp 4 + + If the start and end items collide we do not draw the arrow; the + algorithm we use to find the point the arrow should be drawn at + may fail if the items collide. + + We first set the pen and brush we will use for drawing the arrow. + + \snippet examples/graphicsview/diagramscene/arrow.cpp 5 + + We then need to find the position at which to draw the + arrowhead. The head should be drawn where the line and the end + item intersects. This is done by taking the line between each + point in the polygon and check if it intersects with the line of + the arrow. Since the line start and end points are set to the + center of the items the arrow line should intersect one and only + one of the lines of the polygon. Note that the points in the + polygon are relative to the local coordinate system of the item. + We must therefore add the position of the end item to make the + coordinates relative to the scene. + + \snippet examples/graphicsview/diagramscene/arrow.cpp 6 + + We calculate the angle between the x-axis and the line of the + arrow. We need to turn the arrow head to this angle so that it + follows the direction of the arrow. If the angle is negative we + must turn the direction of the arrow. + + We can then calculate the three points of the arrow head polygon. + One of the points is the end of the line, which now is the + intersection between the arrow line and the end polygon. Then we + clear the \c arrowHead polygon from the previous calculated arrow + head and set these new points. + + \snippet examples/graphicsview/diagramscene/arrow.cpp 7 + + If the line is selected we draw to dotted lines that are + parallel with the line of the arrow. We do not use the default + implementation, which uses \l{QGraphicsItem::}{boundingRect()} + because the QRect bounding rectangle is considerably larger than + the line. +*/ diff --git a/doc/src/examples/digitalclock.qdoc b/doc/src/examples/digitalclock.qdoc new file mode 100644 index 0000000..0ff4642 --- /dev/null +++ b/doc/src/examples/digitalclock.qdoc @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/digitalclock + \title Digital Clock Example + + The Digital Clock example shows how to use QLCDNumber to display a + number with LCD-like digits. + + \image digitalclock-example.png Screenshot of the Digital Clock example + + This example also demonstrates how QTimer can be used to update a widget + at regular intervals. + + \section1 DigitalClock Class Definition + + The \c DigitalClock class provides a clock widget showing the time with + hours and minutes separated by a blinking colon. We subclass QLCDNumber + and implement a private slot called \c showTime() to update the clock + display: + + \snippet examples/widgets/digitalclock/digitalclock.h 0 + + \section1 DigitalClock Class Implementation + + \snippet examples/widgets/digitalclock/digitalclock.cpp 0 + + In the constructor, we first change the look of the LCD numbers. The + QLCDNumber::Filled style produces raised segments filled with the + foreground color (typically black). We also set up a one-second timer + to keep track of the current time, and we connect + its \l{QTimer::timeout()}{timeout()} signal to the private \c showTime() slot + so that the display is updated every second. Then, we + call the \c showTime() slot; without this call, there would be a one-second + delay at startup before the time is shown. + + \snippet examples/widgets/digitalclock/digitalclock.cpp 1 + \snippet examples/widgets/digitalclock/digitalclock.cpp 2 + + The \c showTime() slot is called whenever the clock display needs + to be updated. + + The current time is converted into a string with the format "hh:mm". + When QTime::second() is a even number, the colon in the string is + replaced with a space. This makes the colon appear and vanish every + other second. + + Finally, we call QLCDNumber::display() to update the widget. +*/ diff --git a/doc/src/examples/dirview.qdoc b/doc/src/examples/dirview.qdoc new file mode 100644 index 0000000..2cbfcfe --- /dev/null +++ b/doc/src/examples/dirview.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/dirview + \title Dir View Example + + The Dir View example shows a tree view onto the local filing system. It uses the + QDirModel class to provide supply file and directory information. + + \image dirview-example.png +*/ diff --git a/doc/src/examples/dockwidgets.qdoc b/doc/src/examples/dockwidgets.qdoc new file mode 100644 index 0000000..bc9f5f1 --- /dev/null +++ b/doc/src/examples/dockwidgets.qdoc @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example mainwindows/dockwidgets + \title Dock Widgets Example + + The Dock Widgets example shows how to add dock windows to an + application. It also shows how to use Qt's rich text engine. + + \image dockwidgets-example.png Screenshot of the Dock Widgets example + + The application presents a simple business letter template, and has + a list of customer names and addresses and a list of standard + phrases in two dock windows. The user can click a customer to have + their name and address inserted into the template, and click one or + more of the standard phrases. Errors can be corrected by clicking + the Undo button. Once the letter has been prepared it can be printed + or saved as HTML. + + \section1 MainWindow Class Definition + + Here's the class definition: + + \snippet examples/mainwindows/dockwidgets/mainwindow.h 0 + + We will now review each function in turn. + + \section1 MainWindow Class Implementation + + \snippet examples/mainwindows/dockwidgets/mainwindow.cpp 0 + + We start by including \c <QtGui>, a header file that contains the + definition of all classes in the \l QtCore and \l QtGui + libraries. This saves us from having to include + every class individually and is especially convenient if we add new + widgets. We also include \c mainwindow.h. + + \snippet examples/mainwindows/dockwidgets/mainwindow.cpp 1 + + In the constructor, we start by creating a QTextEdit widget. Then we call + QMainWindow::setCentralWidget(). This function passes ownership of + the QTextEdit to the \c MainWindow and tells the \c MainWindow that + the QTextEdit will occupy the \c MainWindow's central area. + + Then we call \c createActions(), \c createMenus(), \c + createToolBars(), \c createStatusBar(), and \c createDockWindows() + to set up the user interface. Finally we call \c setWindowTitle() to + give the application a title, and \c newLetter() to create a new + letter template. + + We won't quote the \c createActions(), \c createMenus(), \c + createToolBars(), and \c createStatusBar() functions since they + follow the same pattern as all the other Qt examples. + + \snippet examples/mainwindows/dockwidgets/mainwindow.cpp 9 + + We create the customers dock window first, and in addition to a + window title, we also pass it a \c this pointer so that it becomes a + child of \c MainWindow. Normally we don't have to pass a parent + because widgets are parented automatically when they are laid out: + but dock windows aren't laid out using layouts. + + We've chosen to restrict the customers dock window to the left and + right dock areas. (So the user cannot drag the dock window to the + top or bottom dock areas.) The user can drag the dock window out of + the dock areas entirely so that it becomes a free floating window. + We can change this (and whether the dock window is moveable or + closable) using QDockWidget::setFeatures(). + + Once we've created the dock window we create a list widget with the + dock window as parent, then we populate the list and make it the + dock window's widget. Finally we add the dock widget to the \c + MainWindow using \c addDockWidget(), choosing to put it in the right + dock area. + + We undertake a similar process for the paragraphs dock window, + except that we don't restrict which dock areas it can be dragged to. + + Finally we set up the signal-slot connections. If the user clicks a + customer or a paragraph their \c currentTextChanged() signal will be + emitted and we connect these to \c insertCustomer() and + addParagraph() passing the text that was clicked. + + We briefly discuss the rest of the implementation, but have now + covered everything relating to dock windows. + + \snippet examples/mainwindows/dockwidgets/mainwindow.cpp 2 + + In this function we clear the QTextEdit so that it is empty. Next we + create a QTextCursor on the QTextEdit. We move the cursor to the + start of the document and create and format a frame. We then create + some character formats and a table format. We insert a table into + the document and insert the company's name and address into a table + using the table and character formats we created earlier. Then we + insert the skeleton of the letter including two markers \c NAME and + \c ADDRESS. We will also use the \c{Yours sincerely,} text as a marker. + + \snippet examples/mainwindows/dockwidgets/mainwindow.cpp 6 + + If the user clicks a customer we split the customer details into + pieces. We then look for the \c NAME marker using the \c find() + function. This function selects the text it finds, so when we call + \c insertText() with the customer's name the name replaces the marker. + We then look for the \c ADDRESS marker and replace it with each line + of the customer's address. Notice that we wrapped all the insertions + between a \c beginEditBlock() and \c endEditBlock() pair. This means + that the entire name and address insertion is treated as a single + operation by the QTextEdit, so a single undo will revert all the + insertions. + + \snippet examples/mainwindows/dockwidgets/mainwindow.cpp 7 + + This function works in a similar way to \c insertCustomer(). First + we look for the marker, in this case, \c {Yours sincerely,}, and then + replace it with the standard paragraph that the user clicked. Again + we use a \c beginEditBlock() ... \c endEditBlock() pair so that the + insertion can be undone as a single operation. + + \snippet examples/mainwindows/dockwidgets/mainwindow.cpp 3 + + Qt's QTextDocument class makes printing documents easy. We simply + take the QTextEdit's QTextDocument, set up the printer and print the + document. + + \snippet examples/mainwindows/dockwidgets/mainwindow.cpp 4 + + QTextEdit can output its contents in HTML format, so we prompt the + user for the name of an HTML file and if they provide one we simply + write the QTextEdit's contents in HTML format to the file. + + \snippet examples/mainwindows/dockwidgets/mainwindow.cpp 5 + + If the focus is in the QTextEdit, pressing \key Ctrl+Z undoes as + expected. But for the user's convenience we provide an + application-wide undo function that simply calls the QTextEdit's + undo: this means that the user can undo regardless of where the + focus is in the application. +*/ diff --git a/doc/src/examples/dombookmarks.qdoc b/doc/src/examples/dombookmarks.qdoc new file mode 100644 index 0000000..f3944ef --- /dev/null +++ b/doc/src/examples/dombookmarks.qdoc @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xml/dombookmarks + \title DOM Bookmarks Example + + The DOM Bookmarks example provides a reader for XML Bookmark Exchange Language (XBEL) + files that uses Qt's DOM-based XML API to read and parse the files. The SAX Bookmarks + example provides an alternative way to read this type of file. + + \image dombookmarks-example.png + + See the \l{http://pyxml.sourceforge.net/topics/xbel/}{XML Bookmark Exchange Language + Resource Page} for more information about XBEL files. +*/ diff --git a/doc/src/examples/draganddroppuzzle.qdoc b/doc/src/examples/draganddroppuzzle.qdoc new file mode 100644 index 0000000..0e6ed09 --- /dev/null +++ b/doc/src/examples/draganddroppuzzle.qdoc @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example draganddrop/puzzle + \title Drag and Drop Puzzle Example + + The Drag and Drop Puzzle example demonstrates a way of using the drag and drop system with + item view widgets. + + \image draganddroppuzzle-example.png + + This example is an implementation of a simple jigsaw puzzle game using Qt's + drag and drop API. + The \l{Item Views Puzzle Example}{Item View Puzzle} example shows + many of the same features, but takes an alternative approach that uses Qt's + model/view framework to manage drag and drop operations. +*/ diff --git a/doc/src/examples/dragdroprobot.qdoc b/doc/src/examples/dragdroprobot.qdoc new file mode 100644 index 0000000..d3f97b0 --- /dev/null +++ b/doc/src/examples/dragdroprobot.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example graphicsview/dragdroprobot + \title Drag and Drop Robot Example + + This GraphicsView example shows how to implement drag and drop in + a QGraphicsItem subclass, as well as how to animate items using + QGraphicsItemAnimation and QTimeLine. + + \image dragdroprobot-example.png +*/ diff --git a/doc/src/examples/draggableicons.qdoc b/doc/src/examples/draggableicons.qdoc new file mode 100644 index 0000000..23150f9 --- /dev/null +++ b/doc/src/examples/draggableicons.qdoc @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example draganddrop/draggableicons + \title Draggable Icons Example + + The Draggable Icons example shows how to drag and drop image data between widgets + in the same application, and between different applications. + + \image draggableicons-example.png + + In many situations where drag and drop is used, the user starts dragging from + a particular widget and drops the payload onto another widget. In this example, + we subclass QLabel to create labels that we use as drag sources, and place them + inside \l{QWidget}s that serve as both containers and drop sites. + + In addition, when a drag and drop operation occurs, we want to send more than + just an image. We also want to send information about where the user clicked in + the image so that the user can place it precisely on the drop target. This level + of detail means that we must create a custom MIME type for our data. + + \section1 DragWidget Class Definition + + The icon widgets that we use to display icons are subclassed from QLabel: + + \snippet examples/draganddrop/draggableicons/dragwidget.h 0 + + Since the QLabel class provides most of what we require for the icon, we + only need to reimplement the \l QWidget::mousePressEvent() to provide + drag and drop facilities. + + \section1 DragWidget Class Implementation + + The \c DragWidget constructor sets an attribute on the widget that ensures + that it will be deleted when it is closed: + + \snippet examples/draganddrop/draggableicons/dragwidget.cpp 0 + + To enable dragging from the icon, we need to act on a mouse press event. + We do this by reimplementing \l QWidget::mousePressEvent() and setting up + a QDrag object. + + \snippet examples/draganddrop/draggableicons/dragwidget.cpp 1 + + Since we will be sending pixmap data for the icon and information about the + user's click in the icon widget, we construct a QByteArray and package up the + details using a QDataStream. + + For interoperability, drag and drop operations describe the data they contain + using MIME types. In Qt, we describe this data using a QMimeData object: + + \snippet examples/draganddrop/draggableicons/dragwidget.cpp 2 + + We choose an unofficial MIME type for this purpose, and supply the QByteArray + to the MIME data object. + + The drag and drop operation itself is handled by a QDrag object: + + \snippet examples/draganddrop/draggableicons/dragwidget.cpp 3 + + Here, we pass the data to the drag object, set a pixmap that will be shown + alongside the cursor during the operation, and define the position of a hot + spot that places the position of this pixmap under the cursor. + +*/ diff --git a/doc/src/examples/draggabletext.qdoc b/doc/src/examples/draggabletext.qdoc new file mode 100644 index 0000000..4d3d89d --- /dev/null +++ b/doc/src/examples/draggabletext.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example draganddrop/draggabletext + \title Draggable Text Example + + The Draggable Text example shows how to drag and drop textual data between widgets + in the same application, and between different applications. + + \image draggabletext-example.png +*/ diff --git a/doc/src/examples/drilldown.qdoc b/doc/src/examples/drilldown.qdoc new file mode 100644 index 0000000..344b9e7 --- /dev/null +++ b/doc/src/examples/drilldown.qdoc @@ -0,0 +1,552 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example sql/drilldown + \title Drill Down Example + + The Drill Down example shows how to read data from a database as + well as submit changes, using the QSqlRelationalTableModel and + QDataWidgetMapper classes. + + \image drilldown-example.png Screenshot of the Drill Down Example + + When running the example application, a user can retrieve + information about each of Nokia's Qt Software offices by clicking the + corresponding image. The application pops up an information window + displaying the data, and allows the users to alter the location + description as well as the image. The main view will be updated + when the users submit their changes. + + The example consists of three classes: + + \list + \o \c ImageItem is a custom graphics item class used to + display the office images. + + \o \c View is the main application widget allowing the user to + browse through the various locations. + + \o \c InformationWindow displays the requested information, + allowing the users to alter it and submit their changes to the + database. + \endlist + + We will first take a look at the \c InformationWindow class to see + how you can read and modify data from a database. Then we will + review the main application widget, i.e., the \c View class, and + the associated \c ImageItem class. + + \section1 InformationWindow Class Definition + + The \c InformationWindow class is a custom widget inheriting + QWidget: + + \snippet examples/sql/drilldown/informationwindow.h 0 + + When we create an information window, we pass the associated + location ID, a parent, and a pointer to the database, to the + constructor. We will use the database pointer to populate our + window with data, while passing the parent parameter on to the + base class. The ID is stored for future reference. + + Once a window is created, we will use the public \c id() function + to locate it whenever information for the given location is + requested. We will also use the ID to update the main application + widget when the users submit their changes to the database, i.e., + we will emit a signal carrying the ID and file name as parameters + whenever the users changes the associated image. + + \snippet examples/sql/drilldown/informationwindow.h 1 + + Since we allow the users to alter some of the location data, we + must provide functionality for reverting and submitting their + changes. The \c enableButtons() slot is provided for convenience + to enable and disable the various buttons when required. + + \snippet examples/sql/drilldown/informationwindow.h 2 + + The \c createButtons() function is also a convenience function, + provided to simplify the constructor. As mentioned above we store + the location ID for future reference. We also store the name of + the currently displayed image file to be able to determine when to + emit the \c imageChanged() signal. + + The information window uses the QLabel class to display the office + location and the country. The associated image file is displayed + using a QComboBox instance while the description is displayed using + QTextEdit. In addition, the window has three buttons to control + the data flow and whether the window is shown or not. + + Finally, we declare a \e mapper. The QDataWidgetMapper class + provides mapping between a section of a data model to widgets. We + will use the mapper to extract data from the given database, + updating the database whenever the user modifies the data. + + \section1 InformationWindow Class Implementation + + The constructor takes three arguments: a location ID, a database + pointer and a parent widget. The database pointer is actually a + pointer to a QSqlRelationalTableModel object providing an editable + data model (with foreign key support) for our database table. + + \snippet examples/sql/drilldown/informationwindow.cpp 0 + \snippet examples/sql/drilldown/informationwindow.cpp 1 + + First we create the various widgets required to display the data + contained in the database. Most of the widgets are created in a + straight forward manner. But note the combobox displaying the + name of the image file: + + \snippet examples/sql/drilldown/informationwindow.cpp 2 + + In this example, the information about the offices are stored in a + database table called "offices". When creating the model, + we will use a foreign key to establish a relation between this + table and a second data base table, "images", containing the names + of the available image files. We will get back to how this is done + when reviewing the \c View class. The rationale for creating such + a relation though, is that we want to ensure that the user only + can choose between predefined image files. + + The model corresponding to the "images" database table, is + available through the QSqlRelationalTableModel's \l + {QSqlRelationalTableModel::}{relationModel()} function, requiring + the foreign key (in this case the "imagefile" column number) as + argument. We use QComboBox's \l {QComboBox::}{setModel()} function + to make the combobox use the "images" model. And, since this model + has two columns ("locationid" and "file"), we also specify which + column we want to be visible using the QComboBox::setModelColumn() + function. + + \snippet examples/sql/drilldown/informationwindow.cpp 3 + + Then we create the mapper. The QDataWidgetMapper class allows us + to create data-aware widgets by mapping them to sections of an + item model. + + The \l {QDataWidgetMapper::}{addMapping()} function adds a mapping + between the given widget and the specified section of the + model. If the mapper's orientation is horizontal (the default) the + section is a column in the model, otherwise it is a row. We call + the \l {QDataWidgetMapper::}{setCurrentIndex()} function to + initialize the widgets with the data associated with the given + location ID. Every time the current index changes, all the widgets + are updated with the contents from the model. + + We also set the mapper's submit policy to + QDataWidgetMapper::ManualSubmit. This means that no data is + submitted to the database until the user expliclity requests a + submit (the alternative is QDataWidgetMapper::AutoSubmit, + automatically submitting changes when the corresponding widget + looses focus). Finally, we specify the item delegate the mapper + view should use for its items. The QSqlRelationalDelegate class + represents a delegate that unlike the default delegate, enables + combobox functionality for fields that are foreign keys into other + tables (like "imagefile" in our "trolltechoffices" table). + + \snippet examples/sql/drilldown/informationwindow.cpp 4 + + Finally, we connect the "something's changed" signals in the + editors to our custom \c enableButtons() slot, enabling the users + to either submit or revert their changes. We add all the widgets + into a layout, store the location ID and the name of the displayed + image file for future reference, and set the window title and + initial size. + + Note that we also set the Qt::Window window flag to indicate that + our widget is in fact a window, with a window system frame and a + title bar. + + \snippet examples/sql/drilldown/informationwindow.cpp 5 + + When a window is created, it is not deleted until the main + application exits (i.e., if the user closes the information + window, it is only hidden). For this reason we do not want to + create more than one \c InformationWindow object for each + location, and we provide the public \c id() function to be able to + determine whether a window already exists for a given location + when the user requests information about it. + + \snippet examples/sql/drilldown/informationwindow.cpp 6 + + The \c revert() slot is triggered whenever the user hits the \gui + Revert button. + + Since we set the QDataWidgetMapper::ManualSubmit submit policy, + none of the user's changes are written back to the model unless + the user expliclity choose to submit all of them. Nevertheless, we + can use the QDataWidgetMapper's \l {QDataWidgetMapper::}{revert()} + slot to reset the editor widgets, repopulating all widgets with + the current data of the model. + + \snippet examples/sql/drilldown/informationwindow.cpp 7 + + Likewise, the \c submit() slot is triggered whenever the users + decide to submit their changes by pressing the \gui Submit button. + + We use QDataWidgetMapper's \l {QDataWidgetMapper::}{submit()} slot + to submit all changes from the mapped widgets to the model, + i.e. to the database. For every mapped section, the item delegate + will then read the current value from the widget and set it in the + model. Finally, the \e model's \l {QAbstractItemModel::}{submit()} + function is invoked to let the model know that it should submit + whatever it has cached to the permanent storage. + + Note that before any data is submitted, we check if the user has + chosen another image file using the previously stored \c + displayedImage variable as reference. If the current and stored + file names differ, we store the new file name and emit the \c + imageChanged() signal. + + \snippet examples/sql/drilldown/informationwindow.cpp 8 + + The \c createButtons() function is provided for convenience, i.e., + to simplify the constructor. + + We make the \gui Close button the default button, i.e., the button + that is pressed when the user presses \gui Enter, and connect its + \l {QPushButton::}{clicked()} signal to the widget's \l + {QWidget::}{close()} slot. As mentioned above closing the window + only hides the widget; it is not deleted. We also connect the \gui + Submit and \gui Revert buttons to the corresponding \c submit() + and \c revert() slots. + + \snippet examples/sql/drilldown/informationwindow.cpp 9 + + The QDialogButtonBox class is a widget that presents buttons in a + layout that is appropriate to the current widget style. Dialogs + like our information window, typically present buttons in a layout + that conforms to the interface guidelines for that + platform. Invariably, different platforms have different layouts + for their dialogs. QDialogButtonBox allows us to add buttons, + automatically using the appropriate layout for the user's desktop + environment. + + Most buttons for a dialog follow certain roles. We give the \gui + Submit and \gui Revert buttons the \l + {QDialogButtonBox::ButtonRole}{reset} role, i.e., indicating that + pressing the button resets the fields to the default values (in + our case the information contained in the database). The \l + {QDialogButtonBox::ButtonRole}{reject} role indicates that + clicking the button causes the dialog to be rejected. On the other + hand, since we only hide the information window, any changes that + the user has made wil be preserved until the user expliclity + revert or submit them. + + \snippet examples/sql/drilldown/informationwindow.cpp 10 + + The \c enableButtons() slot is called to enable the buttons + whenever the user changes the presented data. Likewise, when the + data the user choose to submit the changes, the buttons are + disabled to indicate that the current data is stored in the + database. + + This completes the \c InformationWindow class. Let's take a look + at how we have used it in our example application. + + \section1 View Class Definition + + The \c View class represents the main application window and + inherits QGraphicsView: + + \snippet examples/sql/drilldown/view.h 0 + \codeline + \snippet examples/sql/drilldown/view.h 1 + + The QGraphicsView class is part of the \l {The Graphics View + Framework} which we will use to display the images of Nokia's + Qt Software offices. To be able to respond to user interaction; + i.e., showing the + appropriate information window whenever the user clicks one of the + office images, we reimplement QGraphicsView's \l + {QGraphicsView::}{mouseReleaseEvent()} function. + + Note that the constructor expects the names of two database + tables: One containing the detailed information about the offices, + and another containing the names of the available image files. We + also provide a private \c updateImage() slot to catch \c + {InformationWindow}'s \c imageChanged() signal that is emitted + whenever the user changes a location's image. + + \snippet examples/sql/drilldown/view.h 2 + + The \c addItems() function is a convenience function provided to + simplify the constructor. It is called only once, creating the + various items and adding them to the view. + + The \c findWindow() function, on the other hand, is frequently + used. It is called from the \c showInformation() function to + detemine whether a window is already created for the given + location (whenever we create an \c InformationWindow object, we + store a reference to it in the \c informationWindows list). The + latter function is in turn called from our custom \c + mouseReleaseEvent() implementation. + + \snippet examples/sql/drilldown/view.h 3 + + Finally we declare a QSqlRelationalTableModel pointer. As + previously mentioned, the QSqlRelationalTableModel class provides + an editable data model with foreign key support. There are a + couple of things you should keep in mind when using the + QSqlRelationalTableModel class: The table must have a primary key + declared and this key cannot contain a relation to another table, + i.e., it cannot be a foreign key. Note also that if a relational + table contains keys that refer to non-existent rows in the + referenced table, the rows containing the invalid keys will not be + exposed through the model. It is the user's or the database's + responsibility to maintain referential integrity. + + \section1 View Class Implementation + + Although the constructor requests the names of both the table + containing office details as well as the table containing the + names of the available image files, we only have to create a + QSqlRelationalTableModel object for the office table: + + \snippet examples/sql/drilldown/view.cpp 0 + + The reason is that once we have a model with the office details, + we can create a relation to the available image files using + QSqlRelationalTableModel's \l + {QSqlRelationalTableModel::}{setRelation()} function. This + function creates a foreign key for the given model column. The key + is specified by the provided QSqlRelation object constructed by + the name of the table the key refers to, the field the key is + mapping to and the field that should be presented to the user. + + Note that setting the table only specifies which table the model + operates on, i.e., we must explicitly call the model's \l + {QSqlRelationalTableModel::}{select()} function to populate our + model. + + \snippet examples/sql/drilldown/view.cpp 1 + + Then we create the contents of our view, i.e., the scene and its + items. The location labels are regular QGraphicsTextItem objects, + and the "Qt" logo is represented by a QGraphicsPixmapItem + object. The images, on the other hand, are instances of the \c + ImageItem class (derived from QGraphicsPixmapItem). We will get + back to this shortly when reviewing the \c addItems() function. + + Finally, we set the main application widget's size constraints and + window title. + + \snippet examples/sql/drilldown/view.cpp 3 + + The \c addItems() function is called only once, i.e., when + creating the main application window. For each row in the database + table, we first extract the corresponding record using the model's + \l {QSqlRelationalTableModel::}{record()} function. The QSqlRecord + class encapsulates both the functionality and characteristics of a + database record, and supports adding and removing fields as well + as setting and retrieving field values. The QSqlRecord::value() + function returns the value of the field with the given name or + index as a QVariant object. + + For each record, we create a label item as well as an image item, + calculate their position and add them to the scene. The image + items are represented by instances of the \c ImageItem class. The + reason we must create a custom item class is that we want to catch + the item's hover events, animating the item when the mouse cursor + is hovering over the image (by default, no items accept hover + events). Please see the \l{The Graphics View Framework} + documentation and the + \l{Qt Examples#Graphics View}{Graphics View examples} for more + details. + + \snippet examples/sql/drilldown/view.cpp 5 + + We reimplement QGraphicsView's \l + {QGraphicsView::}{mouseReleaseEvent()} event handler to respond to + user interaction. If the user clicks any of the image items, this + function calls the private \c showInformation() function to pop up + the associated information window. + + \l {The Graphics View Framework} provides the qgraphicsitem_cast() + function to determine whether the given QGraphicsItem instance is + of a given type. Note that if the event is not related to any of + our image items, we pass it on to the base class implementation. + + \snippet examples/sql/drilldown/view.cpp 6 + + The \c showInformation() function is given an \c ImageItem object + as argument, and starts off by extracting the item's location + ID. Then it determines if there already is created an information + window for this location. If it is, and the window is visible, it + ensures that the window is raised to the top of the widget stack + and activated. If the window exists but is hidden, calling its \l + {QWidget::}{show()} slot gives the same result. + + If no window for the given location exists, we create one by + passing the location ID, a pointer to the model, and our view as a + parent, to the \c InformationWindow constructor. Note that we + connect the information window's \c imageChanged() signal to \e + this widget's \c updateImage() slot, before we give it a suitable + position and add it to the list of existing windows. + + \snippet examples/sql/drilldown/view.cpp 7 + + The \c updateImage() slot takes a location ID and the name of an + image files as arguments. It filters out the image items, and + updates the one that correspond to the given location ID, with the + provided image file. + + \snippet examples/sql/drilldown/view.cpp 8 + + The \c findWindow() function simply searches through the list of + existing windows, returning a pointer to the window that matches + the given location ID, or 0 if the window doesn't exists. + + Finally, let's take a quick look at our custom \c ImageItem class: + + \section1 ImageItem Class Definition + + The \c ImageItem class is provided to facilitate animation of the + image items. It inherits QGraphicsPixmapItem and reimplements its + hover event handlers: + + \snippet examples/sql/drilldown/imageitem.h 0 + + In addition, we implement a public \c id() function to be able to + identify the associated location and a public \c adjust() function + that can be called to ensure that the image item is given the + preferred size regardless of the original image file. + + The animation is implemented using the QTimeLine class together + with the event handlers and the private \c setFrame() slot: The + image item will expand when the mouse cursor hovers over it, + returning back to its orignal size when the cursor leaves its + borders. + + Finally, we store the location ID that this particular record is + associated with as well as a z-value. In the \l {The Graphics View + Framework}, an item's z-value determines its position in the item + stack. An item of high Z-value will be drawn on top of an item + with a lower z-value if they share the same parent item. We also + provide an \c updateItemPosition() function to refresh the view + when required. + + \section1 ImageItem Class Implementation + + The \c ImageItem class is really only a QGraphicsPixmapItem with + some additional features, i.e., we can pass most of the + constructor's arguments (the pixmap, parent and scene) on to the + base class constructor: + + \snippet examples/sql/drilldown/imageitem.cpp 0 + + Then we store the ID for future reference, and ensure that our + item will accept hover events. Hover events are delivered when + there is no current mouse grabber item. They are sent when the + mouse cursor enters an item, when it moves around inside the item, + and when the cursor leaves an item. As we mentioned earlier, none + of the \l {The Graphics View Framework}'s items accept hover + event's by default. + + The QTimeLine class provides a timeline for controlling + animations. Its \l {QTimeLine::}{duration} property holds the + total duration of the timeline in milliseconds. By default, the + time line runs once from the beginning and towards the end. The + QTimeLine::setFrameRange() function sets the timeline's frame + counter; when the timeline is running, the \l + {QTimeLine::}{frameChanged()} signal is emitted each time the + frame changes. We set the duration and frame range for our + animation, and connect the time line's \l + {QTimeLine::}{frameChanged()} and \l {QTimeLine::}{finished()} + signals to our private \c setFrame() and \c updateItemPosition() + slots. + + Finally, we call \c adjust() to ensure that the item is given the + preferred size. + + \snippet examples/sql/drilldown/imageitem.cpp 1 + \codeline + \snippet examples/sql/drilldown/imageitem.cpp 2 + + Whenever the mouse cursor enters or leave the image item, the + corresponding event handlers are triggered: We first set the time + line's direction, making the item expand or shrink, + respectively. Then we alter the item's z-value if it is not already + set to the expected value. + + In the case of hover \e enter events, we immediately update the + item's position since we want the item to appear on top of all + other items as soon as it starts expanding. In the case of hover + \e leave events, on the other hand, we postpone the actual update + to achieve the same result. But remember that when we constructed + our item, we connected the time line's \l + {QTimeLine::}{finished()} signal to the \c updateItemPosition() + slot. In this way the item is given the correct position in the + item stack once the animation is completed. Finally, if the time + line is not already running, we start it. + + \snippet examples/sql/drilldown/imageitem.cpp 3 + + When the time line is running, it triggers the \c setFrame() slot + whenever the current frame changes due to the connection we + created in the item constructor. It is this slot that controls the + animation, expanding or shrinking the image item step by step. + + We first call the \c adjust() function to ensure that we start off + with the item's original size. Then we scale the item with a + factor depending on the animation's progress (using the \c frame + parameter). Note that by default, the transformation will be + relative to the item's top-left corner. Since we want the item to + be transformed relative to its center, we must translate the + coordinate system before we scale the item. + + In the end, only the following convenience functions remain: + + \snippet examples/sql/drilldown/imageitem.cpp 4 + \codeline + \snippet examples/sql/drilldown/imageitem.cpp 5 + \codeline + \snippet examples/sql/drilldown/imageitem.cpp 6 + + The \c adjust() function defines and applies a transformation + matrix, ensuring that our image item appears with the preferred + size regardless of the size of the source image. The \c id() + function is trivial, and is simply provided to be able to identify + the item. In the \c updateItemPosition() slot we call the + QGraphicsItem::setZValue() function, setting the elevation (i.e., + the position) of the item. +*/ diff --git a/doc/src/examples/dropsite.qdoc b/doc/src/examples/dropsite.qdoc new file mode 100644 index 0000000..4780b82 --- /dev/null +++ b/doc/src/examples/dropsite.qdoc @@ -0,0 +1,263 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example draganddrop/dropsite + \title Drop Site Example + + The example shows how to distinguish the various MIME formats available + in a drag and drop operation. + + \image dropsite-example.png Screenshot of the Drop Site example + + The Drop Site example accepts drops from other applications, and displays + the MIME formats provided by the drag object. + + There are two classes, \c DropArea and \c DropSiteWindow, and a \c main() + function in this example. A \c DropArea object is instantiated in + \c DropSiteWindow; a \c DropSiteWindow object is then invoked in the + \c main() function. + + \section1 DropArea Class Definition + + The \c DropArea class is a subclass of QLabel with a public slot, + \c clear(), and a \c changed() signal. + + \snippet draganddrop/dropsite/droparea.h DropArea header part1 + + In addition, \c DropArea also contains a private instance of QLabel and + reimplementations of four \l{QWidget} event handlers: + + \list 1 + \o \l{QWidget::dragEnterEvent()}{dragEnterEvent()} + \o \l{QWidget::dragMoveEvent()}{dragMoveEvent()} + \o \l{QWidget::dragLeaveEvent()}{dragLeaveEvent()} + \o \l{QWidget::dropEvent()}{dropEvent()} + \endlist + + These event handlers are further explained in the implementation of the + \c DropArea class. + + \snippet draganddrop/dropsite/droparea.h DropArea header part2 + + \section1 DropArea Class Implementation + + In the \c DropArea constructor, we set the \l{QWidget::setMinimumSize()} + {minimum size} to 200x200 pixels, the \l{QFrame::setFrameStyle()} + {frame style} to both QFrame::Sunken and QFrame::StyledPanel, and we align + its contents to the center. + + \snippet draganddrop/dropsite/droparea.cpp DropArea constructor + + Also, we enable drop events in \c DropArea by setting the + \l{QWidget::acceptDrops()}{acceptDrops} property to \c true. Then, + we enable the \l{QWidget::autoFillBackground()}{autoFillBackground} + property and invoke the \c clear() function. + + The \l{QWidget::dragEnterEvent()}{dragEnterEvent()} event handler is + called when a drag is in progress and the mouse enters the \c DropArea + object. For the \c DropSite example, when the mouse enters \c DropArea, + we set its text to "<drop content>" and highlight its background. + + \snippet draganddrop/dropsite/droparea.cpp dragEnterEvent() function + + Then, we invoke \l{QDropEvent::acceptProposedAction()} + {acceptProposedAction()} on \a event, setting the drop action to the one + proposed. Lastly, we emit the \c changed() signal, with the data that was + dropped and its MIME type information as a parameter. + + For \l{QWidget::dragMoveEvent()}{dragMoveEvent()}, we just accept the + proposed QDragMoveEvent object, \a event, with + \l{QDropEvent::acceptProposedAction()}{acceptProposedAction()}. + + \snippet draganddrop/dropsite/droparea.cpp dragMoveEvent() function + + The \c DropArea class's implementation of \l{QWidget::dropEvent()} + {dropEvent()} extracts the \a{event}'s mime data and displays it + accordingly. + + \snippet draganddrop/dropsite/droparea.cpp dropEvent() function part1 + + The \c mimeData object can contain one of the following objects: an image, + HTML text, plain text, or a list of URLs. + + \snippet draganddrop/dropsite/droparea.cpp dropEvent() function part2 + + \list + \o If \c mimeData contains an image, we display it in \c DropArea with + \l{QLabel::setPixmap()}{setPixmap()}. + \o If \c mimeData contains HTML, we display it with + \l{QLabel::setText()}{setText()} and set \c{DropArea}'s text format + as Qt::RichText. + \o If \c mimeData contains plain text, we display it with + \l{QLabel::setText()}{setText()} and set \c{DropArea}'s text format + as Qt::PlainText. In the event that \c mimeData contains URLs, we + iterate through the list of URLs to display them on individual + lines. + \o If \c mimeData contains other types of objects, we set + \c{DropArea}'s text, with \l{QLabel::setText()}{setText()} to + "Cannot display data" to inform the user. + \endlist + + We then set \c{DropArea}'s \l{QWidget::backgroundRole()}{backgroundRole} to + QPalette::Dark and we accept \c{event}'s proposed action. + + \snippet draganddrop/dropsite/droparea.cpp dropEvent() function part3 + + The \l{QWidget::dragLeaveEvent()}{dragLeaveEvent()} event handler is + called when a drag is in progress and the mouse leaves the widget. + + \snippet draganddrop/dropsite/droparea.cpp dragLeaveEvent() function + + For \c{DropArea}'s implementation, we clear invoke \c clear() and then + accept the proposed event. + + The \c clear() function sets the text in \c DropArea to "<drop content>" + and sets the \l{QWidget::backgroundRole()}{backgroundRole} to + QPalette::Dark. Lastly, it emits the \c changed() signal. + + \snippet draganddrop/dropsite/droparea.cpp clear() function + + \section1 DropSiteWindow Class Definition + + The \c DropSiteWindow class contains a constructor and a public slot, + \c updateFormatsTable(). + + \snippet draganddrop/dropsite/dropsitewindow.h DropSiteWindow header + + The class also contains a private instance of \c DropArea, \c dropArea, + QLabel, \c abstractLabel, QTableWidget, \c formatsTable, QDialogButtonBox, + \c buttonBox, and two QPushButton objects, \c clearButton and + \c quitButton. + + \section1 DropSiteWindow Class Implementation + + In the constructor of \c DropSiteWindow, we instantiate \c abstractLabel + and set its \l{QLabel::setWordWrap()}{wordWrap} property to \c true. We + also call the \l{QLabel::adjustSize()}{adjustSize()} function to adjust + \c{abstractLabel}'s size according to its contents. + + \snippet draganddrop/dropsite/dropsitewindow.cpp constructor part1 + + Then we instantiate \c dropArea and connect its \c changed() signal to + \c{DropSiteWindow}'s \c updateFormatsTable() slot. + + \snippet draganddrop/dropsite/dropsitewindow.cpp constructor part2 + + We now set up the QTableWidget object, \c formatsTable. Its + horizontal header is set using a QStringList object, \c labels. The number + of columms are set to two and the table is not editable. Also, the + \c{formatTable}'s horizontal header is formatted to ensure that its second + column stretches to occupy additional space available. + + \snippet draganddrop/dropsite/dropsitewindow.cpp constructor part3 + + Two QPushButton objects, \c clearButton and \c quitButton, are instantiated + and added to \c buttonBox - a QDialogButtonBox object. We use + QDialogButtonBox here to ensure that the push buttons are presented in a + layout that conforms to the platform's style. + + \snippet draganddrop/dropsite/dropsitewindow.cpp constructor part4 + + The \l{QPushButton::clicked()}{clicked()} signals for \c quitButton and + \c clearButton are connected to \l{QWidget::close()}{close()} and + \c clear(), respectively. + + For the layout, we use a QVBoxLayout, \c mainLayout, to arrange our widgets + vertically. We also set the window title to "Drop Site" and the minimum + size to 350x500 pixels. + + \snippet draganddrop/dropsite/dropsitewindow.cpp constructor part5 + + We move on to the \c updateFormatsTable() function. This function updates + the \c formatsTable, displaying the MIME formats of the object dropped onto + the \c DropArea object. First, we set \l{QTableWidget}'s + \l{QTableWidget::setRowCount()}{rowCount} property to 0. Then, we validate + to ensure that the QMimeData object passed in is a valid object. + + \snippet draganddrop/dropsite/dropsitewindow.cpp updateFormatsTable() part1 + + Once we are sure that \c mimeData is valid, we iterate through its + supported formats using the \l{The foreach Keyword}{foreach keyword}. + This keyword has the following format: + + \snippet doc/src/snippets/code/doc_src_examples_dropsite.qdoc 0 + + In our example, \c format is the \a variable and the \a container is a + QStringList, obtained from \c mimeData->formats(). + + \note The \l{QMimeData::formats()}{formats()} function returns a + QStringList object, containing all the formats supported by the + \c mimeData. + + \snippet draganddrop/dropsite/dropsitewindow.cpp updateFormatsTable() part2 + + Within each iteration, we create a QTableWidgetItem, \c formatItem and we + set its \l{QTableWidgetItem::setFlags()}{flags} to Qt::ItemIsEnabled, and + its \l{QTableWidgetItem::setTextAlignment()}{text alignment} to Qt::AlignTop + and Qt::AlignLeft. + + A QString object, \c text, is customized to display data according to the + contents of \c format. We invoke {QString}'s \l{QString::simplified()} + {simplified()} function on \c text, to obtain a string that has no + additional space before, after or in between words. + + \snippet draganddrop/dropsite/dropsitewindow.cpp updateFormatsTable() part3 + + If \c format contains a list of URLs, we iterate through them, using spaces + to separate them. On the other hand, if \c format contains an image, we + display the data by converting the text to hexadecimal. + + \snippet draganddrop/dropsite/dropsitewindow.cpp updateFormatsTable() part4 + + Once \c text has been customized to contain the appropriate data, we insert + both \c format and \c text into \c formatsTable with + \l{QTableWidget::setItem()}{setItem()}. Lastly, we invoke + \l{QTableView::resizeColumnToContents()}{resizeColumnToContents()} on + \c{formatsTable}'s first column. + + \section1 The main() Function + + Within the \c main() function, we instantiate \c DropSiteWindow and invoke + its \l{QWidget::show()}{show()} function. + + \snippet draganddrop/dropsite/main.cpp main() function +*/ diff --git a/doc/src/examples/dynamiclayouts.qdoc b/doc/src/examples/dynamiclayouts.qdoc new file mode 100644 index 0000000..96b791b --- /dev/null +++ b/doc/src/examples/dynamiclayouts.qdoc @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example layouts/dynamiclayouts + \title Dynamic Layouts Example + + The Dynamic Layouts example shows how to move widgets around in + existing layouts. +*/ diff --git a/doc/src/examples/echoplugin.qdoc b/doc/src/examples/echoplugin.qdoc new file mode 100644 index 0000000..32ad15b --- /dev/null +++ b/doc/src/examples/echoplugin.qdoc @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/echoplugin + \title Echo Plugin Example + + This example shows how to create a Qt plugin. + + \image echopluginexample.png + + There are two kinds of plugins in Qt: plugins that extend Qt + itself and plugins that extend applications written in Qt. In this + example, we show the procedure of implementing plugins that extend + applications. When you create a plugin you declare an interface, + which is a class with only pure virtual functions. This interface + is inherited by the class that implements the plugin. The class is + stored in a shared library and can therefore be loaded by + applications at run-time. When loaded, the plugin is dynamically + cast to the interface using Qt's \l{Meta-Object + System}{meta-object system}. The plugin \l{How to Create Qt + Plugins}{overview document} gives a high-level introduction to + plugins. + + We have implemented a plugin, the \c EchoPlugin, which implements + the \c EchoInterface. The interface consists of \c echo(), which + takes a QString as argument. The \c EchoPlugin returns the string + unaltered (i.e., it works as the familiar echo command found in + both Unix and Windows). + + We test the plugin in \c EchoWindow: when you push the QPushButton + (as seen in the image above), the application sends the text in + the QLineEdit to the plugin, which echoes it back to the + application. The answer from the plugin is displayed in the + QLabel. + + + \section1 EchoWindow Class Definition + + The \c EchoWindow class lets us test the \c EchoPlugin through a + GUI. + + \snippet examples/tools/echoplugin/echowindow/echowindow.h 0 + + We load the plugin in \c loadPlugin() and cast it to \c + EchoInterface. When the user clicks the \c button we take the + text in \c lineEdit and call the interface's \c echo() with it. + + + \section1 EchoWindow Class Implementation + + We start with a look at the constructor: + + \snippet examples/tools/echoplugin/echowindow/echowindow.cpp 0 + + We create the widgets and set a title for the window. We then load + the plugin. \c loadPlugin() returns false if the plugin could not + be loaded, in which case we disable the widgets. If you wish a + more detailed error message, you can use + \l{QPluginLoader::}{errorString()}; we will look more closely at + QPluginLoader later. + + Here is the implementation of \c sendEcho(): + + \snippet examples/tools/echoplugin/echowindow/echowindow.cpp 1 + + This slot is called when the user pushes \c button or presses + enter in \c lineEdit. We call \c echo() of the echo interface. In + our example this is the \c EchoPlugin, but it could be any plugin + that inherit the \c EchoInterface. We take the QString returned + from \c echo() and display it in the \c label. + + Here is the implementation of \c createGUI(): + + \snippet examples/tools/echoplugin/echowindow/echowindow.cpp 2 + + We create the widgets and lay them out in a grid layout. We + connect the label and line edit to our \c sendEcho() slot. + + Here is the \c loadPlugin() function: + + \snippet examples/tools/echoplugin/echowindow/echowindow.cpp 3 + + Access to plugins at run-time is provided by QPluginLoader. You + supply it with the filename of the shared library the plugin is + stored in and call \l{QPluginLoader::}{instance()}, which loads + and returns the root component of the plugin (i.e., it resolves + the type of the plugin and creates a QObject instance of it). If + the plugin was not successfully loaded, it will be null, so we + return false. If it was loaded correctly, we can cast the plugin + to our \c EchoInterface and return true. In the case that the + plugin loaded does not implement the \c EchoInterface, \c + instance() will return null, but this cannot happen in our + example. Notice that the location of the plugin is not the same + for all platforms. + + + \section1 EchoInterface Class Definition + + The \c EchoInterface defines the functions that the plugin will + provide. An interface is a class that only consists of pure + virtual functions. If non virtual functions were present in the + class you would get misleading compile errors in the moc files. + + \snippet examples/tools/echoplugin/echowindow/echointerface.h 0 + + We declare \c echo(). In our \c EchoPlugin we use this method to + return, or echo, \a message. + + We use the Q_DECLARE_INTERFACE macro to let \l{Meta-Object + System}{Qt's meta object system} aware of the interface. We do + this so that it will be possible to identify plugins that + implements the interface at run-time. The second argument is a + string that must identify the interface in a unique way. + + + \section1 EchoPlugin Class Definition + + We inherit both QObject and \c EchoInterface to make this class a + plugin. The Q_INTERFACES macro tells Qt which interfaces the class + implements. In our case we only implement the \c EchoInterface. + If a class implements more than one interface, they are given as + a comma separated list. + + \snippet examples/tools/echoplugin/plugin/echoplugin.h 0 + + + \section1 EchoPlugin Class Implementation + + Here is the implementation of \c echo(): + + \snippet examples/tools/echoplugin/plugin/echoplugin.cpp 0 + + We simply return the functions parameter. + + \snippet examples/tools/echoplugin/plugin/echoplugin.cpp 1 + + We use the Q_EXPORT_PLUGIN2 macro to let Qt know that the \c + EchoPlugin class is a plugin. The first parameter is the name of + the plugin; it is usual to give the plugin and the library file it + is stored in the same name. + + \section1 The \c main() function + + \snippet examples/tools/echoplugin/echowindow/main.cpp 0 + + We create an \c EchoWindow and display it as a top-level window. + + \section1 The Profiles + + When creating plugins the profiles need to be adjusted. + We show here what changes need to be done. + + The profile in the echoplugin directory uses the \c subdirs + template and simply includes includes to directories in which + the echo window and echo plugin lives: + + \snippet examples/tools/echoplugin/echoplugin.pro 0 + + The profile for the echo window does not need any plugin specific + settings. We move on to the plugin profile: + + \snippet examples/tools/echoplugin/plugin/plugin.pro 0 + + We need to set the TEMPLATE as we now want to make a library + instead of an executable. We also need to tell qmake that we are + creating a plugin. The \c EchoInterface that the plugin implements + lives in the \c echowindow directory, so we need to add that + directory to the include path. We set the TARGET of the project, + which is the name of the library file in which the plugin will be + stored; qmake appends the appropriate file extension depending on + the platform. By convention the target should have the same name + as the plugin (set with Q_EXPORT_PLUGIN2) + + \section1 Further reading and examples + + You can find an overview of the macros needed to create plugins + \l{Macros for Defining Plugins}{here}. + + We give an example of a plugin that extend Qt in the \l{Style + Plugin Example}{style plugin} example. The \l{Plug & Paint + Example}{plug and paint} example shows how to create static + plugins. +*/ diff --git a/doc/src/examples/editabletreemodel.qdoc b/doc/src/examples/editabletreemodel.qdoc new file mode 100644 index 0000000..da01830 --- /dev/null +++ b/doc/src/examples/editabletreemodel.qdoc @@ -0,0 +1,459 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/editabletreemodel + \title Editable Tree Model Example + + This example shows how to implement a simple item-based tree model that can + be used with other classes the model/view framework. + + \image itemviews-editabletreemodel.png + + The model supports editable items, custom headers, and the ability to + insert and remove rows and columns. With these features, it is also + possible to insert new child items, and this is shown in the supporting + example code. + + \note The model only shows the basic principles used when creating an + editable, hierarchical model. You may wish to use the \l{ModelTest} + project to test production models. + + \section1 Overview + + As described in the \l{Model Subclassing Reference}, models must + provide implementations for the standard set of model functions: + \l{QAbstractItemModel::}{flags()}, \l{QAbstractItemModel::}{data()}, + \l{QAbstractItemModel::}{headerData()}, and + \l{QAbstractItemModel::}{rowCount()}. In addition, hierarchical models, + such as this one, need to provide implementations of + \l{QAbstractItemModel::}{index()} and \l{QAbstractItemModel::}{parent()}. + + An editable model needs to provide implementations of + \l{QAbstractItemModel::}{setData()} and + \l{QAbstractItemModel::}{headerData()}, and must return a suitable + combination of flags from its \l{QAbstractItemModel::}{flags()} function. + + Since this example allows the dimensions of the model to be changed, + we must also implement \l{QAbstractItemModel::}{insertRows()}, + \l{QAbstractItemModel::}{insertColumns()}, + \l{QAbstractItemModel::}{removeRows()}, and + \l{QAbstractItemModel::}{removeColumns()}. + + \section1 Design + + As with the \l{itemviews/simpletreemodel}{Simple Tree Model} example, + the model simply acts as a wrapper around a collection + of instances of a \c TreeItem class. Each \c TreeItem is designed to + hold data for a row of items in a tree view, so it contains a list of + values corresponding to the data shown in each column. + + Since QTreeView provides a row-oriented view onto a model, it is + natural to choose a row-oriented design for data structures that + will supply data via a model to this kind of view. Although this makes + the tree model less flexible, and possibly less useful for use with + more sophisticated views, it makes it less complex to design and easier + to implement. + + \target Relations-between-internal-items + \table + \row \o \inlineimage itemviews-editabletreemodel-items.png + \o \bold{Relations between internal items} + + When designing a data structure for use with a custom model, it is useful + to expose each item's parent via a function like + \l{TreeItem::parent}{TreeItem::parent()} because it will make + writing the model's own \l{QAbstractItemModel::}{parent()} function easier. + Similarly, a function like \l{TreeItem::child}{TreeItem::child()} is + helpful when implementing the model's \l{QAbstractItemModel::}{index()} + function. As a result, each \c TreeItem maintains information about + its parent and children, making it possible for us to traverse the tree + structure. + + The diagram shows how \c TreeItem instances are connected via their + \l{TreeItem::parent}{parent()} and \l{TreeItem::child}{child()} + functions. + + In the example shown, two top-level items, \bold{A} and + \bold{B}, can be obtained from the root item by calling its child() + function, and each of these items return the root node from their + parent() functions, though this is only shown for item \bold{A}. + \endtable + + Each \c TreeItem stores data for each column in the row it represents + in its \c itemData private member (a list of QVariant objects). + Since there is a one-to-one mapping between each column in the view + and each entry in the list, we provide a simple + \l{TreeItem::data}{data()} function to read entries in the \c itemData + list and a \l{TreeItem::setData}{setData()} function to allow them to + be modified. + As with other functions in the item, this simplifies the implemention + of the model's \l{QAbstractItemModel::}{data()} and + \l{QAbstractItemModel::}{setData()} functions. + + We place an item at the root of the tree of items. This root item + corresponds to the null model index, \l{QModelIndex::}{QModelIndex()}, + that is used to represent the parent of a top-level item when handling + model indexes. + Although the root item does not have a visible representation in any of + the standard views, we use its internal list of QVariant objects to + store a list of strings that will be passed to views for use as + horizontal header titles. + + \table + \row \o \inlineimage itemviews-editabletreemodel-model.png + \o \bold{Accessing data via the model} + + In the case shown in the diagram, the piece of information represented + by \bold{a} can be obtained using the standard model/view API: + + \snippet doc/src/snippets/code/doc_src_examples_editabletreemodel.qdoc 0 + + Since each items holds pieces of data for each column in a given row, + there can be many model indexes that map to the same \c TreeItem object. + For example, the information represented by \bold{b} can be obtained + using the following code: + + \snippet doc/src/snippets/code/doc_src_examples_editabletreemodel.qdoc 1 + + The same underlying \c TreeItem would be accessed to obtain information + for the other model indexes in the same row as \bold{b}. + \endtable + + In the model class, \c TreeModel, we relate \c TreeItem objects to + model indexes by passing a pointer for each item when we create its + corresponding model index with QAbstractItemModel::createIndex() in + our \l{TreeModel::index}{index()} and \l{TreeModel::parent}{parent()} + implementations. + We can retrieve pointers stored in this way by calling the + \l{QModelIndex::}{internalPointer()} function on the relevant model + index - we create our own \l{TreeModel::getItem}{getItem()} function to + do this work for us, and call it from our \l{TreeModel::data}{data()} + and \l{TreeModel::parent}{parent()} implementations. + + Storing pointers to items is convenient when we control how they are + created and destroyed since we can assume that an address obtained from + \l{QModelIndex::}{internalPointer()} is a valid pointer. + However, some models need to handle items that are obtained from other + components in a system, and in many cases it is not possible to fully + control how items are created or destroyed. In such situations, a pure + pointer-based approach needs to be supplemented by safeguards to ensure + that the model does not attempt to access items that have been deleted. + + \table + \row \o \bold{Storing information in the underlying data structure} + + Several pieces of data are stored as QVariant objects in the \c itemData + member of each \c TreeItem instance + + The diagram shows how pieces of information, + represented by the labels \bold{a}, \bold{b} and \bold{c} in the + previous two diagrams, are stored in items \bold{A}, \bold{B} and + \bold{C} in the underlying data structure. Note that pieces of + information from the same row in the model are all obtained from the + same item. Each element in a list corresponds to a piece of information + exposed by each column in a given row in the model. + + \o \inlineimage itemviews-editabletreemodel-values.png + \endtable + + Since the \c TreeModel implementation has been designed for use with + QTreeView, we have added a restriction on the way it uses \c TreeItem + instances: each item must expose the same number of columns of data. + This makes viewing the model consistent, allowing us to use the root + item to determine the number of columns for any given row, and only + adds the requirement that we create items containing enough data for + the total number of columns. As a result, inserting and removing + columns are time-consuming operations because we need to traverse the + entire tree to modify every item. + + An alternative approach would be to design the \c TreeModel class so + that it truncates or expands the list of data in individual \c TreeItem + instances as items of data are modified. However, this "lazy" resizing + approach would only allow us to insert and remove columns at the end of + each row and would not allow columns to be inserted or removed at + arbitrary positions in each row. + + \target Relating-items-using-model-indexes + \table + \row + \o \inlineimage itemviews-editabletreemodel-indexes.png + \o \bold{Relating items using model indexes} + + As with the \l{itemviews/simpletreemodel}{Simple Tree Model} example, + the \c TreeModel needs to be able to take a model index, find the + corresponding \c TreeItem, and return model indexes that correspond to + its parents and children. + + In the diagram, we show how the model's \l{TreeModel::parent()}{parent()} + implementation obtains the model index corresponding to the parent of + an item supplied by the caller, using the items shown in a + \l{Relations-between-internal-items}{previous diagram}. + + A pointer to item \bold{C} is obtained from the corresponding model index + using the \l{QModelIndex::internalPointer()} function. The pointer was + stored internally in the index when it was created. Since the child + contains a pointer to its parent, we use its \l{TreeItem::parent}{parent()} + function to obtain a pointer to item \bold{B}. The parent model index is + created using the QAbstractItemModel::createIndex() function, passing + the pointer to item \bold{B} as the internal pointer. + \endtable + + \section1 TreeItem Class Definition + + The \c TreeItem class provides simple items that contain several + pieces of data, and which can provide information about their parent + and child items: + + \snippet examples/itemviews/editabletreemodel/treeitem.h 0 + + We have designed the API to be similar to that provided by + QAbstractItemModel by giving each item functions to return the number + of columns of information, read and write data, and insert and remove + columns. However, we make the relationship between items explicit by + providing functions to deal with "children" rather than "rows". + + Each item contains a list of pointers to child items, a pointer to its + parent item, and a list of QVariant objects that correspond to + information held in columns in a given row in the model. + + \section1 TreeItem Class Implementation + + Each \c TreeItem is constructed with a list of data and an optional + parent item: + + \snippet examples/itemviews/editabletreemodel/treeitem.cpp 0 + + Initially, each item has no children. These are added to the item's + internal \c childItems member using the \c insertChildren() function + described later. + + The destructor ensures that each child added to the item is deleted + when the item itself is deleted: + + \snippet examples/itemviews/editabletreemodel/treeitem.cpp 1 + + \target TreeItem::parent + Since each item stores a pointer to its parent, the \c parent() function + is trivial: + + \snippet examples/itemviews/editabletreemodel/treeitem.cpp 9 + + \target TreeItem::child + Three functions provide information about the children of an item. + \c child() returns a specific child from the internal list of children: + + \snippet examples/itemviews/editabletreemodel/treeitem.cpp 2 + + The \c childCount() function returns the total number of children: + + \snippet examples/itemviews/editabletreemodel/treeitem.cpp 3 + + The \c childNumber() function is used to determine the index of the child + in its parent's list of children. It accesses the parent's \c childItems + member directly to obtain this information: + + \snippet examples/itemviews/editabletreemodel/treeitem.cpp 4 + + The root item has no parent item; for this item, we return zero to be + consistent with the other items. + + The \c columnCount() function simply returns the number of elements in + the internal \c itemData list of QVariant objects: + + \snippet examples/itemviews/editabletreemodel/treeitem.cpp 5 + + \target TreeItem::data + Data is retrieved using the \c data() function, which accesses the + appropriate element in the \c itemData list: + + \snippet examples/itemviews/editabletreemodel/treeitem.cpp 6 + + \target TreeItem::setData + Data is set using the \c setData() function, which only stores values + in the \c itemData list for valid list indexes, corresponding to column + values in the model: + + \snippet examples/itemviews/editabletreemodel/treeitem.cpp 11 + + To make implementation of the model easier, we return true to indicate + whether the data was set successfully, or false if an invalid column + + Editable models often need to be resizable, enabling rows and columns to + be inserted and removed. The insertion of rows beneath a given model index + in the model leads to the insertion of new child items in the corresponding + item, handled by the \c insertChildren() function: + + \snippet examples/itemviews/editabletreemodel/treeitem.cpp 7 + + This ensures that new items are created with the required number of columns + and inserted at a valid position in the internal \c childItems list. + Items are removed with the \c removeChildren() function: + + \snippet examples/itemviews/editabletreemodel/treeitem.cpp 10 + + As discussed above, the functions for inserting and removing columns are + used differently to those for inserting and removing child items because + they are expected to be called on every item in the tree. We do this by + recursively calling this function on each child of the item: + + \snippet examples/itemviews/editabletreemodel/treeitem.cpp 8 + + \section1 TreeModel Class Definition + + The \c TreeModel class provides an implementation of the QAbstractItemModel + class, exposing the necessary interface for a model that can be edited and + resized. + + \snippet examples/itemviews/editabletreemodel/treemodel.h 0 + + The constructor and destructor are specific to this model. + + \snippet examples/itemviews/editabletreemodel/treemodel.h 1 + + Read-only tree models only need to provide the above functions. The + following public functions provide support for editing and resizing: + + \snippet examples/itemviews/editabletreemodel/treemodel.h 2 + + To simplify this example, the data exposed by the model is organized into + a data structure by the model's \l{TreeModel::setupModelData}{setupModelData()} + function. Many real world models will not process the raw data at all, but + simply work with an existing data structure or library API. + + \section1 TreeModel Class Implementation + + The constructor creates a root item and initializes it with the header + data supplied: + + \snippet examples/itemviews/editabletreemodel/treemodel.cpp 0 + + We call the internal \l{TreeModel::setupModelData}{setupModelData()} + function to convert the textual data supplied to a data structure we can + use with the model. Other models may be initialized with a ready-made + data structure, or use an API to a library that maintains its own data. + + The destructor only has to delete the root item; all child items will + be recursively deleted by the \c TreeItem destructor. + + \snippet examples/itemviews/editabletreemodel/treemodel.cpp 1 + + \target TreeModel::getItem + Since the model's interface to the other model/view components is based + on model indexes, and the internal data structure is item-based, many of + the functions implemented by the model need to be able to convert any + given model index to its corresponding item. For convenience and + consistency, we have defined a \c getItem() function to perform this + repetitive task: + + \snippet examples/itemviews/editabletreemodel/treemodel.cpp 4 + + This function assumes that each model index it is passed corresponds to + a valid item in memory. If the index is invalid, or its internal pointer + does not refer to a valid item, the root item is returned instead. + + The model's \c rowCount() implementation is simple: it first uses the + \c getItem() function to obtain the relevant item, then returns the + number of children it contains: + + \snippet examples/itemviews/editabletreemodel/treemodel.cpp 8 + + By contrast, the \c columnCount() implementation does not need to look + for a particular item because all items are defined to have the same + number of columns associated with them. + + \snippet examples/itemviews/editabletreemodel/treemodel.cpp 2 + + As a result, the number of columns can be obtained directly from the root + item. + + To enable items to be edited and selected, the \c flags() function needs + to be implemented so that it returns a combination of flags that includes + the Qt::ItemIsEditable and Qt::ItemIsSelectable flags as well as + Qt::ItemIsEnabled: + + \snippet examples/itemviews/editabletreemodel/treemodel.cpp 3 + + \target TreeModel::index + The model needs to be able to generate model indexes to allow other + components to request data and information about its structure. This task + is performed by the \c index() function, which is used to obtain model + indexes corresponding to children of a given parent item: + + \snippet examples/itemviews/editabletreemodel/treemodel.cpp 5 + + In this model, we only return model indexes for child items if the parent + index is invalid (corresponding to the root item) or if it has a zero + column number. + + We use the custom \l{TreeModel::getItem}{getItem()} function to obtain + a \c TreeItem instance that corresponds to the model index supplied, and + request its child item that corresponds to the specified row. + + \snippet examples/itemviews/editabletreemodel/treemodel.cpp 6 + + Since each item contains information for an entire row of data, we create + a model index to uniquely identify it by calling + \l{QAbstractItemModel::}{createIndex()} it with the row and column numbers + and a pointer to the item. In the \l{TreeModel::data}{data()} function, + we will use the item pointer and column number to access the data + associated with the model index; in this model, the row number is not + needed to identify data. + + \target TreeModel::parent + The \c parent() function supplies model indexes for parents of items + by finding the corresponding item for a given model index, using its + \l{TreeItem::parent}{parent()} function to obtain its parent item, + then creating a model index to represent the parent. (See + \l{Relating-items-using-model-indexes}{the above diagram}). + + \snippet examples/itemviews/editabletreemodel/treemodel.cpp 7 + + Items without parents, including the root item, are handled by returning + a null model index. Otherwise, a model index is created and returned as + in the \l{TreeModel::index}{index()} function, with a suitable row number, + but with a zero column number to be consistent with the scheme used in + the \l{TreeModel::index}{index()} implementation. + + \target TreeModel::data + \target TreeModel::setupModelData + +*/ diff --git a/doc/src/examples/elasticnodes.qdoc b/doc/src/examples/elasticnodes.qdoc new file mode 100644 index 0000000..90f2f01 --- /dev/null +++ b/doc/src/examples/elasticnodes.qdoc @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example graphicsview/elasticnodes + \title Elastic Nodes Example + + This GraphicsView example shows how to implement edges between nodes in a graph. + + \image elasticnodes-example.png +*/ diff --git a/doc/src/examples/extension.qdoc b/doc/src/examples/extension.qdoc new file mode 100644 index 0000000..8a0ca3a --- /dev/null +++ b/doc/src/examples/extension.qdoc @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example dialogs/extension + \title Extension Example + + The Extension example shows how to add an extension to a QDialog + using the QAbstractButton::toggled() signal and the + QWidget::setVisible() slot. + + \image extension-example.png Screenshot of the Extension example + + The Extension application is a dialog that allows the user to + perform a simple search as well as a more advanced search. + + The simple search has two options: \gui {Match case} and \gui + {Search from start}. The advanced search options include the + possibilities to search for \gui {Whole words}, \gui {Search + backward} and \gui {Search selection}. Only the simple search is + visible when the application starts. The advanced search options + are located in the application's extension part, and can be made + visible by pressing the \gui More button: + + \image extension_more.png Screenshot of the Extension example + + \section1 FindDialog Class Definition + + The \c FindDialog class inherits QDialog. The QDialog class is the + base class of dialog windows. A dialog window is a top-level + window mostly used for short-term tasks and brief communications + with the user. + + \snippet examples/dialogs/extension/finddialog.h 0 + + The \c FindDialog widget is the main application widget, and + displays the application's search options and controlling + buttons. + + In addition to a constructor, we declare the several child + widgets: We need a QLineEdit with an associated QLabel to let the + user type a word to search for, we need several \l + {QCheckBox}{QCheckBox}es to facilitate the search options, and we + need three \l {QPushButton}{QPushButton}s: the \gui Find button to + start a search, the \gui More button to enable an advanced search, + and the \gui Close button to exit the application. Finally, we + need a QWidget representing the application's extension part. + + \section1 FindDialog Class Implementation + + In the constructor we first create the standard child widgets for + the simple search: the QLineEdit with the associated QLabel, two + of the \l {QCheckBox}{QCheckBox}es and all the \l + {QPushButton}{QPushButton}s. + + \snippet examples/dialogs/extension/finddialog.cpp 0 + + We give the options and buttons a shortcut key using the & + character. In the \gui {Find what} option's case, we also need to + use the QLabel::setBuddy() function to make the shortcut key work + as expected; then, when the user presses the shortcut key + indicated by the label, the keyboard focus is transferred to the + label's buddy widget, the QLineEdit. + + We set the \gui Find button's default property to true, using the + QPushButton::setDefault() function. Then the push button will be + pressed if the user presses the Enter (or Return) key. Note that a + QDialog can only have one default button. + + \snippet examples/dialogs/extension/finddialog.cpp 2 + + Then we create the extension widget, and the \l + {QCheckBox}{QCheckBox}es associated with the advanced search + options. + + \snippet examples/dialogs/extension/finddialog.cpp 3 + + Now that the extension widget is created, we can connect the \gui + More button's \l{QAbstractButton::toggled()}{toggled()} signal to + the extension widget's \l{QWidget::setVisible()}{setVisible()} slot. + + The QAbstractButton::toggled() signal is emitted whenever a + checkable button changes its state. The signal's argument is true + if the button is checked, or false if the button is unchecked. The + QWidget::setVisible() slot sets the widget's visible status. If + the status is true the widget is shown, otherwise the widget is + hidden. + + Since we made the \gui More button checkable when we created it, + the connection makes sure that the extension widget is shown + depending on the state of \gui More button. + + We also connect the \gui Close button to the QWidget::close() + slot, and we put the checkboxes associated with the advanced + search options into a layout we install on the extension widget. + + \snippet examples/dialogs/extension/finddialog.cpp 4 + + Before we create the main layout, we create several child layouts + for the widgets: First we allign the QLabel ans its buddy, the + QLineEdit, using a QHBoxLayout. Then we vertically allign the + QLabel and QLineEdit with the checkboxes associated with the + simple search, using a QVBoxLayout. We also create a QVBoxLayout + for the buttons. In the end we lay out the two latter layouts and + the extension widget using a QGridLayout. + + \snippet examples/dialogs/extension/finddialog.cpp 5 + + Finally, we hide the extension widget using the QWidget::hide() + function, making the application only show the simple search + options when it starts. When the user wants to access the advanced + search options, the dialog only needs to change the visibility of + the extension widget. Qt's layout management takes care of the + dialog's appearance. +*/ diff --git a/doc/src/examples/fetchmore.qdoc b/doc/src/examples/fetchmore.qdoc new file mode 100644 index 0000000..5434098 --- /dev/null +++ b/doc/src/examples/fetchmore.qdoc @@ -0,0 +1,84 @@ +/*! + \example itemviews/fetchmore + \title Fetch More Example + + The Fetch More example shows how two add items to an item view + model on demand. + + \image fetchmore-example.png + + The user of the example can enter a directory in the \gui + Directory line edit. The contents of the directory will + be listed in the list view below. + + When you have large - or perhaps even infinite - data sets, you + will need to add items to the model in batches, and preferably only + when the items are needed by the view (i.e., when they are visible + in the view). + + In this example, we implement \c FileListModel - an item view + model containing the entries of a directory. We also have \c + Window, which sets up the GUI and feeds the model with + directories. + + Let's take a tour of \c {FileListModel}'s code. + + \section1 FileListModel Class Definition + + The \c FileListModel inherits QAbstractListModel and contains the + contents of a directory. It will add items to itself only when + requested to do so by the view. + + \snippet examples/itemviews/fetchmore/filelistmodel.h 0 + + The secret lies in the reimplementation of + \l{QAbstractItemModel::}{fetchMore()} and + \l{QAbstractItemModel::}{canFetchMore()} from QAbstractItemModel. + These functions are called by the item view when it needs more + items. + + The \c setDirPath() function sets the directory the model will + work on. We emit \c numberPopulated() each time we add a batch of + items to the model. + + We keep all directory entries in \c fileList. \c fileCount is the + number of items that have been added to the model. + + \section1 FileListModel Class Implementation + + We start by checking out the \c setDirPath(). + + \snippet examples/itemviews/fetchmore/filelistmodel.cpp 0 + + We use a QDir to get the contents of the directory. We need to + inform QAbstractItemModel that we want to remove all items - if + any - from the model. + + \snippet examples/itemviews/fetchmore/filelistmodel.cpp 1 + + The \c canFetchMore() function is called by the view when it needs + more items. We return true if there still are entries that we have + not added to the model; otherwise, we return false. + + And now, the \c fetchMore() function itself: + + \snippet examples/itemviews/fetchmore/filelistmodel.cpp 2 + + We first calculate the number of items to fetch. + \l{QAbstractItemModel::}{beginInsertRows()} and + \l{QAbstractItemModel::}{endInsertRows()} are mandatory for + QAbstractItemModel to keep up with the row insertions. Finally, we + emit \c numberPopulated(), which is picked up by \c Window. + + To complete the tour, we also look at \c rowCount() and \c data(). + + \snippet examples/itemviews/fetchmore/filelistmodel.cpp 4 + + Notice that the row count is only the items we have added so far, + i.e., not the number of entries in the directory. + + In \c data(), we return the appropriate entry from the \c + fileList. We also separate the batches with a different background + color. +*/ + diff --git a/doc/src/examples/filetree.qdoc b/doc/src/examples/filetree.qdoc new file mode 100644 index 0000000..e53769c --- /dev/null +++ b/doc/src/examples/filetree.qdoc @@ -0,0 +1,421 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/filetree + \title File System Example + + This example shows how to use QtXmlPatterns for querying non-XML + data that is modeled to look like XML. + + \tableofcontents + + \section1 Introduction + + The example models your computer's file system to look like XML and + allows you to query the file system with XQuery. Suppose we want to + find all the \c{cpp} files in the subtree beginning at + \c{/filetree}: + + \image filetree_1-example.png + + \section2 The User Inteface + + The example is shown below. First, we use \c{File->Open Directory} + (not shown) to select the \c{/filetree} directory. Then we use the + combobox on the right to select the XQuery that searches for \c{cpp} + files (\c{listCPPFiles.xq}). Selecting an XQuery runs the query, + which in this case traverses the model looking for all the \c{cpp} + files. The XQuery text and the query results are shown on the right: + + \image filetree_2-example.png + + Don't be mislead by the XML representation of the \c{/filetree} + directory shown on the left. This is not the node model itself but + the XML obtained by traversing the node model and outputting it as + XML. Constructing and using the custom node model is explained in + the code walk-through. + + \section2 Running your own XQueries + + You can write your own XQuery files and run them in the example + program. The file \c{xmlpatterns/filetree/queries.qrc} is the \l{The + Qt Resource System} {resource file} for this example. It is used in + \c{main.cpp} (\c{Q_INIT_RESOURCE(queries);}). It lists the XQuery + files (\c{.xq}) that can be selected in the combobox. + + \quotefromfile examples/xmlpatterns/filetree/queries.qrc + \printuntil + + To add your own queries to the example's combobox, store your + \c{.xq} files in the \c{examples/xmlpatterns/filetree/queries} + directory and add them to \c{queries.qrc} as shown above. + + \section1 Code Walk-Through + + The strategy is to create a custom node model that represents the + directory tree of the computer's file system. That tree structure is + non-XML data. The custom node model must have the same callback + interface as the XML node models that the QtXmlPatterns query engine + uses to execute queries. The query engine can then traverse the + custom node model as if it were traversing the node model built from + an XML document. + + The required callback interface is in QAbstractXmlNodeModel, so we + create a custom node model by subclassing QAbstractXmlNodeModel and + providing implementations for its pure virtual functions. For many + cases, the implementations of several of the virtual functions are + always the same, so QtXmlPatterns also provides QSimpleXmlNodeModel, + which subclasses QAbstractXmlNodeModel and provides implementations + for the callback functions that you can ignore. By subclassing + QSimpleXmlNodeModel instead of QAbstractXmlNodeModel, you can reduce + development time. + + \section2 The Custom Node Model Class: FileTree + + The custom node model for this example is class \c{FileTree}, which + is derived from QSimpleXmlNodeModel. \c{FileTree} implements all the + callback functions that don't have standard implementations in + QSimpleXmlNodeModel. When you implement your own custom node model, + you must provide implementations for these callback functions: + + \snippet examples/xmlpatterns/filetree/filetree.h 0 + \snippet examples/xmlpatterns/filetree/filetree.h 1 + + The \c{FileTree} class declares four data members: + + \snippet examples/xmlpatterns/filetree/filetree.h 2 + + The QVector \c{m_fileInfos} will contain the node model. Each + QFileInfo in the vector will represent a file or a directory in the + file system. At this point it is instructive to note that although + the node model class for this example (\c{FileTree}) actually builds + and contains the custom node model, building the custom node model + isn't always required. The node model class for the \l{QObject XML + Model Example} {QObject node model example} does not build its node + model but instead uses an already existing QObject tree as its node + model and just implements the callback interface for that already + existing data structure. In this file system example, however, + although we have an already existing data structure, i.e. the file + system, that data structure is not in memory and is not in a form we + can use. So we must build an analog of the file system in memory + from instances of QFileInfo, and we use that analog as the custom + node model. + + The two sets of flags, \c{m_filterAllowAll} and \c{m_sortFlags}, + contain OR'ed flags from QDir::Filters and QDir::SortFlags + respectively. They are set by the \c{FileTree} constructor and used + in calls to QDir::entryInfoList() for getting the child list for a + directory node, i.e. a QFileInfoList containing the file and + directory nodes for all the immediate children of a directory. + + The QVector \c{m_names} is an auxiliary component of the node + model. It holds the XML element and attribute names (QXmlName) for + all the node types that will be found in the node model. \c{m_names} + is indexed by the enum \c{FileTree::Type}, which specifies the node + types: + + \target Node_Type + \snippet examples/xmlpatterns/filetree/filetree.h 4 + + \c{Directory} and \c{File} will represent the XML element nodes for + directories and files respectively, and the other enum values will + represent the XML attribute nodes for a file's path, name, suffix, + its size in bytes, and its mime type. The \c{FileTree} constructor + initializes \c{m_names} with an appropriate QXmlName for each + element and attribute type: + + \snippet examples/xmlpatterns/filetree/filetree.cpp 2 + + Note that the constructor does \e{not} pre-build the entire node + model. Instead, the node model is built \e{incrementally} as the + query engine evaluates a query. To see how the query engine causes + the node model to be built incrementally, see \l{Building And + Traversing The Node Model}. To see how the query engine accesses the + node model, see \l{Accessing the node model}. See also: \l{Node + Model Building Strategy}. + + \section3 Accessing The Node Model + + Since the node model is stored outside the query engine in the + \c{FileTree} class, the query engine knows nothing about it and can + only access it by calling functions in the callback interface. When + the query engine calls any callback function to access data in the + node model, it passes a QXmlNodeModelIndex to identify the node in + the node model that it wants to access. Hence all the virtual + functions in the callback interface use a QXmlNodeModelIndex to + uniquely identify a node in the model. + + We use the index of a QFileInfo in \c{m_fileInfos} to uniquely + identify a node in the node model. To get the QXmlNodeModelIndex for + a QFileInfo, the class uses the private function \c{toNodeIndex()}: + + \target main toNodeIndex + \snippet examples/xmlpatterns/filetree/filetree.cpp 1 + + It searches the \c{m_fileInfos} vector for a QFileInfo that matches + \c{fileInfo}. If a match is found, its array index is passed to + QAbstractXmlNodeModel::createIndex() as the \c data value for the + QXmlNodeIndex. If no match is found, the unmatched QFileInfo is + appended to the vector, so this function is also doing the actual + incremental model building (see \l{Building And Traversing The Node + Model}). + + Note that \c{toNodeIndex()} gets a \l{Node_Type} {node type} as the + second parameter, which it just passes on to + \l{QAbstractXmlNodeModel::createIndex()} {createIndex()} as the + \c{additionalData} value. Logically, this second parameter + represents a second dimension in the node model, where the first + dimension represents the \e element nodes, and the second dimension + represents each element's attribute nodes. The meaning is that each + QFileInfo in the \c{m_fileInfos} vector can represent an \e{element} + node \e{and} one or more \e{attribute} nodes. In particular, the + QFileInfo for a file will contain the values for the attribute nodes + path, name, suffix, size, and mime type (see + \c{FileTree::attributes()}). Since the attributes are contained in + the QFileInfo of the file element, there aren't actually any + attribute nodes in the node model. Hence, we can use a QVector for + \c{m_fileInfos}. + + A convenience overloading of \l{toNodeIndex of convenience} + {toNodeIndex()} is also called in several places, wherever it is + known that the QXmlNodeModelIndex being requested is for a directory + or a file and not for an attribute. The convenience function takes + only the QFileInfo parameter and calls the other \l{main toNodeIndex} + {toNodeIndex()}, after obtaining either the Directory or File node + type directly from the QFileInfo: + + \target toNodeIndex of convenience + \snippet examples/xmlpatterns/filetree/filetree.cpp 0 + + Note that the auxiliary vector \c{m_names} is accessed using the + \l{Node_Type} {node type}, for example: + + \snippet examples/xmlpatterns/filetree/filetree.cpp 3 + + Most of the virtual functions in the callback interface are as + simple as the ones described so far, but the callback function used + for traversing (and building) the node model is more complex. + + \section3 Building And Traversing The Node Model + + The node model in \c{FileTree} is not fully built before the query + engine begins evaluating the query. In fact, when the query engine + begins evaluating its first query, the only node in the node model + is the one representing the root directory for the selected part of + the file system. See \l{The UI Class: MainWindow} below for details + about how the UI triggers creation of the model. + + The query engine builds the node model incrementally each time it + calls the \l{next node on axis} {nextFromSimpleAxis()} callback + function, as it traverses the node model to evaluate a query. Thus + the query engine only builds the region of the node model that it + needs for evaluating the query. + + \l{next node on axis} {nextFromSimpleAxis()} takes an + \l{QAbstractXmlNodeModel::SimpleAxis} {axis identifier} and a + \l{QXmlNodeModelIndex} {node identifier} as parameters. The + \l{QXmlNodeModelIndex} {node identifier} represents the \e{context + node} (i.e. the query engine's current location in the model), and + the \l{QAbstractXmlNodeModel::SimpleAxis} {axis identifier} + represents the direction we want to move from the context node. The + function finds the appropriate next node and returns its + QXmlNodeModelIndex. + + \l{next node on axis} {nextFromSimpleAxis()} is where most of the + work of implementing a custom node model will be required. The + obvious way to do it is to use a switch statement with a case for + each \l{QAbstractXmlNodeModel::SimpleAxis} {axis}. + + \target next node on axis + \snippet examples/xmlpatterns/filetree/filetree.cpp 4 + + The first thing this function does is call \l{to file info} + {toFileInfo()} to get the QFileInfo of the context node. The use of + QVector::at() here is guaranteed to succeed because the context node + must already be in the node model, and hence must have a QFileInfo + in \c{m_fileInfos}. + + \target to file info + \snippet examples/xmlpatterns/filetree/filetree.cpp 6 + + The \l{QAbstractXmlNodeModel::Parent} {Parent} case looks up the + context node's parent by constructing a QFileInfo from the context + node's \l{QFileInfo::absoluteFilePath()} {path} and passing it to + \l{main toNodeIndex} {toNodeIndex()} to find the QFileInfo in + \c{m_fileInfos}. + + The \l{QAbstractXmlNodeModel::FirstChild} {FirstChild} case requires + that the context node must be a directory, because a file doesn't + have children. If the context node is not a directory, a default + constructed QXmlNodeModelIndex is returned. Otherwise, + QDir::entryInfoList() constructs a QFileInfoList of the context + node's children. The first QFileInfo in the list is passed to + \l{toNodeIndex of convenience} {toNodeIndex()} to get its + QXmlNodeModelIndex. Note that this will add the child to the node + model, if it isn't in the model yet. + + The \l{QAbstractXmlNodeModel::PreviousSibling} {PreviousSibling} and + \l{QAbstractXmlNodeModel::NextSibling} {NextSibling} cases call the + \l{nextSibling helper} {nextSibling() helper function}. It takes the + QXmlNodeModelIndex of the context node, the QFileInfo of the context + node, and an offest of +1 or -1. The context node is a child of some + parent, so the function gets the parent and then gets the child list + for the parent. The child list is searched to find the QFileInfo of + the context node. It must be there. Then the offset is applied, -1 + for the previous sibling and +1 for the next sibling. The resulting + index is passed to \l{toNodeIndex of convenience} {toNodeIndex()} to + get its QXmlNodeModelIndex. Note again that this will add the + sibling to the node model, if it isn't in the model yet. + + \target nextSibling helper + \snippet examples/xmlpatterns/filetree/filetree.cpp 5 + + \section2 The UI Class: MainWindow + + The example's UI is a conventional Qt GUI application inheriting + QMainWindow and the Ui_MainWindow base class generated by + \l{Qt Designer Manual} {Qt Designer}. + + \snippet examples/xmlpatterns/filetree/mainwindow.h 0 + + It contains the custom node model (\c{m_fileTree}) and an instance + of QXmlNodeModelIndex (\c{m_fileNode}) used for holding the node + index for the root of the file system subtree. \c{m_fileNode} will + be bound to a $variable in the XQuery to be evaluated. + + Two actions of interest are handled by slot functions: \l{Selecting + A Directory To Model} and \l{Selecting And Running An XQuery}. + + \section3 Selecting A Directory To Model + + The user selects \c{File->Open Directory} to choose a directory to + be loaded into the custom node model. Choosing a directory signals + the \c{on_actionOpenDirectory_triggered()} slot: + + \snippet examples/xmlpatterns/filetree/mainwindow.cpp 1 + + The slot function simply calls the private function + \c{loadDirectory()} with the path of the chosen directory: + + \target the standard code pattern + \snippet examples/xmlpatterns/filetree/mainwindow.cpp 4 + + \c{loadDirectory()} demonstrates a standard code pattern for using + QtXmlPatterns programatically. First it gets the node model index + for the root of the selected directory. Then it creates an instance + of QXmlQuery and calls QXmlQuery::bindVariable() to bind the node + index to the XQuery variable \c{$fileTree}. It then calls + QXmlQuery::setQuery() to load the XQuery text. + + \note QXmlQuery::bindVariable() must be called \e before calling + QXmlQuery::setQuery(), which loads and parses the XQuery text and + must have access to the variable binding as the text is parsed. + + The next lines create an output device for outputting the query + result, which is then used to create a QXmlFormatter to format the + query result as XML. QXmlQuery::evaluateTo() is called to run the + query, and the formatted XML output is displayed in the left panel + of the UI window. + + Finally, the private function \l{Selecting And Running An XQuery} + {evaluateResult()} is called to run the currently selected XQuery + over the custom node model. + + \note As described in \l{Building And Traversing The Node Model}, + the \c FileTree class wants to build the custom node model + incrementally as it evaluates the XQuery. But, because the + \c{loadDirectory()} function runs the \c{wholeTree.xq} XQuery, it + actually builds the entire node model anyway. See \l{Node Model + Building Strategy} for a discussion about building your custom node + model. + + \section3 Selecting And Running An XQuery + + The user chooses an XQuery from the menu in the combobox on the + right. Choosing an XQuery signals the + \c{on_queryBox_currentIndexChanged()} slot: + + \snippet examples/xmlpatterns/filetree/mainwindow.cpp 2 + + The slot function opens and loads the query file and then calls the + private function \c{evaluateResult()} to run the query: + + \snippet examples/xmlpatterns/filetree/mainwindow.cpp 3 + + \c{evaluateResult()} is a second example of the same code pattern + shown in \l{the standard code pattern} {loadDirectory()}. In this + case, it runs the XQuery currently selected in the combobox instead + of \c{qrc:/queries/wholeTree.xq}, and it outputs the query result to + the panel on the lower right of the UI window. + + \section2 Node Model Building Strategy + + We saw that the \l{The Custom Node Model Class: FileTree} {FileTree} + tries to build its custom node model incrementally, but we also saw + that the \l{the standard code pattern} {MainWindow::loadDirectory()} + function in the UI class immediately subverts the incremental build + by running the \c{wholeTree.xq} XQuery, which traverses the entire + selected directory, thereby causing the entire node model to be + built. + + If we want to preserve the incremental build capability of the + \c{FileTree} class, we can strip the running of \c{wholeTree.xq} out + of \l{the standard code pattern} {MainWindow::loadDirectory()}: + + \snippet examples/xmlpatterns/filetree/mainwindow.cpp 5 + \snippet examples/xmlpatterns/filetree/mainwindow.cpp 6 + + Note, however, that \c{FileTree} doesn't have the capability of + deleting all or part of the node model. The node model, once built, + is only deleted when the \c{FileTree} instance goes out of scope. + + In this example, each element node in the node model represents a + directory or a file in the computer's file system, and each node is + represented by an instance of QFileInfo. An instance of QFileInfo is + not costly to produce, but you might imagine a node model where + building new nodes is very costly. In such cases, the capability to + build the node model incrementally is important, because it allows + us to only build the region of the model we need for evaluating the + query. In other cases, it will be simpler to just build the entire + node model. + +*/ diff --git a/doc/src/examples/findfiles.qdoc b/doc/src/examples/findfiles.qdoc new file mode 100644 index 0000000..db41f43 --- /dev/null +++ b/doc/src/examples/findfiles.qdoc @@ -0,0 +1,263 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example dialogs/findfiles + \title Find Files Example + + The Find Files example shows how to use QProgressDialog to provide + feedback on the progress of a slow operation. The example also + shows how to use QFileDialog to facilitate browsing, how to use + QTextStream's streaming operators to read a file, and how to use + QTableWidget to provide standard table display facilities for + applications. In addition, files can be opened using the + QDesktopServices class. + + \image findfiles-example.png Screenshot of the Find Files example + + With the Find Files application the user can search for files in a + specified directory, matching a specified file name (using wild + cards if appropiate) and containing a specified text. + + The user is provided with a \gui Browse option, and the result of + the search is displayed in a table with the names of the files + found and their sizes. In addition the application provides a + total count of the files found. + + \section1 Window Class Definition + + The \c Window class inherits QWidget, and is the main application + widget. It shows the search options, and displays the search + results. + + \snippet examples/dialogs/findfiles/window.h 0 + + We need two private slots: The \c browse() slot is called whenever + the user wants to browse for a directory to search in, and the \c + find() slot is called whenever the user requests a search to be + performed by pressing the \gui Find button. + + In addition we declare several private functions: We use the \c + findFiles() function to search for files matching the user's + specifications, we call the \c showFiles() function to display the + results, and we use \c createButton(), \c createComboBox() and \c + createFilesTable() when we are constructing the widget. + + \section1 Window Class Implementation + + In the constructor we first create the application's widgets. + + \snippet examples/dialogs/findfiles/window.cpp 0 + + We create the application's buttons using the private \c + createButton() function. Then we create the comboboxes associated + with the search specifications, using the private \c + createComboBox() function. We also create the application's labels + before we use the private \c createFilesTable() function to create + the table displaying the search results. + + \snippet examples/dialogs/findfiles/window.cpp 1 + + Then we add all the widgets to a main layout using QGridLayout. We + have, however, put the \c Find and \c Quit buttons and a + stretchable space in a separate QHBoxLayout first, to make the + buttons appear in the \c Window widget's bottom right corner. + + \snippet examples/dialogs/findfiles/window.cpp 2 + + The \c browse() slot presents a file dialog to the user, using the + QFileDialog class. QFileDialog enables a user to traverse the file + system in order to select one or many files or a directory. The + easiest way to create a QFileDialog is to use the convenience + static functions. + + Here we use the static QFileDialog::getExistingDirectory() + function which returns an existing directory selected by the + user. Then we display the directory in the directory combobox + using the QComboBox::addItem() function, and updates the current + index. + + QComboBox::addItem() adds an item to the combobox with the given + text (if it is not already present in the list), and containing + the specified userData. The item is appended to the list of + existing items. + + \snippet examples/dialogs/findfiles/window.cpp 3 + + The \c find() slot is called whenever the user requests a new + search by pressing the \gui Find button. + + First we eliminate any previous search results by setting the + table widgets row count to zero. Then we retrieve the + specified file name, text and directory path from the respective + comboboxes. + + \snippet examples/dialogs/findfiles/window.cpp 4 + + We use the directory's path to create a QDir; the QDir class + provides access to directory structures and their contents. We + create a list of the files (contained in the newly created QDir) + that match the specified file name. If the file name is empty + the list will contain all the files in the directory. + + Then we search through all the files in the list, using the private + \c findFiles() function, eliminating the ones that don't contain + the specified text. And finally, we display the results using the + private \c showFiles() function. + + If the user didn't specify any text, there is no reason to search + through the files, and we display the results immediately. + + \image findfiles_progress_dialog.png Screenshot of the Progress Dialog + + \snippet examples/dialogs/findfiles/window.cpp 5 + + In the private \c findFiles() function we search through a list of + files, looking for the ones that contain a specified text. This + can be a very slow operation depending on the number of files as + well as their sizes. In case there are a large number of files, or + there exists some large files on the list, we provide a + QProgressDialog. + + The QProgressDialog class provides feedback on the progress of a + slow operation. It is used to give the user an indication of how + long an operation is going to take, and to demonstrate that the + application has not frozen. It can also give the user an + opportunity to abort the operation. + + \snippet examples/dialogs/findfiles/window.cpp 6 + + We run through the files, one at a time, and for each file we + update the QProgressDialog value. This property holds the current + amount of progress made. We also update the progress dialog's + label. + + Then we call the QCoreApplication::processEvents() function using + the QApplication object. In this way we interleave the display of + the progress made with the process of searching through the files + so the application doesn't appear to be frozen. + + The QApplication class manages the GUI application's control flow + and main settings. It contains the main event loop, where all + events from the window system and other sources are processed and + dispatched. QApplication inherits QCoreApplication. The + QCoreApplication::processEvents() function processes all pending + events according to the specified QEventLoop::ProcessEventFlags + until there are no more events to process. The default flags are + QEventLoop::AllEvents. + + \snippet examples/dialogs/findfiles/window.cpp 7 + + After updating the QProgressDialog, we create a QFile using the + QDir::absoluteFilePath() function which returns the absolute path + name of a file in the directory. We open the file in read-only + mode, and read one line at a time using QTextStream. + + The QTextStream class provides a convenient interface for reading + and writing text. Using QTextStream's streaming operators, you can + conveniently read and write words, lines and numbers. + + For each line we read we check if the QProgressDialog has been + canceled. If it has, we abort the operation, otherwise we check if + the line contains the specified text. When we find the text within + one of the files, we add the file's name to a list of found files + that contain the specified text, and start searching a new file. + + Finally, we return the list of the files found. + + \snippet examples/dialogs/findfiles/window.cpp 8 + + Both the \c findFiles() and \c showFiles() functions are called from + the \c find() slot. In the \c showFiles() function we run through + the provided list of file names, adding each file name to the + first column in the table widget and retrieving the file's size using + QFile and QFileInfo for the second column. + + We also update the total number of files found. + + \snippet examples/dialogs/findfiles/window.cpp 9 + + The private \c createButton() function is called from the + constructor. We create a QPushButton with the provided text, + connect it to the provided slot, and return a pointer to the + button. + + \snippet examples/dialogs/findfiles/window.cpp 10 + + The private \c createComboBox() function is also called from the + contructor. We create a QComboBox with the given text, and make it + editable. + + When the user enters a new string in an editable combobox, the + widget may or may not insert it, and it can insert it in several + locations, depending on the QComboBox::InsertPolicy. The default + policy is is QComboBox::InsertAtBottom. + + Then we add the provided text to the combobox, and specify the + widget's size policies, before we return a pointer to the + combobox. + + \snippet examples/dialogs/findfiles/window.cpp 11 + + The private \c createFilesTable() function is called from the + constructor. In this function we create the QTableWidget that + will display the search results. We set its horizontal headers and + their resize mode. + + QTableWidget inherits QTableView which provides a default + model/view implementation of a table view. The + QTableView::horizontalHeader() function returns the table view's + horizontal header as a QHeaderView. The QHeaderView class provides + a header row or header column for item views, and the + QHeaderView::setResizeMode() function sets the constraints on how + the section in the header can be resized. + + Finally, we hide the QTableWidget's vertical headers using the + QWidget::hide() function, and remove the default grid drawn for + the table using the QTableView::setShowGrid() function. + + \snippet examples/dialogs/findfiles/window.cpp 12 + + The \c openFileOfItem() slot is invoked when the user double + clicks on a cell in the table. The QDesktopServices::openUrl() + knows how to open a file given the file name. +*/ + diff --git a/doc/src/examples/flowlayout.qdoc b/doc/src/examples/flowlayout.qdoc new file mode 100644 index 0000000..557ba39 --- /dev/null +++ b/doc/src/examples/flowlayout.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example layouts/flowlayout + \title Flow Layout Example + + The Flow Layout example demonstrates a custom layout that arranges child widgets from + left to right and top to bottom in a top-level widget. + + \image flowlayout-example.png +*/ diff --git a/doc/src/examples/fontsampler.qdoc b/doc/src/examples/fontsampler.qdoc new file mode 100644 index 0000000..1fbb879 --- /dev/null +++ b/doc/src/examples/fontsampler.qdoc @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example painting/fontsampler + \title Font Sampler Example + + The Font Sampler example shows how to preview and print multi-page documents. + + \image fontsampler-example.png +*/ diff --git a/doc/src/examples/formextractor.qdoc b/doc/src/examples/formextractor.qdoc new file mode 100644 index 0000000..b98f5bd --- /dev/null +++ b/doc/src/examples/formextractor.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example webkit/formextractor + \title Form Extractor Example + + The Form Extractor example shows how to use QWebFrame with JavaScript to + extract form data. + + \image formextractor-example.png + +*/ diff --git a/doc/src/examples/fortuneclient.qdoc b/doc/src/examples/fortuneclient.qdoc new file mode 100644 index 0000000..cbdd164 --- /dev/null +++ b/doc/src/examples/fortuneclient.qdoc @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example network/fortuneclient + \title Fortune Client Example + + The Fortune Client example shows how to create a client for a simple + network service using QTcpSocket. It is intended to be run alongside the + \l{network/fortuneserver}{Fortune Server} example or + the \l{network/threadedfortuneserver}{Threaded Fortune Server} example. + + \image fortuneclient-example.png Screenshot of the Fortune Client example + + This example uses a simple QDataStream-based data transfer protocol to + request a line of text from a fortune server (from the + \l{network/fortuneserver}{Fortune Server} example). The client requests a + fortune by simply connecting to the server. The server then responds with + a 16-bit (quint16) integer containing the length of the fortune text, + followed by a QString. + + QTcpSocket supports two general approaches to network programming: + + \list + + \o \e{The asynchronous (non-blocking) approach.} Operations are scheduled + and performed when control returns to Qt's event loop. When the operation + is finished, QTcpSocket emits a signal. For example, + QTcpSocket::connectToHost() returns immediately, and when the connection + has been established, QTcpSocket emits + \l{QTcpSocket::connected()}{connected()}. + + \o \e{The synchronous (blocking) approach.} In non-GUI and multithreaded + applications, you can call the \c waitFor...() functions (e.g., + QTcpSocket::waitForConnected()) to suspend the calling thread until the + operation has completed, instead of connecting to signals. + + \endlist + + In this example, we will demonstrate the asynchronous approach. The + \l{network/blockingfortuneclient}{Blocking Fortune Client} example + illustrates the synchronous approach. + + Our class contains some data and a few private slots: + + \snippet examples/network/fortuneclient/client.h 0 + + Other than the widgets that make up the GUI, the data members include a + QTcpSocket pointer, a copy of the fortune text currently displayed, and + the size of the packet we are currently reading (more on this later). + + The socket is initialized in the Client constructor. We'll pass the main + widget as parent, so that we won't have to worry about deleting the + socket: + + \snippet examples/network/fortuneclient/client.cpp 0 + \dots + \snippet examples/network/fortuneclient/client.cpp 1 + + The only QTcpSocket signals we need in this example are + QTcpSocket::readyRead(), signifying that data has been received, and + QTcpSocket::error(), which we will use to catch any connection errors: + + \dots + \snippet examples/network/fortuneclient/client.cpp 3 + \dots + \snippet examples/network/fortuneclient/client.cpp 5 + + Clicking the \gui{Get Fortune} button will invoke the \c + requestNewFortune() slot: + + \snippet examples/network/fortuneclient/client.cpp 6 + + In this slot, we initialize \c blockSize to 0, preparing to read a new block + of data. Because we allow the user to click \gui{Get Fortune} before the + previous connection finished closing, we start off by aborting the + previous connection by calling QTcpSocket::abort(). (On an unconnected + socket, this function does nothing.) We then proceed to connecting to the + fortune server by calling QTcpSocket::connectToHost(), passing the + hostname and port from the user interface as arguments. + + As a result of calling \l{QTcpSocket::connectToHost()}{connectToHost()}, + one of two things can happen: + + \list + \o \e{The connection is established.} In this case, the server will send us a + fortune. QTcpSocket will emit \l{QTcpSocket::readyRead()}{readyRead()} + every time it receives a block of data. + + \o \e{An error occurs.} We need to inform the user if the connection + failed or was broken. In this case, QTcpSocket will emit + \l{QTcpSocket::error()}{error()}, and \c Client::displayError() will be + called. + \endlist + + Let's go through the \l{QTcpSocket::error()}{error()} case first: + + \snippet examples/network/fortuneclient/client.cpp 13 + + We pop up all errors in a dialog using + QMessageBox::information(). QTcpSocket::RemoteHostClosedError is silently + ignored, because the fortune server protocol ends with the server closing + the connection. + + Now for the \l{QTcpSocket::readyRead()}{readyRead()} alternative. This + signal is connected to \c Client::readFortune(): + + \snippet examples/network/fortuneclient/client.cpp 8 + \codeline + \snippet examples/network/fortuneclient/client.cpp 10 + + The protocol is based on QDataStream, so we start by creating a stream + object, passing the socket to QDataStream's constructor. We then + explicitly set the protocol version of the stream to QDataStream::Qt_4_0 + to ensure that we're using the same version as the fortune server, no + matter which version of Qt the client and server use. + + Now, TCP is based on sending a stream of data, so we cannot expect to get + the entire fortune in one go. Especially on a slow network, the data can + be received in several small fragments. QTcpSocket buffers up all incoming + data and emits \l{QTcpSocket::readyRead()}{readyRead()} for every new + block that arrives, and it is our job to ensure that we have received all + the data we need before we start parsing. The server's response starts + with the size of the packet, so first we need to ensure that we can read + the size, then we will wait until QTcpSocket has received the full packet. + + \snippet examples/network/fortuneclient/client.cpp 11 + \codeline + \snippet examples/network/fortuneclient/client.cpp 12 + + We proceed by using QDataStream's streaming operator to read the fortune + from the socket into a QString. Once read, we can call QLabel::setText() + to display the fortune. + + \sa {Fortune Server Example}, {Blocking Fortune Client Example} +*/ diff --git a/doc/src/examples/fortuneserver.qdoc b/doc/src/examples/fortuneserver.qdoc new file mode 100644 index 0000000..e6a7f85 --- /dev/null +++ b/doc/src/examples/fortuneserver.qdoc @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example network/fortuneserver + \title Fortune Server Example + + The Fortune Server example shows how to create a server for a simple + network service. It is intended to be run alongside the + \l{network/fortuneclient}{Fortune Client} example or the the + \l{network/blockingfortuneclient}{Blocking Fortune Client} example. + + \image fortuneserver-example.png Screenshot of the Fortune Server example + + This example uses QTcpServer to accept incoming TCP connections, and a + simple QDataStream based data transfer protocol to write a fortune to the + connecting client (from the \l{network/fortuneclient}{Fortune Client} + example), before closing the connection. + + \snippet examples/network/fortuneserver/server.h 0 + + The server is implemented using a simple class with only one slot, for + handling incoming connections. + + \snippet examples/network/fortuneserver/server.cpp 1 + + In its constructor, our Server object calls QTcpServer::listen() to set up + a QTcpServer to listen on all addresses, on an arbitrary port. In then + displays the port QTcpServer picked in a label, so that user knows which + port the fortune client should connect to. + + \snippet examples/network/fortuneserver/server.cpp 2 + + Our server generates a list of random fortunes that is can send to + connecting clients. + + \snippet examples/network/fortuneserver/server.cpp 3 + + When a client connects to our server, QTcpServer will emit + QTcpServer::newConnection(). In turn, this will invoke our + sendFortune() slot: + + \snippet examples/network/fortuneserver/server.cpp 4 + + The purpose of this slot is to select a random line from our list of + fortunes, encode it into a QByteArray using QDataStream, and then write it + to the connecting socket. This is a common way to transfer binary data + using QTcpSocket. First we create a QByteArray and a QDataStream object, + passing the bytearray to QDataStream's constructor. We then explicitly set + the protocol version of QDataStream to QDataStream::Qt_4_0 to ensure that + we can communicate with clients from future versions of Qt. (See + QDataStream::setVersion().) + + \snippet examples/network/fortuneserver/server.cpp 6 + + At the start of our QByteArray, we reserve space for a 16 bit integer that + will contain the total size of the data block we are sending. We continue + by streaming in a random fortune. Then we seek back to the beginning of + the QByteArray, and overwrite the reserved 16 bit integer value with the + total size of the array. By doing this, we provide a way for clients to + verify how much data they can expect before reading the whole packet. + + \snippet examples/network/fortuneserver/server.cpp 7 + + We then call QTcpServer::newPendingConnection(), which returns the + QTcpSocket representing the server side of the connection. By connecting + QTcpSocket::disconnected() to QObject::deleteLater(), we ensure that the + socket will be deleted after disconnecting. + + \snippet examples/network/fortuneserver/server.cpp 8 + + The encoded fortune is written using QTcpSocket::write(), and we finally + call QTcpSocket::disconnectFromHost(), which will close the connection + after QTcpSocket has finished writing the fortune to the network. Because + QTcpSocket works asynchronously, the data will be written after this + function returns, and control goes back to Qt's event loop. The socket + will then close, which in turn will cause QObject::deleteLater() to delete + it. + + \sa {Fortune Client Example}, {Threaded Fortune Server Example} + */ diff --git a/doc/src/examples/framebufferobject.qdoc b/doc/src/examples/framebufferobject.qdoc new file mode 100644 index 0000000..3220641 --- /dev/null +++ b/doc/src/examples/framebufferobject.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example opengl/framebufferobject + \title Framebuffer Object Example + + The Framebuffer Object example demonstrates how to use the + QGLFramebufferObject class to render into an off-screen buffer and + use the contents as a texture in a QGLWidget. + + \image framebufferobject-example.png +*/ diff --git a/doc/src/examples/framebufferobject2.qdoc b/doc/src/examples/framebufferobject2.qdoc new file mode 100644 index 0000000..721706a --- /dev/null +++ b/doc/src/examples/framebufferobject2.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example opengl/framebufferobject2 + \title Framebuffer Object 2 Example + + The Framebuffer Object 2 example demonstrates how to use the + QGLFramebufferObject class to render into an off-screen buffer and + use the contents as a texture in a QGLWidget. + + \image framebufferobject2-example.png +*/ diff --git a/doc/src/examples/fridgemagnets.qdoc b/doc/src/examples/fridgemagnets.qdoc new file mode 100644 index 0000000..de95b52 --- /dev/null +++ b/doc/src/examples/fridgemagnets.qdoc @@ -0,0 +1,374 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example draganddrop/fridgemagnets + \title Fridge Magnets Example + + The Fridge Magnets example shows how to supply more than one type + of MIME-encoded data with a drag and drop operation. + + \image fridgemagnets-example.png + + With this application the user can play around with a collection + of fridge magnets, using drag and drop to form new sentences from + the words on the magnets. The example consists of two classes: + + \list + \o \c DragLabel is a custom widget representing one + single fridge magnet. + \o \c DragWidget provides the main application window. + \endlist + + We will first take a look at the \c DragLabel class, then we will + examine the \c DragWidget class. + + \section1 DragLabel Class Definition + + Each fridge magnet is represented by an instance of the \c + DragLabel class: + + \snippet examples/draganddrop/fridgemagnets/draglabel.h 0 + + Each instance of this QLabel subclass will be used to display an + pixmap generated from a text string. Since we cannot store both + text and a pixmap in a standard label, we declare a private variable + to hold the original text, and we define an additional member + function to allow it to be accessed. + + \section1 DragLabel Class Implementation + + In the \c DragLabel constructor, we first create a QImage object + on which we will draw the fridge magnet's text and frame: + + \snippet examples/draganddrop/fridgemagnets/draglabel.cpp 0 + + Its size depends on the current font size, and its format is + QImage::Format_ARGB32_Premultiplied; i.e., the image is stored + using a premultiplied 32-bit ARGB format (0xAARRGGBB). + + We then construct a font object that uses the application's + default font, and set its style strategy. The style strategy tells + the font matching algorithm what type of fonts should be used to + find an appropriate default family. The QFont::ForceOutline forces + the use of outline fonts. + + To draw the text and frame onto the image, we use the QPainter + class. QPainter provides highly optimized methods to do most of + the drawing GUI programs require. It can draw everything from + simple lines to complex shapes like pies and chords. It can also + draw aligned text and pixmaps. + + \snippet examples/draganddrop/fridgemagnets/draglabel.cpp 1 + + A painter can be activated by passing a paint device to the + constructor, or by using the \l{QPainter::}{begin()} method as we + do in this example. The \l{QPainter::}{end()} method deactivates + it. Note that the latter function is called automatically upon + destruction when the painter is actived by its constructor. The + QPainter::Antialiasing render hint ensures that the paint engine + will antialias the edges of primitives if possible. + + When the painting is done, we convert our image to a pixmap using + QPixmap's \l {QPixmap::}{fromImage()} method. This method also + takes an optional flags argument, and converts the given image to + a pixmap using the specified flags to control the conversion (the + flags argument is a bitwise-OR of the Qt::ImageConversionFlags; + passing 0 for flags sets all the default options). + + \snippet examples/draganddrop/fridgemagnets/draglabel.cpp 2 + + Finally, we set the label's \l{QLabel::pixmap}{pixmap property} + and store the label's text for later use. + + \e{Note that setting the pixmap clears any previous content, including + any text previously set using QLabel::setText(), and disables + the label widget's buddy shortcut, if any.} + + \section1 DragWidget Class Definition + + The \c DragWidget class inherits QWidget, providing support for + drag and drop operations: + + \snippet examples/draganddrop/fridgemagnets/dragwidget.h 0 + + To make the widget responsive to drag and drop operations, we simply + reimplement the \l{QWidget::}{dragEnterEvent()}, + \l{QWidget::}{dragMoveEvent()} and \l{QWidget::}{dropEvent()} event + handlers inherited from QWidget. + + We also reimplement \l{QWidget::}{mousePressEvent()} to make the + widget responsive to mouse clicks. This is where we will write code + to start drag and drop operations. + + \section1 DragWidget Class Implementation + + In the constructor, we first open the file containing the words on + our fridge magnets: + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 0 + + QFile is an I/O device for reading and writing text and binary + files and resources, and may be used by itself or in combination + with QTextStream or QDataStream. We have chosen to read the + contents of the file using the QTextStream class that provides a + convenient interface for reading and writing text. + + We then create the fridge magnets. As long as there is data (the + QTextStream::atEnd() method returns true if there is no more data + to be read from the stream), we read one line at a time using + QTextStream's \l {QTextStream::}{readLine()} method. + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 1 + + For each line, we create a \c DragLabel object using the read line + as text, we calculate its position and ensure that it is visible by + calling the QWidget::show() method. We set the Qt::WA_DeleteOnClose + attribute on each label to ensure that any unused labels will be + deleted; we will need to create new labels and delete old ones when + they are dragged around, and this ensures that the example does not + leak memory. + + We also set the \c FridgeMagnets widget's palette, minimum size + and window title. + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 2 + + Finally, to enable our user to move the fridge magnets around, we + must also set the \c FridgeMagnets widget's + \l{QWidget::acceptDrops}{acceptDrops} property. + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 3 + + Setting this property to true announces to the system that this + widget \e may be able to accept drop events (events that are sent + when drag and drop actions are completed). Later, we will + implement the functions that ensure that the widget accepts the + drop events it is interested in. + + \section2 Dragging + + Let's take a look at the \l{QWidget::}{mousePressEvent()} event + handler, where drag and drop operations begin: + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 13 + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 14 + + Mouse events occur when a mouse button is pressed or released + inside a widget, or when the mouse cursor is moved. By + reimplementing the \l{QWidget::}{mousePressEvent()} method we + ensure that we will receive mouse press events for the widget + containing the fridge magnets. + + Whenever we receive such an event, we first check to see if the + position of the click coincides with one of the labels. If not, + we simply return. + + If the user clicked a label, we determine the position of the + \e{hot spot} (the position of the click relative to the top-left + corner of the label). We create a byte array to store the label's + text and the hot spot, and we use a QDataStream object to stream + the data into the byte array. + + With all the information in place, we create a new QMimeData object. + As mentioned above, QMimeData objects associate the data that they + hold with the corresponding MIME types to ensure that information + can be safely transferred between applications. The + \l{QMimeData::}{setData()} method sets the data associated with a + given MIME type. In our case, we associate our item data with the + custom \c application/x-fridgemagnet type. + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 15 + + Note that we also associate the magnet's text with the + \c text/plain MIME type using QMimeData's \l{QMimeData::}{setText()} + method. Below, we will see how our widget detects both these MIME + types with its event handlers. + + Finally, we create a QDrag object. It is the QDrag class that + handles most of the details of a drag and drop operation, + providing support for MIME-based drag and drop data transfer. The + data to be transferred by the drag and drop operation is contained + in a QMimeData object. When we call QDrag's + \l{QDrag::}{setMimeData()} method the ownership of our item data is + transferred to the QDrag object. + + We call the \l{QDrag::}{setPixmap()} function to set the pixmap used + to represent the data during the drag and drop operation. + Typically, this pixmap shows an icon that represents the MIME type + of the data being transferred, but any pixmap can be used. In this + example, we simply use the pixmap used by the label itself to make + it look like the fridge magnet itself is being moved. + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 16 + + We also specify the cursor's hot spot, its position relative to the + top-level corner of the drag pixmap, to be the point we calculated + above. This makes the process of dragging the label feel more natural + because the cursor always points to the same place on the label + during the drag operation. + + We start the drag operation using QDrag's \l{QDrag::}{exec()} function, + requesting that the magnet is copied when the drag is completed. + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 17 + + The function returns the drop action actually performed by the user + (this can be either a copy or a move action in this case); if this + action is equal to Qt::MoveAction we will close the activated + fridge magnet widget because we will create a new one to replace it + (see the \l{drop}{dropEvent()} implementation). Otherwise, if + the drop is outside our main widget, we simply show the widget in + its original position. + + \section2 Dropping + + When a a drag and drop action enters our widget, we will receive a + drag enter \e event. QDragEnterEvent inherits most of its + functionality from QDragMoveEvent, which in turn inherits most of + its functionality from QDropEvent. Note that we must accept this + event in order to receive the drag move events that are sent while + the drag and drop action is in progress. The drag enter event is + always immediately followed by a drag move event. + + In our \c dragEnterEvent() implementation, we first determine + whether we support the event's MIME type or not: + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 4 + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 5 + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 6 + + If the type is \c application/x-fridgemagnet and the event + origins from any of this application's fridge magnet widgets, we + first set the event's drop action using the + QDropEvent::setDropAction() method. An event's drop action is the + action to be performed on the data by the target. Qt::MoveAction + indicates that the data is moved from the source to the target. + + Then we call the event's \l {QDragMoveEvent::}{accept()} method to + indicate that we have handled the event. In general, unaccepted + events might be propagated to the parent widget. If the event + origins from any other widget, we simply accept the proposed + action. + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 7 + + We also accept the proposed action if the event's MIME type is \c + text/plain, i.e., if QMimeData::hasText() returns true. If the + event has any other type, on the other hand, we call the event's + \l {QDragMoveEvent::}{ignore()} method allowing the event to be + propagated further. + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 8 + + Drag move events occur when the cursor enters a widget, when it + moves within the widget, and when a modifier key is pressed on the + keyboard while the widget has focus. Our widget will receive drag + move events repeatedly while a drag is within its boundaries. We + reimplement the \l {QWidget::}{dragMoveEvent()} method, and + examine the event in the exact same way as we did with drag enter + events. + + Note that the \l{QWidget::}{dropEvent()} event handler behaves + slightly differently: We first get hold of the event's MIME + data. + + \target drop + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 9 + + The QMimeData class provides a container for data that + records information about its MIME type. QMimeData objects + associate the data that they hold with the corresponding MIME + types to ensure that information can be safely transferred between + applications, and copied around within the same application. + + We retrieve the data associated with the \c application/x-fridgemagnet + MIME type using a data stream in order to create a new \c DragLabel + object. + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 10 + + The QDataStream class provides serialization of binary data to a + QIODevice (a data stream is a binary stream of encoded information + which is completely independent of the host computer's operating + system, CPU or byte order). + + Finally, we create a label and move it to the event's position: + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 11 + + If the source of the event is also the widget receiving the + drop event, we set the event's drop action to Qt::MoveAction and + call the event's \l{QDragMoveEvent::}{accept()} + method. Otherwise, we simply accept the proposed action. This + means that labels are moved rather than copied in the same + window. However, if we drag a label to a second instance of the + Fridge Magnets example, the default action is to copy it, leaving + the original in the first instance. + + If the event's MIME type is \c text/plain (i.e., if + QMimeData::hasText() returns true) we retrieve its text and split + it into words. For each word we create a new \c DragLabel action, + and show it at the event's position plus an offset depending on + the number of words in the text. In the end we accept the proposed + action. This lets the user drop selected text from a text editor or + Web browser onto the widget to add more fridge magnets. + + \snippet examples/draganddrop/fridgemagnets/dragwidget.cpp 12 + + If the event has any other type, we call the event's + \l{QDragMoveEvent::}{ignore()} method allowing the event to be + propagated further. + + \section1 Summary + + We set our main widget's \l{QWidget::}{acceptDrops} property + and reimplemented QWidget's \l{QWidget::}{dragEnterEvent()}, + \l{QWidget::}{dragMoveEvent()} and \l{QWidget::}{dropEvent()} event + handlers to support content dropped on our widget. + + In addition, we reimplemented the \l{QWidget::}{mousePressEvent()} + function to let the user pick up fridge magnets in the first place. + + Because data is communicated using drag and drop operations and + encoded using MIME types, you can run more than one instance of this + example, and transfer magnets between them. +*/ diff --git a/doc/src/examples/ftp.qdoc b/doc/src/examples/ftp.qdoc new file mode 100644 index 0000000..9cc9cd1 --- /dev/null +++ b/doc/src/examples/ftp.qdoc @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example network/ftp + \title FTP Example + + The FTP example demonstrates a simple FTP client that can be used + to list the available files on an FTP server and download them. + + \image ftp-example.png + + The user of the example can enter the address or hostname of an + FTP server in the \gui {Ftp Server} line edit, and then push the + \gui Connect button to connect to it. A list of the server's + top-level directory is then presented in the \gui {File List} tree + view. If the selected item in the view is a file, the user can + download it by pushing the \gui Download button. An item + representing a directory can be double clicked with the mouse to + show the contents of that directory in the view. + + The functionality required for the example is implemented in the + QFtp class, which provides an easy, high-level interface to the + file transfer protocol. FTP operations are requested through + \l{QFtp::Command}s. The operations are asynchronous. QFtp will + notify us through signals when commands are started and finished. + + We have one class, \c FtpWindow, which sets up the GUI and handles + the FTP functionality. We will now go through its definition and + implementation - focusing on the code concerning FTP. The code for + managing the GUI is explained in other examples. + + \section1 FtpWindow Class Definition + + The \c FtpWindow class displays a window, in which the user can + connect to and browse the contents of an FTP server. The slots of + \c FtpWindow are connected to its widgets, and contain the + functionality for managing the FTP connection. We also connect to + signals in QFtp, which tells us when the + \l{QFtp::Command}{commands} we request are finished, the progress + of current commands, and information about files on the server. + + \snippet examples/network/ftp/ftpwindow.h 0 + + We will look at each slot when we examine the \c FtpWindow + implementation in the next section. We also make use of a few + private variables: + + \snippet examples/network/ftp/ftpwindow.h 1 + + The \c isDirectory hash keeps a history of all entries explored on + the FTP server, and registers whether an entry represents a + directory or a file. We use the QFile object to download files + from the FTP server. + + \section1 FtpWindow Class Implementation + + We skip the \c FtpWindow constructor as it only contains code for + setting up the GUI, which is explained in other examples. + + We move on to the slots, starting with \c connectOrDisconnect(). + + \snippet examples/network/ftp/ftpwindow.cpp 0 + + If \c ftp is already pointing to a QFtp object, we QFtp::Close its + FTP connection and delete the object it points to. Note that we do + not delete the object using standard C++ \c delete as we need it + to finish its abort operation. + + \dots + \snippet examples/network/ftp/ftpwindow.cpp 1 + + If we get here, \c connectOrDisconnect() was called to establish a + new FTP connection. We create a new QFtp for our new connection, + and connect its signals to slots in \c FtpWindow. The + \l{QFtp::}{listInfo()} signal is emitted whenever information + about a single file on the sever has been resolved. This signal is + sent when we ask QFtp to \l{QFtp::}{list()} the contents of a + directory. Finally, the \l{QFtp::}{dataTransferProgress()} signal + is emitted repeatedly during an FTP file transfer, giving us + progress reports. + + \snippet examples/network/ftp/ftpwindow.cpp 2 + + The \gui {Ftp Server} line edit contains the IP address or + hostname of the server to which we want to connect. We first check + that the URL is a valid FTP sever address. If it isn't, we still + try to connect using the plain text in \c ftpServerLineEdit. In + either case, we assume that port \c 21 is used. + + If the URL does not contain a user name and password, we use + QFtp::login(), which will attempt to log into the FTP sever as an + anonymous user. The QFtp object will now notify us when it has + connected to the FTP server; it will also send a signal if it + fails to connect or the username and password were rejected. + + We move on to the \c downloadFile() slot: + + \snippet examples/network/ftp/ftpwindow.cpp 3 + \dots + \snippet examples/network/ftp/ftpwindow.cpp 4 + + We first fetch the name of the file, which we find in the selected + item of \c fileList. We then start the download by using + QFtp::get(). QFtp will send progress signals during the download + and a signal when the download is completed. + + \snippet examples/network/ftp/ftpwindow.cpp 5 + + QFtp supports canceling the download of files. + + \snippet examples/network/ftp/ftpwindow.cpp 6 + + The \c ftpCommandFinished() slot is called when QFtp has + finished a QFtp::Command. If an error occurred during the + command, QFtp will set \c error to one of the values in + the QFtp::Error enum; otherwise, \c error is zero. + + \snippet examples/network/ftp/ftpwindow.cpp 7 + + After login, the QFtp::list() function will list the top-level + directory on the server. addToList() is connected to + QFtp::listInfo(), and will be invoked for each entry in that + directory. + + \snippet examples/network/ftp/ftpwindow.cpp 8 + + When a \l{QFtp::}{Get} command is finished, a file has finished + downloading (or an error occurred during the download). + + \snippet examples/network/ftp/ftpwindow.cpp 9 + + After a \l{QFtp::}{List} command is performed, we have to check if + no entries were found (in which case our \c addToList() function + would not have been called). + + Let's continue with the the \c addToList() slot: + + \snippet examples/network/ftp/ftpwindow.cpp 10 + + When a new file has been resolved during a QFtp::List command, + this slot is invoked with a QUrlInfo describing the file. We + create a separate row for the file in \c fileList. If \c fileList + does not have a current item, we set the new item to be the + current item. + + \snippet examples/network/ftp/ftpwindow.cpp 11 + + The \c processItem() slot is called when an item is double clicked + in the \gui {File List}. If the item represents a directory, we + want to load the contents of that directory with QFtp::list(). + + \snippet examples/network/ftp/ftpwindow.cpp 12 + + \c cdToParent() is invoked when the the user requests to go to the + parent directory of the one displayed in the file list. After + changing the directory, we QFtp::List its contents. + + \snippet examples/network/ftp/ftpwindow.cpp 13 + + The \c updateDataTransferProgress() slot is called regularly by + QFtp::dataTransferProgress() when a file download is in progress. + We use a QProgressDialog to show the download progression to the + user. + + \snippet examples/network/ftp/ftpwindow.cpp 14 + + The \c enableDownloadButton() is called whenever the current item + in \c fileList changes. If the item represents a file, the \gui + {Enable Download} Button should be enabled; otherwise, it is + disabled. +*/ + diff --git a/doc/src/examples/globalVariables.qdoc b/doc/src/examples/globalVariables.qdoc new file mode 100644 index 0000000..e1b83fe --- /dev/null +++ b/doc/src/examples/globalVariables.qdoc @@ -0,0 +1,238 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/xquery/globalVariables + \title C++ Source Code Analyzer Example + + This example uses XQuery and the \c xmlpatterns command line utility to + query C++ source code. + + \tableofcontents + + \section1 Introduction + + Suppose we want to analyze C++ source code to find coding standard + violations and instances of bad or inefficient patterns. We can do + it using the common searching and pattern matching utilities to + process the C++ files (e.g., \c{grep}, \c{sed}, and \c{awk}). Now + we can also use XQuery with the QtXmlPatterns module. + + An extension to the \c{g++} open source C++ compiler + (\l{http://public.kitware.com/GCC_XML/HTML/Index.html} {GCC-XML}) + generates an XML description of C++ source code declarations. This + XML description can then be processed by QtXmlPatterns using + XQueries to navigate the XML description of the C++ source and + produce a report. Consider the problem of finding mutable global + variables: + + \section2 Reporting Uses of Mutable Global Variables + + Suppose we want to introduce threading to a C++ application that + was originally written without threading. In a threaded program, + mutable global variables can cause bugs, because one thread might + change a global variable that other threads are reading, or two + threads might try to set the same global variable. So when + converting our program to use threading, one of the things we must + do is protect the global variables to prevent the bugs described + above. How can we use XQuery and + \l{http://public.kitware.com/GCC_XML/HTML/Index.html} {GCC-XML} to + find the variables that need protecting? + + \section3 A C++ application + + Consider the declarations in this hypothetical C++ application: + + \snippet examples/xmlpatterns/xquery/globalVariables/globals.cpp 0 + + \section3 The XML description of the C++ application + + Submitting this C++ source to + \l{http://public.kitware.com/GCC_XML/HTML/Index.html} {GCC-XML} + produces this XML description: + + \quotefromfile examples/xmlpatterns/xquery/globalVariables/globals.gccxml + \printuntil + + \section3 The XQuery for finding global variables + + We need an XQuery to find the global variables in the XML + description. Here is our XQuery source. We walk through it in + \l{XQuery Code Walk-Through}. + + \quotefromfile examples/xmlpatterns/xquery/globalVariables/reportGlobals.xq + \printuntil + + \section3 Running the XQuery + + To run the XQuery using the \c xmlpatterns command line utility, + enter the following command: + + \code + xmlpatterns reportGlobals.xq -param fileToOpen=globals.gccxml -output globals.html + \endcode + + \section3 The XQuery output + + The \c xmlpatterns command loads and parses \c globals.gccxml, + runs the XQuery \c reportGlobals.xq, and generates this report: + + \raw HTML +<html xmlns="http://www.w3.org/1999/xhtml/" xml:lang="en" lang="en"> + <head> + <title>Global variables report for globals.gccxml</title> + </head> + <style type="text/css"> + .details + { + text-align: left; + font-size: 80%; + color: blue + } + .variableName + { + font-family: courier; + color: blue + } + </style> + <body> + <p class="details">Start report: 2008-12-16T13:43:49.65Z</p> + <p>Global variables with complex types:</p> + <ol> + <li> + <span class="variableName">mutableComplex1</span> in globals.cpp at line 14</li> + <li> + <span class="variableName">mutableComplex2</span> in globals.cpp at line 15</li> + <li> + <span class="variableName">constComplex1</span> in globals.cpp at line 16</li> + <li> + <span class="variableName">constComplex2</span> in globals.cpp at line 17</li> + </ol> + <p>Mutable global variables with primitives types:</p> + <ol> + <li> + <span class="variableName">mutablePrimitive1</span> in globals.cpp at line 1</li> + <li> + <span class="variableName">mutablePrimitive2</span> in globals.cpp at line 2</li> + </ol> + <p class="details">End report: 2008-12-16T13:43:49.65Z</p> + </body> +</html> + \endraw + + \section1 XQuery Code Walk-Through + + The XQuery source is in + \c{examples/xmlpatterns/xquery/globalVariables/reportGlobals.xq} + It begins with two variable declarations that begin the XQuery: + + \quotefromfile examples/xmlpatterns/xquery/globalVariables/reportGlobals.xq + \skipto declare variable + \printto (: + + The first variable, \c{$fileToOpen}, appears in the \c xmlpatterns + command shown earlier, as \c{-param fileToOpen=globals.gccxml}. + This binds the variable name to the file name. This variable is + then used in the declaration of the second variable, \c{$inDoc}, + as the parameter to the + \l{http://www.w3.org/TR/xpath-functions/#func-doc} {doc()} + function. The \c{doc()} function returns the document node of + \c{globals.gccxml}, which is assigned to \c{$inDoc} to be used + later in the XQuery as the root node of our searches for global + variables. + + Next skip to the end of the XQuery, where the \c{<html>} element + is constructed. The \c{<html>} will contain a \c{<head>} element + to specify a heading for the html page, followed by some style + instructions for displaying the text, and then the \c{<body>} + element. + + \quotefromfile examples/xmlpatterns/xquery/globalVariables/reportGlobals.xq + \skipto <html xmlns + \printuntil + + The \c{<body>} element contains a call to the \c{local:report()} + function, which is where the query does the "heavy lifting." Note + the two \c{return} clauses separated by the \e {comma operator} + about halfway down: + + \quotefromfile examples/xmlpatterns/xquery/globalVariables/reportGlobals.xq + \skipto declare function local:report() + \printuntil }; + + The \c{return} clauses are like two separate queries. The comma + operator separating them means that both \c{return} clauses are + executed and both return their results, or, rather, both output + their results. The first \c{return} clause searches for global + variables with complex types, and the second searches for mutable + global variables with primitive types. + + Here is the html generated for the \c{<body>} element. Compare + it with the XQuery code above: + + \quotefromfile examples/xmlpatterns/xquery/globalVariables/globals.html + \skipto <body> + \printuntil </body> + + The XQuery declares three more local functions that are called in + turn by the \c{local:report()} function. \c{isComplexType()} + returns true if the variable has a complex type. The variable can + be mutable or const. + + \quotefromfile examples/xmlpatterns/xquery/globalVariables/reportGlobals.xq + \skipto declare function local:isComplexType + \printuntil }; + + \c{isPrimitive()} returns true if the variable has a primitive + type. The variable must be mutable. + + \quotefromfile examples/xmlpatterns/xquery/globalVariables/reportGlobals.xq + \skipto declare function local:isPrimitive + \printuntil }; + + \c{location()} returns a text constructed from the variable's file + and line number attributes. + + \quotefromfile examples/xmlpatterns/xquery/globalVariables/reportGlobals.xq + \skipto declare function local:location + \printuntil }; + + */ diff --git a/doc/src/examples/grabber.qdoc b/doc/src/examples/grabber.qdoc new file mode 100644 index 0000000..efb5b6f --- /dev/null +++ b/doc/src/examples/grabber.qdoc @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example opengl/grabber + \title Grabber Example + + The Grabber examples shows how to retrieve the contents of an OpenGL framebuffer. + + \image grabber-example.png +*/ diff --git a/doc/src/examples/groupbox.qdoc b/doc/src/examples/groupbox.qdoc new file mode 100644 index 0000000..c5f6a62 --- /dev/null +++ b/doc/src/examples/groupbox.qdoc @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/groupbox + \title Group Box Example + + The Group Box example shows how to use the different kinds of group + boxes in Qt. + + Group boxes are container widgets that organize buttons into groups, + both logically and on screen. They manage the interactions between + the user and the application so that you do not have to enforce + simple constraints. + + Group boxes are usually used to organize check boxes and radio + buttons into exclusive groups. + + \image groupbox-example.png + + The Group Boxes example consists of a single \c Window class that + is used to show four group boxes: an exclusive radio button group, + a non-exclusive checkbox group, an exclusive radio button group + with an enabling checkbox, and a group box with normal push buttons. + + \section1 Window Class Definition + + The \c Window class is a subclass of \c QWidget that is used to + display a number of group boxes. The class definition contains + functions to construct each group box and populate it with different + selections of button widgets: + + \snippet examples/widgets/groupbox/window.h 0 + + In the example, the widget will be used as a top-level window, so + the constructor is defined so that we do not have to specify a parent + widget. + + \section1 Window Class Implementation + + The constructor creates a grid layout and fills it with each of the + group boxes that are to be displayed: + + \snippet examples/widgets/groupbox/window.cpp 0 + + The functions used to create each group box each return a + QGroupBox to be inserted into the grid layout. + + \snippet examples/widgets/groupbox/window.cpp 1 + + The first group box contains and manages three radio buttons. Since + the group box contains only radio buttons, it is exclusive by + default, so only one radio button can be checked at any given time. + We check the first radio button to ensure that the button group + contains one checked button. + + \snippet examples/widgets/groupbox/window.cpp 3 + + We use a vertical layout within the group box to present the + buttons in the form of a vertical list, and return the group + box to the constructor. + + The second group box is itself checkable, providing a convenient + way to disable all the buttons inside it. Initially, it is + unchecked, so the group box itself must be checked before any of + the radio buttons inside can be checked. + + \snippet examples/widgets/groupbox/window.cpp 4 + + The group box contains three exclusive radio buttons, and an + independent checkbox. For consistency, one radio button must be + checked at all times, so we ensure that the first one is initially + checked. + + \snippet examples/widgets/groupbox/window.cpp 5 + + The buttons are arranged in the same way as those in the first + group box. + + \snippet examples/widgets/groupbox/window.cpp 6 + + The third group box is constructed with a "flat" style that is + better suited to certain types of dialog. + + \snippet examples/widgets/groupbox/window.cpp 7 + + This group box contains only checkboxes, so it is non-exclusive by + default. This means that each checkbox can be checked independently + of the others. + + \snippet examples/widgets/groupbox/window.cpp 8 + + Again, we use a vertical layout within the group box to present + the buttons in the form of a vertical list. + + \snippet examples/widgets/groupbox/window.cpp 9 + + The final group box contains only push buttons and, like the + second group box, it is checkable. + + \snippet examples/widgets/groupbox/window.cpp 10 + + We create a normal button, a toggle button, and a flat push button: + + \snippet examples/widgets/groupbox/window.cpp 11 + + Push buttons can be used to display popup menus. We create one, and + attach a simple menu to it: + + \snippet examples/widgets/groupbox/window.cpp 12 + + Finally, we lay out the widgets vertically, and return the group box + that we created: + + \snippet examples/widgets/groupbox/window.cpp 13 +*/ diff --git a/doc/src/examples/hellogl.qdoc b/doc/src/examples/hellogl.qdoc new file mode 100644 index 0000000..2fc51a3 --- /dev/null +++ b/doc/src/examples/hellogl.qdoc @@ -0,0 +1,272 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example opengl/hellogl + \title Hello GL Example + + The Hello GL example demonstrates the basic use of the OpenGL-related classes + provided with Qt. + + \image hellogl-example.png + + Qt provides the QGLWidget class to enable OpenGL graphics to be rendered within + a standard application user interface. By subclassing this class, and providing + reimplementations of event handler functions, 3D scenes can be displayed on + widgets that can be placed in layouts, connected to other objects using signals + and slots, and manipulated like any other widget. + + \tableofcontents + + \section1 GLWidget Class Definition + + The \c GLWidget class contains some standard public definitions for the + constructor, destructor, \l{QWidget::sizeHint()}{sizeHint()}, and + \l{QWidget::minimumSizeHint()}{minimumSizeHint()} functions: + + \snippet examples/opengl/hellogl/glwidget.h 0 + + We use a destructor to ensure that any OpenGL-specific data structures + are deleted when the widget is no longer needed. + + \snippet examples/opengl/hellogl/glwidget.h 1 + + The signals and slots are used to allow other objects to interact with the + 3D scene. + + \snippet examples/opengl/hellogl/glwidget.h 2 + + OpenGL initialization, viewport resizing, and painting are handled by + reimplementing the QGLWidget::initializeGL(), QGLWidget::resizeGL(), and + QGLWidget::paintGL() handler functions. To enable the user to interact + directly with the scene using the mouse, we reimplement + QWidget::mousePressEvent() and QWidget::mouseMoveEvent(). + + \snippet examples/opengl/hellogl/glwidget.h 3 + + The rest of the class contains utility functions and variables that are + used to construct and hold orientation information for the scene. The + \c object variable will be used to hold an identifier for an OpenGL + display list. + + \section1 GLWidget Class Implementation + + In this example, we split the class into groups of functions and describe + them separately. This helps to illustrate the differences between subclasses + of native widgets (such as QWidget and QFrame) and QGLWidget subclasses. + + \section2 Widget Construction and Sizing + + The constructor provides default rotation angles for the scene, initializes + the variable used for the display list, and sets up some colors for later use. + + \snippet examples/opengl/hellogl/glwidget.cpp 0 + + We also implement a destructor to release OpenGL-related resources when the + widget is deleted: + + \snippet examples/opengl/hellogl/glwidget.cpp 1 + + The destructor ensures that the display list is deleted properly. + + We provide size hint functions to ensure that the widget is shown at a + reasonable size: + + \snippet examples/opengl/hellogl/glwidget.cpp 2 + \codeline + \snippet examples/opengl/hellogl/glwidget.cpp 3 + \snippet examples/opengl/hellogl/glwidget.cpp 4 + + The widget provides three slots that enable other components in the + example to change the orientation of the scene: + + \snippet examples/opengl/hellogl/glwidget.cpp 5 + + In the above slot, the \c xRot variable is updated only if the new angle + is different to the old one, the \c xRotationChanged() signal is emitted to + allow other components to be updated, and the widget's + \l{QGLWidget::updateGL()}{updateGL()} handler function is called. + + The \c setYRotation() and \c setZRotation() slots perform the same task for + rotations measured by the \c yRot and \c zRot variables. + + \section2 OpenGL Initialization + + The \l{QGLWidget::initializeGL()}{initializeGL()} function is used to + perform useful initialization tasks that are needed to render the 3D scene. + These often involve defining colors and materials, enabling and disabling + certain rendering flags, and setting other properties used to customize the + rendering process. + + \snippet examples/opengl/hellogl/glwidget.cpp 6 + + In this example, we reimplement the function to set the background color, + create a display list containing information about the object we want to + display, and set up the rendering process to use a particular shading model + and rendering flags: + + \section2 Resizing the Viewport + + The \l{QGLWidget::resizeGL()}{resizeGL()} function is used to ensure that + the OpenGL implementation renders the scene onto a viewport that matches the + size of the widget, using the correct transformation from 3D coordinates to + 2D viewport coordinates. + + The function is called whenever the widget's dimensions change, and is + supplied with the new width and height. Here, we define a square viewport + based on the length of the smallest side of the widget to ensure that + the scene is not distorted if the widget has sides of unequal length: + + \snippet examples/opengl/hellogl/glwidget.cpp 8 + + A discussion of the projection transformation used is outside the scope of + this example. Please consult the OpenGL reference documentation for an + explanation of projection matrices. + + \section2 Painting the Scene + + The \l{QGLWidget::paintGL()}{paintGL()} function is used to paint the + contents of the scene onto the widget. For widgets that only need to be + decorated with pure OpenGL content, we reimplement QGLWidget::paintGL() + \e instead of reimplementing QWidget::paintEvent(): + + \snippet examples/opengl/hellogl/glwidget.cpp 7 + + In this example, we clear the widget using the background color that + we defined in the \l{QGLWidget::initializeGL()}{initializeGL()} function, + set up the frame of reference for the object we want to display, and call + the display list containing the rendering commands for the object. + + \section2 Mouse Handling + + Just as in subclasses of native widgets, mouse events are handled by + reimplementing functions such as QWidget::mousePressEvent() and + QWidget::mouseMoveEvent(). + + The \l{QWidget::mousePressEvent()}{mousePressEvent()} function simply + records the position of the mouse when a button is initially pressed: + + \snippet examples/opengl/hellogl/glwidget.cpp 9 + + The \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()} function uses the + previous location of the mouse cursor to determine how much the object + in the scene should be rotated, and in which direction: + + \snippet examples/opengl/hellogl/glwidget.cpp 10 + + Since the user is expected to hold down the mouse button and drag the + cursor to rotate the object, the cursor's position is updated every time + a move event is received. + + \section2 Utility Functions + + We have omitted the utility functions, \c makeObject(), \c quad(), + \c extrude(), and \c normalizeAngle() from our discussion. These can be + viewed in the quoted source for \c glwidget.cpp via the link at the + start of this document. + + \section1 Window Class Definition + + The \c Window class is used as a container for the \c GLWidget used to + display the scene: + + \snippet examples/opengl/hellogl/window.h 0 + + In addition, it contains sliders that are used to change the orientation + of the object in the scene. + + \section1 Window Class Implementation + + The constructor constructs an instance of the \c GLWidget class and some + sliders to manipulate its contents. + + \snippet examples/opengl/hellogl/window.cpp 0 + + We connect the \l{QAbstractSlider::valueChanged()}{valueChanged()} signal + from each of the sliders to the appropriate slots in \c{glWidget}. + This allows the user to change the orientation of the object by dragging + the sliders. + + We also connect the \c xRotationChanged(), \c yRotationChanged(), and + \c zRotationChanged() signals from \c glWidget to the + \l{QAbstractSlider::setValue()}{setValue()} slots in the + corresponding sliders. + + \snippet examples/opengl/hellogl/window.cpp 1 + + The sliders are placed horizontally in a layout alongside the \c GLWidget, + and initialized with suitable default values. + + The \c createSlider() utility function constructs a QSlider, and ensures + that it is set up with a suitable range, step value, tick interval, and + page step value before returning it to the calling function: + + \snippet examples/opengl/hellogl/window.cpp 2 + + \section1 Summary + + The \c GLWidget class implementation shows how to subclass QGLWidget for + the purposes of rendering a 3D scene using OpenGL calls. Since QGLWidget + is a subclass of QWidget, subclasses of QGLWidget can be placed in layouts + and provided with interactive features just like normal custom widgets. + + We ensure that the widget is able to correctly render the scene using OpenGL + by reimplementing the following functions: + + \list + \o QGLWidget::initializeGL() sets up resources needed by the OpenGL implementation + to render the scene. + \o QGLWidget::resizeGL() resizes the viewport so that the rendered scene fits onto + the widget, and sets up a projection matrix to map 3D coordinates to 2D viewport + coordinates. + \o QGLWidget::paintGL() performs painting operations using OpenGL calls. + \endlist + + Since QGLWidget is a subclass of QWidget, it can also be used + as a normal paint device, allowing 2D graphics to be drawn with QPainter. + This use of QGLWidget is discussed in the \l{2D Painting Example}{2D Painting} + example. + + More advanced users may want to paint over parts of a scene rendered using + OpenGL. QGLWidget allows pure OpenGL rendering to be mixed with QPainter + calls, but care must be taken to maintain the state of the OpenGL implementation. + See the \l{Overpainting Example}{Overpainting} example for more information. +*/ diff --git a/doc/src/examples/hellogl_es.qdoc b/doc/src/examples/hellogl_es.qdoc new file mode 100644 index 0000000..0293584 --- /dev/null +++ b/doc/src/examples/hellogl_es.qdoc @@ -0,0 +1,124 @@ +/*! + \example opengl/hellogl_es + \title Hello GL ES Example + + The Hello GL ES example is the \l{Hello GL Example} ported to OpenGL ES. + It also included some effects from the OpenGL \l{Overpainting Example}. + + \image hellogl-es-example.png + + A complete introduction to OpenGL ES and a description of all differences + between OpenGL and OpenGL ES is out of the scope of this document; but + we will describe some of the major issues and differences. + + Since Hello GL ES is a direct port of standard OpenGL code, it is a fairly + good example for porting OpenGL code to OpenGL ES. + + \tableofcontents + + \section1 Using QGLWidget + + QGLWidget can be used for OpenGL ES similar to the way it is used with + standard OpenGL; but there are some differences. We use EGL 1.0 to embedd + the OpenGL ES window within the native window manager. In + QGLWidget::initializeGL() we initialize OpenGL ES. + + \section1 Using OpenGL ES rendering commands + + To update the scene, we reimplment QGLWidget::paintGL(). We use OpenGL ES + rendering commands just like we do with standard OpenGL. Since the OpenGL + ES common light profile only supports fixed point functions, we need to + abstract it somehow. Hence, we define an abstraction layer in + \c{cl_helper.h}. + + \snippet examples/opengl/hellogl_es/cl_helper.h 0 + + Instead of \c glFogxv() or \c glFogfv() we use \c q_glFogv() and to + convert the coordinates of a vertice we use the macro \c f2vt(). That way, + if QT_OPENGL_ES_CL is defined we use the fixed point functions and every + float is converted to fixed point. + + If QT_OPENGL_ES_CL is not defined we use the floating point functions. + + \snippet examples/opengl/hellogl_es/cl_helper.h 1 + + This way we support OpenGL ES Common and Common Light with the same code + and abstract the fact that we use either the floating point functions or + otherwise the fixed point functions. + + \section1 Porting OpenGL to OpenGL ES + + Since OpenGL ES is missing the immediate mode and does not support quads, + we have to create triangle arrays. + + We create a quad by adding vertices to a QList of vertices. We create both + sides of the quad and hardcode a distance of 0.05f. We also compute the + correct normal for each face and store them in another QList. + + \snippet examples/opengl/hellogl_es/glwidget.cpp 0 + + And then we convert the complete list of vertexes and the list of normals + into the native OpenGL ES format that we can use with the OpenGL ES API. + + \snippet examples/opengl/hellogl_es/glwidget.cpp 1 + + In \c paintQtLogo() we draw the triangle array using OpenGL ES. We use + q_vertexTypeEnum to abstract the fact that our vertex and normal arrays + are either in float or in fixed point format. + + \snippet examples/opengl/hellogl_es/glwidget.cpp 2 + + \section1 Using QGLPainter + + Since the \c QGLPainter is slower for OpenGL ES we paint the bubbles with + the rasterizer and cache them in a QImage. This happends only once during + the initialiazation. + + \snippet examples/opengl/hellogl_es/bubble.cpp 0 + + For each bubble this QImage is then drawn to the QGLWidget by using the + according QPainter with transparency enabled. + + \snippet examples/opengl/hellogl_es/bubble.cpp 1 + + Another difference beetwen OpenGL and OpenGL ES is that OpenGL ES does not + support glPushAttrib(GL_ALL_ATTRIB_BITS). So we have to restore all the + OpenGL states ourselves, after we created the QPainter in + GLWidget::paintGL(). + + \snippet examples/opengl/hellogl_es/glwidget.cpp 3 + + Setting up up the model view matrix and setting the right OpenGL states is + done in the same way as for standard OpenGL. + + \snippet examples/opengl/hellogl_es/glwidget.cpp 4 + + Now we have to restore the OpenGL state for the QPainter. This is not done + automatically for OpenGL ES. + + \snippet examples/opengl/hellogl_es/glwidget.cpp 5 + + Now we use the QPainter to draw the transparent bubbles. + + \snippet examples/opengl/hellogl_es/glwidget.cpp 6 + + In the end, we calculate the framerate and display it using the QPainter + again. + + \snippet examples/opengl/hellogl_es/glwidget.cpp 7 + + After we finished all the drawing operations we swap the screen buffer. + + \snippet examples/opengl/hellogl_es/glwidget.cpp 8 + + \section1 Summary + + Similar to the \l{Hello GL Example}, we subclass QGLWidget to render + a 3D scene using OpenGL ES calls. QGLWidget is a subclass of QWidget. + Hence, its \l{QGLWidget}'s subclasses can be placed in layouts and + provided with interactive features just like normal custom widgets. + + QGLWidget allows pure OpenGL ES rendering to be mixed with QPainter calls, + but care must be taken to maintain the state of the OpenGL ES + implementation. +*/ diff --git a/doc/src/examples/helloscript.qdoc b/doc/src/examples/helloscript.qdoc new file mode 100644 index 0000000..5662680 --- /dev/null +++ b/doc/src/examples/helloscript.qdoc @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example script/helloscript + \title Hello Script Example + + The Hello Script example shows the basic use of Qt Script: How to embed + a script engine into the application, how to evaluate a script, and how + to process the result of the evaluation. The example also shows how to + apply internationalization to scripts. + + \snippet examples/script/helloscript/main.cpp 0 + + The application will load the script file to evaluate from a resource, so + we first make sure that the resource is initialized. + + \snippet examples/script/helloscript/main.cpp 1 + + We attempt to load a translation, and install translation functions in the + script engine. How to produce a translation is explained later. + + \snippet examples/script/helloscript/main.cpp 2 + + A push button is created and exported to the script environment as a + global variable, \c button. Scripts will be able to access properties, + signals and slots of the button as properties of the \c button script + object; the script object acts as a proxy to the C++ button object. + + \snippet examples/script/helloscript/main.cpp 3 + + The contents of the script file are read. + + \snippet examples/script/helloscript/helloscript.qs 0 + + The script sets the \c text (note that the qTr() function is used to allow + for translation) and \c styleSheet properties of the button, and calls the + button's \c show() slot. + + \snippet examples/script/helloscript/main.cpp 4 + + The script is evaluated. Note that the file name is passed as the + (optional) second parameter; this makes it possible for the script engine + to produce a meaningful backtrace if something goes wrong, and makes the + qTr() function be able to resolve the translations that are associated + with this script. + + \snippet examples/script/helloscript/main.cpp 5 + + If the result is an Error object (e.g. the script contained a syntax + error, or tried to call a function that doesn't exist), we obtain + the line number and string representation of the error and display + it in a message box. + + \snippet examples/script/helloscript/main.cpp 6 + + If the evaluation went well, the application event loop is entered. + + \section1 Translating the Application + + The Qt Script internalization support builds on what Qt already provides + for C++; see the \l{Hello tr() Example} for an introduction. + + Since we haven't made the translation file \c helloscript_la.qm, the + source text is shown when we run the application ("Hello world!"). + + To generate the translation file, run \c lupdate as follows: + + \code + lupdate helloscript.qs -ts helloscript_la.ts + \endcode + + You should now have a file \c helloscript_la.ts in the current + directory. Run \c linguist to edit the translation: + + \code + linguist helloscript_la.ts + \endcode + + You should now see the text "helloscript.qs" in the top left pane. + Double-click it, then click on "Hello world!" and enter "Orbis, te + saluto!" in the \gui Translation pane (the middle right of the + window). Don't forget the exclamation mark! + + Click the \gui Done checkbox and choose \gui File|Save from the + menu bar. The \c .ts file will no longer contain + + \snippet doc/src/snippets/code/doc_src_examples_hellotr.qdoc 3 + + but instead will have + + \snippet doc/src/snippets/code/doc_src_examples_hellotr.qdoc 4 + + To see the application running in Latin, we have to generate a \c .qm + file from the \c .ts file. Generating a \c .qm file can be achieved + either from within \e {Qt Linguist} (for a single \c .ts file), or + by using the command line program \c lrelease which will produce one \c + .qm file for each of the \c .ts files listed in the project file. + Generate \c hellotr_la.qm from \c hellotr_la.ts by choosing + \gui File|Release from \e {Qt Linguist}'s menu bar and pressing + \gui Save in the file save dialog that pops up. Now run the \c helloscript + program again. This time the button will be labelled "Orbis, te + saluto!". +*/ diff --git a/doc/src/examples/hellotr.qdoc b/doc/src/examples/hellotr.qdoc new file mode 100644 index 0000000..72efd11 --- /dev/null +++ b/doc/src/examples/hellotr.qdoc @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example linguist/hellotr + \title Hello tr() Example + + This example is a small Hello World program with a Latin translation. The + screenshot below shows the English version. + + \image linguist-hellotr_en.png + + See the \l{Qt Linguist manual} for more information about + translating Qt application. + + \section1 Line by Line Walkthrough + + + \snippet examples/linguist/hellotr/main.cpp 0 + + This line includes the definition of the QTranslator class. + Objects of this class provide translations for user-visible text. + + \snippet examples/linguist/hellotr/main.cpp 5 + + Creates a QTranslator object without a parent. + + \snippet examples/linguist/hellotr/main.cpp 6 + + Tries to load a file called \c hellotr_la.qm (the \c .qm file extension is + implicit) that contains Latin translations for the source texts used in + the program. No error will occur if the file is not found. + + \snippet examples/linguist/hellotr/main.cpp 7 + + Adds the translations from \c hellotr_la.qm to the pool of translations used + by the program. + + \snippet examples/linguist/hellotr/main.cpp 8 + + Creates a push button that displays "Hello world!". If \c hellotr_la.qm + was found and contains a translation for "Hello world!", the + translation appears; if not, the source text appears. + + All classes that inherit QObject have a \c tr() function. Inside + a member function of a QObject class, we simply write \c tr("Hello + world!") instead of \c QPushButton::tr("Hello world!") or \c + QObject::tr("Hello world!"). + + \section1 Running the Application in English + + Since we haven't made the translation file \c hellotr_la.qm, the source text + is shown when we run the application: + + \image linguist-hellotr_en.png + + \section1 Creating a Latin Message File + + The first step is to create a project file, \c hellotr.pro, that lists + all the source files for the project. The project file can be a qmake + project file, or even an ordinary makefile. Any file that contains + + \snippet examples/linguist/hellotr/hellotr.pro 0 + \snippet examples/linguist/hellotr/hellotr.pro 1 + + will work. \c TRANSLATIONS specifies the message files we want to + maintain. In this example, we just maintain one set of translations, + namely Latin. + + Note that the file extension is \c .ts, not \c .qm. The \c .ts + translation source format is designed for use during the + application's development. Programmers or release managers run + the \c lupdate program to generate and update \c .ts files with + the source text that is extracted from the source code. + Translators read and update the \c .ts files using \e {Qt + Linguist} adding and editing their translations. + + The \c .ts format is human-readable XML that can be emailed directly + and is easy to put under version control. If you edit this file + manually, be aware that the default encoding for XML is UTF-8, not + Latin1 (ISO 8859-1). One way to type in a Latin1 character such as + '\oslash' (Norwegian o with slash) is to use an XML entity: + "\ø". This will work for any Unicode 4.0 character. + + Once the translations are complete the \c lrelease program is used to + convert the \c .ts files into the \c .qm Qt message file format. The + \c .qm format is a compact binary format designed to deliver very + fast lookup performance. Both \c lupdate and \c lrelease read all the + project's source and header files (as specified in the HEADERS and + SOURCES lines of the project file) and extract the strings that + appear in \c tr() function calls. + + \c lupdate is used to create and update the message files (\c hellotr_la.ts + in this case) to keep them in sync with the source code. It is safe to + run \c lupdate at any time, as \c lupdate does not remove any + information. For example, you can put it in the makefile, so the \c .ts + files are updated whenever the source changes. + + Try running \c lupdate right now, like this: + + \snippet doc/src/snippets/code/doc_src_examples_hellotr.qdoc 0 + + (The \c -verbose option instructs \c lupdate to display messages that + explain what it is doing.) You should now have a file \c hellotr_la.ts in + the current directory, containing this: + + \snippet doc/src/snippets/code/doc_src_examples_hellotr.qdoc 1 + + You don't need to understand the file format since it is read and + updated using tools (\c lupdate, \e {Qt Linguist}, \c lrelease). + + \section1 Translating to Latin with Qt Linguist + + We will use \e {Qt Linguist} to provide the translation, although + you can use any XML or plain text editor to enter a translation into a + \c .ts file. + + To start \e {Qt Linguist}, type + + \snippet doc/src/snippets/code/doc_src_examples_hellotr.qdoc 2 + + You should now see the text "QPushButton" in the top left pane. + Double-click it, then click on "Hello world!" and enter "Orbis, te + saluto!" in the \gui Translation pane (the middle right of the + window). Don't forget the exclamation mark! + + Click the \gui Done checkbox and choose \gui File|Save from the + menu bar. The \c .ts file will no longer contain + + \snippet doc/src/snippets/code/doc_src_examples_hellotr.qdoc 3 + + but instead will have + + \snippet doc/src/snippets/code/doc_src_examples_hellotr.qdoc 4 + + \section1 Running the Application in Latin + + To see the application running in Latin, we have to generate a \c .qm + file from the \c .ts file. Generating a \c .qm file can be achieved + either from within \e {Qt Linguist} (for a single \c .ts file), or + by using the command line program \c lrelease which will produce one \c + .qm file for each of the \c .ts files listed in the project file. + Generate \c hellotr_la.qm from \c hellotr_la.ts by choosing + \gui File|Release from \e {Qt Linguist}'s menu bar and pressing + \gui Save in the file save dialog that pops up. Now run the \c hellotr + program again. This time the button will be labelled "Orbis, te + saluto!". + + \image linguist-hellotr_la.png +*/ diff --git a/doc/src/examples/http.qdoc b/doc/src/examples/http.qdoc new file mode 100644 index 0000000..17404a8 --- /dev/null +++ b/doc/src/examples/http.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example network/http + \title HTTP Example + + The HTTP example demonstrates a simple HTTP client that shows how to fetch files + specified by URLs from remote hosts. + + \image http-example.png +*/ diff --git a/doc/src/examples/i18n.qdoc b/doc/src/examples/i18n.qdoc new file mode 100644 index 0000000..68d9153 --- /dev/null +++ b/doc/src/examples/i18n.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/i18n + \title I18N Example + + The Internationalization (I18N) example demonstrates Qt's support for translated + text. Developers can write the initial application text in one language, and + translations can be provided later without any modifications to the code. + + \image i18n-example.png +*/ diff --git a/doc/src/examples/icons.qdoc b/doc/src/examples/icons.qdoc new file mode 100644 index 0000000..750ef2e --- /dev/null +++ b/doc/src/examples/icons.qdoc @@ -0,0 +1,794 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/icons + \title Icons Example + + The Icons example shows how QIcon can generate pixmaps reflecting + an icon's state, mode and size. These pixmaps are generated from + the set of pixmaps made available to the icon, and are used by Qt + widgets to show an icon representing a particular action. + + \image icons-example.png Screenshot of the Icons example + + Contents: + + \tableofcontents + + \section1 QIcon Overview + + The QIcon class provides scalable icons in different modes and + states. An icon's state and mode are depending on the intended use + of the icon. Qt currently defines four modes: + + \table + \header \o Mode \o Description + \row + \o QIcon::Normal + \o Display the pixmap when the user is not interacting with the + icon, but the functionality represented by the icon is + available. + \row + \o QIcon::Active + \o Display the pixmap when the functionality represented by the + icon is available and the user is interacting with the icon, + for example, moving the mouse over it or clicking it. + \row + \o QIcon::Disabled + \o Display the pixmap when the functionality represented by + the icon is not available. + \row + \o QIcon::Selected + \o Display the pixmap when the icon is selected. + \endtable + + QIcon's states are QIcon::On and QIcon::Off, which will display + the pixmap when the widget is in the respective state. The most + common usage of QIcon's states are when displaying checkable tool + buttons or menu entries (see QAbstractButton::setCheckable() and + QAction::setCheckable()). When a tool button or menu entry is + checked, the QIcon's state is \l{QIcon::}{On}, otherwise it's + \l{QIcon::}{Off}. You can, for example, use the QIcon's states to + display differing pixmaps depending on whether the tool button or + menu entry is checked or not. + + A QIcon can generate smaller, larger, active, disabled, and + selected pixmaps from the set of pixmaps it is given. Such + pixmaps are used by Qt widgets to show an icon representing a + particular action. + + \section1 Overview of the Icons Application + + With the Icons application you get a preview of an icon's + generated pixmaps reflecting its different states, modes and size. + + When an image is loaded into the application, it is converted into + a pixmap and becomes a part of the set of pixmaps available to the + icon. An image can be excluded from this set by checking off the + related checkbox. The application provides a sub directory + containing sets of images explicitly designed to illustrate how Qt + renders an icon in different modes and states. + + The application allows you to manipulate the icon size with some + predefined sizes and a spin box. The predefined sizes are style + dependent, but most of the styles have the same values: Only the + Macintosh style differ by using 32 pixels, instead of 16 pixels, + for toolbar buttons. You can navigate between the available styles + using the \gui View menu. + + \image icons-view-menu.png Screenshot of the View menu + + The \gui View menu also provide the option to make the application + guess the icon state and mode from an image's file name. The \gui + File menu provide the options of adding an image and removing all + images. These last options are also available through a context + menu that appears if you press the right mouse button within the + table of image files. In addition, the \gui File menu provide an + \gui Exit option, and the \gui Help menu provide information about + the example and about Qt. + + \image icons_find_normal.png Screenshot of the Find Files + + The screenshot above shows the application with one image file + loaded. The \gui {Guess Image Mode/State} is enabled and the + style is Plastique. + + When QIcon is provided with only one available pixmap, that + pixmap is used for all the states and modes. In this case the + pixmap's icon mode is set to normal, and the generated pixmaps + for the normal and active modes will look the same. But in + disabled and selected mode, Qt will generate a slightly different + pixmap. + + The next screenshot shows the application with an additional file + loaded, providing QIcon with two available pixmaps. Note that the + new image file's mode is set to disabled. When rendering the \gui + Disabled mode pixmaps, Qt will now use the new image. We can see + the difference: The generated disabled pixmap in the first + screenshot is slightly darker than the pixmap with the originally + set disabled mode in the second screenshot. + + \image icons_find_normal_disabled.png Screenshot of the Find Files + + When Qt renders the icon's pixmaps it searches through the set of + available pixmaps following a particular algorithm. The algorithm + is documented in QIcon, but we will describe some particular cases + below. + + \image icons_monkey_active.png Screenshot of the Find Files + + In the screenshot above, we have set \c monkey_on_32x32 to be an + Active/On pixmap and \c monkey_off_64x64 to be Normal/Off. To + render the other six mode/state combinations, QIcon uses the + search algorithm described in the table below: + + \table + \header \o{2,1} Requested Pixmap \o{8,1} Preferred Alternatives (mode/state) + \header \o Mode \o State \o 1 \o 2 \o 3 \o 4 \o 5 \o 6 \o 7 \o 8 + \row \o{1,2} Normal \o Off \o \bold N0 \o A0 \o N1 \o A1 \o D0 \o S0 \o D1 \o S1 + \row \o On \o N1 \o \bold A1 \o N0 \o A0 \o D1 \o S1 \o D0 \o S0 + \row \o{1,2} Active \o Off \o A0 \o \bold N0 \o A1 \o N1 \o D0 \o S0 \o D1 \o S1 + \row \o On \o \bold A1 \o N1 \o A0 \o N0 \o D1 \o S1 \o D0 \o S0 + \row \o{1,2} Disabled \o Off \o D0 \o \bold {N0'} \o A0' \o D1 \o N1' \o A1' \o S0' \o S1' + \row \o On \o D1 \o N1' \o \bold {A1'} \o D0 \o N0' \o A0' \o S1' \o S0' + \row \o{1,2} Selected \o Off \o S0 \o \bold {N0''} \o A0'' \o S1 \o N1'' \o A1'' \o D0'' \o D1'' + \row \o On \o S1 \o N1'' \o \bold {A1''} \o S0 \o N0'' \o A0'' \o D1'' \o D0'' + \endtable + + In the table, "0" and "1" stand for Off" and "On", respectively. + Single quotes indicates that QIcon generates a disabled ("grayed + out") version of the pixmap; similarly, double quuote indicate + that QIcon generates a selected ("blued out") version of the + pixmap. + + The alternatives used in the screenshot above are shown in bold. + For example, the Disabled/Off pixmap is derived by graying out + the Normal/Off pixmap (\c monkey_off_64x64). + + In the next screenshots, we loaded the whole set of monkey + images. By checking or unchecking file names from the image list, + we get different results: + + \table + \row + \o \inlineimage icons_monkey.png Screenshot of the Monkey Files + \o \inlineimage icons_monkey_mess.png Screenshot of the Monkey Files + \endtable + + For any given mode/state combination, it is possible to specify + several images at different resolutions. When rendering an + icon, QIcon will automatically pick the most suitable image + and scale it down if necessary. (QIcon never scales up images, + because this rarely looks good.) + + The screenshots below shows what happens when we provide QIcon + with three images (\c qt_extended_16x16.png, \c qt_extended_32x32.png, \c + qt_extended_48x48.png) and try to render the QIcon at various + resolutions: + + \table + \row + \o + \o \inlineimage icons_qt_extended_8x8.png Qt Extended icon at 8 x 8 + \o \inlineimage icons_qt_extended_16x16.png Qt Extended icon at 16 x 16 + \o \inlineimage icons_qt_extended_17x17.png Qt Extended icon at 17 x 17 + \row + \o + \o 8 x 8 + \o \bold {16 x 16} + \o 17 x 17 + \row + \o \inlineimage icons_qt_extended_32x32.png Qt Extended icon at 32 x 32 + \o \inlineimage icons_qt_extended_33x33.png Qt Extended icon at 33 x 33 + \o \inlineimage icons_qt_extended_48x48.png Qt Extended icon at 48 x 48 + \o \inlineimage icons_qt_extended_64x64.png Qt Extended icon at 64 x 64 + \row + \o \bold {32 x 32} + \o 33 x 33 + \o \bold {48 x 48} + \o 64 x 64 + \endtable + + For sizes up to 16 x 16, QIcon uses \c qt_extended_16x16.png and + scales it down if necessary. For sizes between 17 x 17 and 32 x + 32, it uses \c qt_extended_32x32.png. For sizes above 32 x 32, it uses + \c qt_extended_48x48.png. + + \section1 Line-by-Line Walkthrough + + The Icons example consists of four classes: + + \list + \o \c MainWindow inherits QMainWindow and is the main application + window. + \o \c IconPreviewArea is a custom widget that displays all + combinations of states and modes for a given icon. + \o \c IconSizeSpinBox is a subclass of QSpinBox that lets the + user enter icon sizes (e.g., "48 x 48"). + \o \c ImageDelegate is a subclass of QItemDelegate that provides + comboboxes for letting the user set the mode and state + associated with an image. + \endlist + + We will start by reviewing the \c IconPreviewArea class before we + take a look at the \c MainWindow class. Finally, we will review the + \c IconSizeSpinBox and \c ImageDelegate classes. + + \section2 IconPreviewArea Class Definition + + An \c IconPreviewArea widget consists of a group box containing a grid of + QLabel widgets displaying headers and pixmaps. + + \image icons_preview_area.png Screenshot of IconPreviewArea. + + \snippet examples/widgets/icons/iconpreviewarea.h 0 + + The \c IconPreviewArea class inherits QWidget. It displays the + generated pixmaps corresponding to an icon's possible states and + modes at a given size. + + We need two public functions to set the current icon and the + icon's size. In addition the class has three private functions: We + use the \c createHeaderLabel() and \c createPixmapLabel() + functions when constructing the preview area, and we need the \c + updatePixmapLabels() function to update the preview area when + the icon or the icon's size has changed. + + The \c NumModes and \c NumStates constants reflect \l{QIcon}'s + number of currently defined modes and states. + + \section2 IconPreviewArea Class Implementation + + \snippet examples/widgets/icons/iconpreviewarea.cpp 0 + + In the constructor we create the labels displaying the headers and + the icon's generated pixmaps, and add them to a grid layout. + + When creating the header labels, we make sure the enums \c + NumModes and \c NumStates defined in the \c .h file, correspond + with the number of labels that we create. Then if the enums at + some point are changed, the \c Q_ASSERT() macro will alert that this + part of the \c .cpp file needs to be updated as well. + + If the application is built in debug mode, the \c Q_ASSERT() + macro will expand to + + \snippet doc/src/snippets/code/doc_src_examples_icons.qdoc 0 + + In release mode, the macro simply disappear. The mode can be set + in the application's \c .pro file. One way to do so is to add an + option to \c qmake when building the application: + + \snippet doc/src/snippets/code/doc_src_examples_icons.qdoc 1 + + or + + \snippet doc/src/snippets/code/doc_src_examples_icons.qdoc 2 + + Another approach is to add this line directly to the \c .pro + file. + + \snippet examples/widgets/icons/iconpreviewarea.cpp 1 + \codeline + \snippet examples/widgets/icons/iconpreviewarea.cpp 2 + + The public \c setIcon() and \c setSize() functions change the icon + or the icon size, and make sure that the generated pixmaps are + updated. + + \snippet examples/widgets/icons/iconpreviewarea.cpp 3 + \codeline + \snippet examples/widgets/icons/iconpreviewarea.cpp 4 + + We use the \c createHeaderLabel() and \c createPixmapLabel() + functions to create the preview area's labels displaying the + headers and the icon's generated pixmaps. Both functions return + the QLabel that is created. + + \snippet examples/widgets/icons/iconpreviewarea.cpp 5 + + We use the private \c updatePixmapLabel() function to update the + generated pixmaps displayed in the preview area. + + For each mode, and for each state, we retrieve a pixmap using the + QIcon::pixmap() function, which generates a pixmap corresponding + to the given state, mode and size. + + \section2 MainWindow Class Definition + + The \c MainWindow widget consists of three main elements: an + images group box, an icon size group box and a preview area. + + \image icons-example.png Screenshot of the Icons example + + \snippet examples/widgets/icons/mainwindow.h 0 + + The MainWindow class inherits from QMainWindow. We reimplement the + constructor, and declare several private slots: + + \list + \o The \c about() slot simply provides information about the example. + \o The \c changeStyle() slot changes the application's GUI style and + adjust the style dependent size options. + \o The \c changeSize() slot changes the size of the preview area's icon. + \o The \c changeIcon() slot updates the set of pixmaps available to the + icon displayed in the preview area. + \o The \c addImage() slot allows the user to load a new image into the + application. + \endlist + + In addition we declare several private functions to simplify the + constructor. + + \section2 MainWindow Class Implementation + + \snippet examples/widgets/icons/mainwindow.cpp 0 + + In the constructor we first create the main window's central + widget and its child widgets, and put them in a grid layout. Then + we create the menus with their associated entries and actions. + + Before we resize the application window to a suitable size, we set + the window title and determine the current style for the + application. We also enable the icon size spin box by clicking the + associated radio button, making the current value of the spin box + the icon's initial size. + + \snippet examples/widgets/icons/mainwindow.cpp 1 + + The \c about() slot displays a message box using the static + QMessageBox::about() function. In this example it displays a + simple box with information about the example. + + The \c about() function looks for a suitable icon in four + locations: It prefers its parent's icon if that exists. If it + doesn't, the function tries the top-level widget containing + parent, and if that fails, it tries the active window. As a last + resort it uses the QMessageBox's Information icon. + + \snippet examples/widgets/icons/mainwindow.cpp 2 + + In the \c changeStyle() slot we first check the slot's + parameter. If it is false we immediately return, otherwise we find + out which style to change to, i.e. which action that triggered the + slot, using the QObject::sender() function. + + This function returns the sender as a QObject pointer. Since we + know that the sender is a QAction object, we can safely cast the + QObject. We could have used a C-style cast or a C++ \c + static_cast(), but as a defensive programming technique we use a + \l qobject_cast(). The advantage is that if the object has the + wrong type, a null pointer is returned. Crashes due to null + pointers are much easier to diagnose than crashes due to unsafe + casts. + + \snippet examples/widgets/icons/mainwindow.cpp 3 + \snippet examples/widgets/icons/mainwindow.cpp 4 + + Once we have the action, we extract the style name using + QAction::data(). Then we create a QStyle object using the static + QStyleFactory::create() function. + + Although we can assume that the style is supported by the + QStyleFactory: To be on the safe side, we use the \c Q_ASSERT() + macro to check if the created style is valid before we use the + QApplication::setStyle() function to set the application's GUI + style to the new style. QApplication will automatically delete + the style object when a new style is set or when the application + exits. + + The predefined icon size options provided in the application are + style dependent, so we need to update the labels in the icon size + group box and in the end call the \c changeSize() slot to update + the icon's size. + + \snippet examples/widgets/icons/mainwindow.cpp 5 + + The \c changeSize() slot sets the size for the preview area's + icon. + + To determine the new size we first check if the spin box is + enabled. If it is, we extract the extent of the new size from the + box. If it's not, we search through the predefined size options, + extract the QStyle::PixelMetric and use the QStyle::pixelMetric() + function to determine the extent. Then we create a QSize object + based on the extent, and use that object to set the size of the + preview area's icon. + + \snippet examples/widgets/icons/mainwindow.cpp 12 + + The first thing we do when the \c addImage() slot is called, is to + show a file dialog to the user. The easiest way to create a file + dialog is to use QFileDialog's static functions. Here we use the + \l {QFileDialog::getOpenFileNames()}{getOpenFileNames()} function + that will return one or more existing files selected by the user. + + For each of the files the file dialog returns, we add a row to the + table widget. The table widget is listing the images the user has + loaded into the application. + + \snippet examples/widgets/icons/mainwindow.cpp 13 + \snippet examples/widgets/icons/mainwindow.cpp 14 + + We retrieve the image name using the QFileInfo::baseName() + function that returns the base name of the file without the path, + and create the first table widget item in the row. Then we add the + file's complete name to the item's data. Since an item can hold + several information pieces, we need to assign the file name a role + that will distinguish it from other data. This role can be Qt::UserRole + or any value above it. + + We also make sure that the item is not editable by removing the + Qt::ItemIsEditable flag. Table items are editable by default. + + \snippet examples/widgets/icons/mainwindow.cpp 15 + \snippet examples/widgets/icons/mainwindow.cpp 16 + \snippet examples/widgets/icons/mainwindow.cpp 17 + + Then we create the second and third items in the row making the + default mode Normal and the default state Off. But if the \gui + {Guess Image Mode/State} option is checked, and the file name + contains "_act", "_dis", or "_sel", the modes are changed to + Active, Disabled, or Selected. And if the file name contains + "_on", the state is changed to On. The sample files in the + example's \c images subdirectory respect this naming convension. + + \snippet examples/widgets/icons/mainwindow.cpp 18 + \snippet examples/widgets/icons/mainwindow.cpp 19 + + In the end we add the items to the associated row, and use the + QTableWidget::openPersistentEditor() function to create + comboboxes for the mode and state columns of the items. + + Due to the the connection between the table widget's \l + {QTableWidget::itemChanged()}{itemChanged()} signal and the \c + changeIcon() slot, the new image is automatically converted into a + pixmap and made part of the set of pixmaps available to the icon + in the preview area. So, corresponding to this fact, we need to + make sure that the new image's check box is enabled. + + \snippet examples/widgets/icons/mainwindow.cpp 6 + \snippet examples/widgets/icons/mainwindow.cpp 7 + + The \c changeIcon() slot is called when the user alters the set + of images listed in the QTableWidget, to update the QIcon object + rendered by the \c IconPreviewArea. + + We first create a QIcon object, and then we run through the + QTableWidget, which lists the images the user has loaded into the + application. + + \snippet examples/widgets/icons/mainwindow.cpp 8 + \snippet examples/widgets/icons/mainwindow.cpp 9 + \snippet examples/widgets/icons/mainwindow.cpp 10 + + We also extract the image file's name using the + QTableWidgetItem::data() function. This function takes a + Qt::DataItemRole as an argument to retrieve the right data + (remember that an item can hold several pieces of information) + and returns it as a QVariant. Then we use the + QVariant::toString() function to get the file name as a QString. + + To create a pixmap from the file, we need to first create an + image and then convert this image into a pixmap using + QPixmap::fromImage(). Once we have the final pixmap, we add it, + with its associated mode and state, to the QIcon's set of + available pixmaps. + + \snippet examples/widgets/icons/mainwindow.cpp 11 + + After running through the entire list of images, we change the + icon of the preview area to the one we just created. + + \snippet examples/widgets/icons/mainwindow.cpp 20 + + In the \c removeAllImages() slot, we simply set the table widget's + row count to zero, automatically removing all the images the user + has loaded into the application. Then we update the set of pixmaps + available to the preview area's icon using the \c changeIcon() + slot. + + \image icons_images_groupbox.png Screenshot of the images group box + + The \c createImagesGroupBox() function is implemented to simplify + the constructor. The main purpose of the function is to create a + QTableWidget that will keep track of the images the user has + loaded into the application. + + \snippet examples/widgets/icons/mainwindow.cpp 21 + + First we create a group box that will contain the table widget. + Then we create a QTableWidget and customize it to suit our + purposes. + + We call QAbstractItemView::setSelectionMode() to prevent the user + from selecting items. + + The QAbstractItemView::setItemDelegate() call sets the item + delegate for the table widget. We create a \c ImageDelegate that + we make the item delegate for our view. + + The QItemDelegate class can be used to provide an editor for an item view + class that is subclassed from QAbstractItemView. Using a delegate + for this purpose allows the editing mechanism to be customized and + developed independently from the model and view. + + In this example we derive \c ImageDelegate from QItemDelegate. + QItemDelegate usually provides line editors, while our subclass + \c ImageDelegate, provides comboboxes for the mode and state + fields. + + \snippet examples/widgets/icons/mainwindow.cpp 22 + \snippet examples/widgets/icons/mainwindow.cpp 23 + + Then we customize the QTableWidget's horizontal header, and hide + the vertical header. + + \snippet examples/widgets/icons/mainwindow.cpp 24 + \snippet examples/widgets/icons/mainwindow.cpp 25 + + At the end, we connect the QTableWidget::itemChanged() signal to + the \c changeIcon() slot to ensuret that the preview area is in + sync with the image table. + + \image icons_size_groupbox.png Screenshot of the icon size group box + + The \c createIconSizeGroupBox() function is called from the + constructor. It creates the widgets controlling the size of the + preview area's icon. + + \snippet examples/widgets/icons/mainwindow.cpp 26 + + First we create a group box that will contain all the widgets; + then we create the radio buttons and the spin box. + + The spin box is not a regular QSpinBox but an \c IconSizeSpinBox. + The \c IconSizeSpinBox class inherits QSpinBox and reimplements + two functions: QSpinBox::textFromValue() and + QSpinBox::valueFromText(). The \c IconSizeSpinBox is designed to + handle icon sizes, e.g., "32 x 32", instead of plain integer + values. + + \snippet examples/widgets/icons/mainwindow.cpp 27 + + Then we connect all of the radio buttons + \l{QRadioButton::toggled()}{toggled()} signals and the spin box's + \l {QSpinBox::valueChanged()}{valueChanged()} signal to the \c + changeSize() slot to make sure that the size of the preview + area's icon is updated whenever the user changes the icon size. + In the end we put the widgets in a layout that we install on the + group box. + + \snippet examples/widgets/icons/mainwindow.cpp 28 + + In the \c createActions() function we create and customize all the + actions needed to implement the functionality associated with the + menu entries in the application. + + In particular we create the \c styleActionGroup based on the + currently available GUI styles using + QStyleFactory. QStyleFactory::keys() returns a list of valid keys, + typically including "windows", "motif", "cde", and + "plastique". Depending on the platform, "windowsxp" and + "macintosh" may be available. + + We create one action for each key, and adds the action to the + action group. Also, for each action, we call QAction::setData() + with the style name. We will retrieve it later using + QAction::data(). + + \snippet examples/widgets/icons/mainwindow.cpp 29 + + In the \c createMenu() function, we add the previously created + actions to the \gui File, \gui View and \gui Help menus. + + The QMenu class provides a menu widget for use in menu bars, + context menus, and other popup menus. We put each menu in the + application's menu bar, which we retrieve using + QMainWindow::menuBar(). + + \snippet examples/widgets/icons/mainwindow.cpp 30 + + QWidgets have a \l{QWidget::contextMenuPolicy}{contextMenuPolicy} + property that controls how the widget should behave when the user + requests a context menu (e.g., by right-clicking). We set the + QTableWidget's context menu policy to Qt::ActionsContextMenu, + meaning that the \l{QAction}s associated with the widget should + appear in its context menu. + + Then we add the \gui{Add Image} and \gui{Remove All Images} + actions to the table widget. They will then appear in the table + widget's context menu. + + \snippet examples/widgets/icons/mainwindow.cpp 31 + + In the \c checkCurrentStyle() function we go through the group of + style actions, looking for the current GUI style. + + For each action, we first extract the style name using + QAction::data(). Since this is only a QStyleFactory key (e.g., + "macintosh"), we cannot compare it directly to the current + style's class name. We need to create a QStyle object using the + static QStyleFactory::create() function and compare the class + name of the created QStyle object with that of the current style. + As soon as we are done with a QStyle candidate, we delete it. + + For all QObject subclasses that use the \c Q_OBJECT macro, the + class name of an object is available through its + \l{QObject::metaObject()}{meta-object}. + + We can assume that the style is supported by + QStyleFactory, but to be on the safe side we use the \c + Q_ASSERT() macro to make sure that QStyleFactory::create() + returned a valid pointer. + + \section2 IconSizeSpinBox Class Definition + + \snippet examples/widgets/icons/iconsizespinbox.h 0 + + The \c IconSizeSpinBox class is a subclass of QSpinBox. A plain + QSpinBox can only handle integers. But since we want to display + the spin box's values in a more sophisticated way, we need to + subclass QSpinBox and reimplement the QSpinBox::textFromValue() + and QSpinBox::valueFromText() functions. + + \image icons_size_spinbox.png Screenshot of the icon size spinbox + + \section2 IconSizeSpinBox Class Implementation + + \snippet examples/widgets/icons/iconsizespinbox.cpp 0 + + The constructor is trivial. + + \snippet examples/widgets/icons/iconsizespinbox.cpp 2 + + QSpinBox::textFromValue() is used by the spin box whenever it + needs to display a value. The default implementation returns a + base 10 representation of the \c value parameter. + + Our reimplementation returns a QString of the form "32 x 32". + + \snippet examples/widgets/icons/iconsizespinbox.cpp 1 + + The QSpinBox::valueFromText() function is used by the spin box + whenever it needs to interpret text typed in by the user. Since + we reimplement the \c textFromValue() function we also need to + reimplement the \c valueFromText() function to interpret the + parameter text and return the associated int value. + + We parse the text using a regular expression (a QRegExp). We + define an expression that matches one or several digits, + optionally followed by whitespace, an "x" or the times symbol, + whitespace and one or several digits again. + + The first digits of the regular expression are captured using + parentheses. This enables us to use the QRegExp::cap() or + QRegExp::capturedTexts() functions to extract the matched + characters. If the first and second numbers of the spin box value + differ (e.g., "16 x 24"), we use the first number. + + When the user presses \key Enter, QSpinBox first calls + QSpinBox::valueFromText() to interpret the text typed by the + user, then QSpinBox::textFromValue() to present it in a canonical + format (e.g., "16 x 16"). + + \section2 ImageDelegate Class Definition + + \snippet examples/widgets/icons/imagedelegate.h 0 + + The \c ImageDelegate class is a subclass of QItemDelegate. The + QItemDelegate class provides display and editing facilities for + data items from a model. A single QItemDelegate object is + responsible for all items displayed in a item view (in our case, + a QTableWidget). + + A QItemDelegate can be used to provide an editor for an item view + class that is subclassed from QAbstractItemView. Using a delegate + for this purpose allows the editing mechanism to be customized and + developed independently from the model and view. + + \snippet examples/widgets/icons/imagedelegate.h 1 + + The default implementation of QItemDelegate creates a QLineEdit. + Since we want the editor to be a QComboBox, we need to subclass + QItemDelegate and reimplement the QItemDelegate::createEditor(), + QItemDelegate::setEditorData() and QItemDelegate::setModelData() + functions. + + \snippet examples/widgets/icons/imagedelegate.h 2 + + The \c emitCommitData() slot is used to emit the + QImageDelegate::commitData() signal with the appropriate + argument. + + \section2 ImageDelegate Class Implementation + + \snippet examples/widgets/icons/imagedelegate.cpp 0 + + The constructor is trivial. + + \snippet examples/widgets/icons/imagedelegate.cpp 1 + + The default QItemDelegate::createEditor() implementation returns + the widget used to edit the item specified by the model and item + index for editing. The parent widget and style option are used to + control the appearance of the editor widget. + + Our reimplementation create and populate a combobox instead of + the default line edit. The contents of the combobox depends on + the column in the table for which the editor is requested. Column + 1 contains the QIcon modes, whereas column 2 contains the QIcon + states. + + In addition, we connect the combobox's \l + {QComboBox::activated()}{activated()} signal to the \c + emitCommitData() slot to emit the + QAbstractItemDelegate::commitData() signal whenever the user + chooses an item using the combobox. This ensures that the rest of + the application notices the change and updates itself. + + \snippet examples/widgets/icons/imagedelegate.cpp 2 + + The QItemDelegate::setEditorData() function is used by + QTableWidget to transfer data from a QTableWidgetItem to the + editor. The data is stored as a string; we use + QComboBox::findText() to locate it in the combobox. + + Delegates work in terms of models, not items. This makes it + possible to use them with any item view class (e.g., QListView, + QListWidget, QTreeView, etc.). The transition between model and + items is done implicitly by QTableWidget; we don't need to worry + about it. + + \snippet examples/widgets/icons/imagedelegate.cpp 3 + + The QItemDelegate::setEditorData() function is used by QTableWidget + to transfer data back from the editor to the \l{QTableWidgetItem}. + + \snippet examples/widgets/icons/imagedelegate.cpp 4 + + The \c emitCommitData() slot simply emit the + QAbstractItemDelegate::commitData() signal for the editor that + triggered the slot. This signal must be emitted when the editor + widget has completed editing the data, and wants to write it back + into the model. +*/ diff --git a/doc/src/examples/imagecomposition.qdoc b/doc/src/examples/imagecomposition.qdoc new file mode 100644 index 0000000..8cba805 --- /dev/null +++ b/doc/src/examples/imagecomposition.qdoc @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example painting/imagecomposition + \title Image Composition Example + + The Image Composition example lets the user combine images + together using any composition mode supported by QPainter, described + in detail in \l{QPainter#Composition Modes}{Composition Modes}. + + \image imagecomposition-example.png + + \section1 Setting Up The Resource File + + The Image Composition example requires two source images, + \e butterfly.png and \e checker.png that are embedded within + \e imagecomposition.qrc. The file contains the following code: + + \quotefile examples/painting/imagecomposition/imagecomposition.qrc + + For more information on resource files, see \l{The Qt Resource System}. + + \section1 ImageComposer Class Definition + + The \c ImageComposer class is a subclass of QWidget that implements three + private slots, \c chooseSource(), \c chooseDestination(), and + \c recalculateResult(). + + \snippet examples/painting/imagecomposition/imagecomposer.h 0 + + In addition, \c ImageComposer consists of five private functions, + \c addOp(), \c chooseImage(), \c loadImage(), \c currentMode(), and + \c imagePos(), as well as private instances of QToolButton, QComboBox, + QLabel, and QImage. + + \snippet examples/painting/imagecomposition/imagecomposer.h 1 + + \section1 ImageComposer Class Implementation + + We declare a QSize object, \c resultSize, as a static constant with width + and height equal to 200. + + \snippet examples/painting/imagecomposition/imagecomposer.cpp 0 + + Within the constructor, we instantiate a QToolButton object, + \c sourceButton and set its \l{QAbstractButton::setIconSize()}{iconSize} + property to \c resultSize. The \c operatorComboBox is instantiated and + then populated using the \c addOp() function. This function accepts a + QPainter::CompositionMode, \a mode, and a QString, \a name, representing + the name of the composition mode. + + \snippet examples/painting/imagecomposition/imagecomposer.cpp 1 + + The \c destinationButton is instantiated and its + \l{QAbstractButton::setIconSize()}{iconSize} property is set to + \c resultSize as well. The \l{QLabel}s \c equalLabel and \c resultLabel + are created and \c{resultLabel}'s \l{QWidget::setMinimumWidth()} + {minimumWidth} is set. + + \snippet examples/painting/imagecomposition/imagecomposer.cpp 2 + + We connect the following signals to their corresponding slots: + \list + \o \c{sourceButton}'s \l{QPushButton::clicked()}{clicked()} signal is + connected to \c chooseSource(), + \o \c{operatorComboBox}'s \l{QComboBox::activated()}{activated()} + signal is connected to \c recalculateResult(), and + \o \c{destinationButton}'s \l{QToolButton::clicked()}{clicked()} signal + is connected to \c chooseDestination(). + \endlist + + \snippet examples/painting/imagecomposition/imagecomposer.cpp 3 + + A QGridLayout, \c mainLayout, is used to place all the widgets. Note + that \c{mainLayout}'s \l{QLayout::setSizeConstraint()}{sizeConstraint} + property is set to QLayout::SetFixedSize, which means that + \c{ImageComposer}'s size cannot be resized at all. + + \snippet examples/painting/imagecomposition/imagecomposer.cpp 4 + + We create a QImage, \c resultImage, and we invoke \c loadImage() twice + to load both the image files in our \e imagecomposition.qrc file. Then, + we set the \l{QWidget::setWindowTitle()}{windowTitle} property to + "Image Composition". + + \snippet examples/painting/imagecomposition/imagecomposer.cpp 5 + + The \c chooseSource() and \c chooseDestination() functions are + convenience functions that invoke \c chooseImage() with specific + parameters. + + \snippet examples/painting/imagecomposition/imagecomposer.cpp 6 + \codeline + \snippet examples/painting/imagecomposition/imagecomposer.cpp 7 + + The \c chooseImage() function loads an image of the user's choice, + depending on the \a title, \a image, and \a button. + + \snippet examples/painting/imagecomposition/imagecomposer.cpp 10 + + The \c recalculateResult() function is used to calculate amd display the + result of combining the two images together with the user's choice of + composition mode. + + \snippet examples/painting/imagecomposition/imagecomposer.cpp 8 + + The \c addOp() function adds an item to the \c operatorComboBox using + \l{QComboBox}'s \l{QComboBox::addItem()}{addItem} function. This function + accepts a QPainter::CompositionMode, \a mode, and a QString, \a name. The + rectangle is filled with Qt::Transparent and both the \c sourceImage and + \c destinationImage are painted, before displaying it on \c resultLabel. + + \snippet examples/painting/imagecomposition/imagecomposer.cpp 9 + + The \c loadImage() function paints a transparent background using + \l{QPainter::fillRect()}{fillRect()} and draws \c image in a + centralized position using \l{QPainter::drawImage()}{drawImage()}. + This \c image is then set as the \c{button}'s icon. + + \snippet examples/painting/imagecomposition/imagecomposer.cpp 11 + + The \c currentMode() function returns the composition mode currently + selected in \c operatorComboBox. + + \snippet examples/painting/imagecomposition/imagecomposer.cpp 12 + + We use the \c imagePos() function to ensure that images loaded onto the + QToolButton objects, \c sourceButton and \c destinationButton, are + centralized. + + \snippet examples/painting/imagecomposition/imagecomposer.cpp 13 + + \section1 The \c main() Function + + The \c main() function instantiates QApplication and \c ImageComposer + and invokes its \l{QWidget::show()}{show()} function. + + \snippet examples/painting/imagecomposition/main.cpp 0 + + */ diff --git a/doc/src/examples/imageviewer.qdoc b/doc/src/examples/imageviewer.qdoc new file mode 100644 index 0000000..6881673 --- /dev/null +++ b/doc/src/examples/imageviewer.qdoc @@ -0,0 +1,340 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/imageviewer + \title Image Viewer Example + + The example shows how to combine QLabel and QScrollArea to + display an image. QLabel is typically used for displaying text, + but it can also display an image. QScrollArea provides a + scrolling view around another widget. If the child widget exceeds + the size of the frame, QScrollArea automatically provides scroll + bars. + + The example demonstrates how QLabel's ability to scale its + contents (QLabel::scaledContents), and QScrollArea's ability to + automatically resize its contents (QScrollArea::widgetResizable), + can be used to implement zooming and scaling features. In + addition the example shows how to use QPainter to print an image. + + \image imageviewer-example.png Screenshot of the Image Viewer example + + With the Image Viewer application, the users can view an image of + their choice. The \gui File menu gives the user the possibility + to: + + \list + \o \gui{Open...} - Open an image file + \o \gui{Print...} - Print an image + \o \gui{Exit} - Exit the application + \endlist + + Once an image is loaded, the \gui View menu allows the users to: + + \list + \o \gui{Zoom In} - Scale the image up by 25% + \o \gui{Zoom Out} - Scale the image down by 25% + \o \gui{Normal Size} - Show the image at its original size + \o \gui{Fit to Window} - Stretch the image to occupy the entire window + \endlist + + In addition the \gui Help menu provides the users with information + about the Image Viewer example in particular, and about Qt in + general. + + \section1 ImageViewer Class Definition + + \snippet examples/widgets/imageviewer/imageviewer.h 0 + + The \c ImageViewer class inherits from QMainWindow. We reimplement + the constructor, and create several private slots to facilitate + the menu entries. In addition we create four private functions. + + We use \c createActions() and \c createMenus() when constructing + the \c ImageViewer widget. We use the \c updateActions() function + to update the menu entries when a new image is loaded, or when + the \gui {Fit to Window} option is toggled. The zoom slots use \c + scaleImage() to perform the zooming. In turn, \c + scaleImage() uses \c adjustScrollBar() to preserve the focal point after + scaling an image. + + \section1 ImageViewer Class Implementation + + \snippet examples/widgets/imageviewer/imageviewer.cpp 0 + + In the constructor we first create the label and the scroll area. + + We set \c {imageLabel}'s size policy to \l + {QSizePolicy::Ignored}{ignored}, making the users able to scale + the image to whatever size they want when the \gui {Fit to Window} + option is turned on. Otherwise, the default size polizy (\l + {QSizePolicy::Preferred}{preferred}) will make scroll bars appear + when the scroll area becomes smaller than the label's minimum size + hint. + + We ensure that the label will scale its contents to fill all + available space, to enable the image to scale properly when + zooming. If we omitted to set the \c {imageLabel}'s \l + {QLabel::scaledContents}{scaledContents} property, zooming in + would enlarge the QLabel, but leave the pixmap at + its original size, exposing the QLabel's background. + + We make \c imageLabel the scroll area's child widget, and we make + \c scrollArea the central widget of the QMainWindow. At the end + we create the associated actions and menus, and customize the \c + {ImageViewer}'s appearance. + + \snippet examples/widgets/imageviewer/imageviewer.cpp 1 + \snippet examples/widgets/imageviewer/imageviewer.cpp 2 + + In the \c open() slot, we show a file dialog to the user. The + easiest way to create a QFileDialog is to use the static + convenience functions. QFileDialog::getOpenFileName() returns an + existing file selected by the user. If the user presses \gui + Cancel, QFileDialog returns an empty string. + + Unless the file name is a empty string, we check if the file's + format is an image format by constructing a QImage which tries to + load the image from the file. If the constructor returns a null + image, we use a QMessageBox to alert the user. + + The QMessageBox class provides a modal dialog with a short + message, an icon, and some buttons. As with QFileDialog the + easiest way to create a QMessageBox is to use its static + convenience functions. QMessageBox provides a range of different + messages arranged along two axes: severity (question, + information, warning and critical) and complexity (the number of + necessary response buttons). In this particular example an + information message with an \gui OK button (the default) is + sufficient, since the message is part of a normal operation. + + \snippet examples/widgets/imageviewer/imageviewer.cpp 3 + \snippet examples/widgets/imageviewer/imageviewer.cpp 4 + + If the format is supported, we display the image in \c imageLabel + by setting the label's \l {QLabel::pixmap}{pixmap}. Then we enable + the \gui Print and \gui {Fit to Window} menu entries and update + the rest of the view menu entries. The \gui Open and \gui Exit + entries are enabled by default. + + If the \gui {Fit to Window} option is turned off, the + QScrollArea::widgetResizable property is \c false and it is + our responsibility (not QScrollArea's) to give the QLabel a + reasonable size based on its contents. We call + \{QWidget::adjustSize()}{adjustSize()} to achieve this, which is + essentially the same as + + \snippet doc/src/snippets/code/doc_src_examples_imageviewer.qdoc 0 + + In the \c print() slot, we first make sure that an image has been + loaded into the application: + + \snippet examples/widgets/imageviewer/imageviewer.cpp 5 + \snippet examples/widgets/imageviewer/imageviewer.cpp 6 + + If the application is built in debug mode, the \c Q_ASSERT() macro + will expand to + + \snippet doc/src/snippets/code/doc_src_examples_imageviewer.qdoc 1 + + In release mode, the macro simply disappear. The mode can be set + in the application's \c .pro file. One way to do so is to add an + option to \gui qmake when building the appliction: + + \snippet doc/src/snippets/code/doc_src_examples_imageviewer.qdoc 2 + + or + + \snippet doc/src/snippets/code/doc_src_examples_imageviewer.qdoc 3 + + Another approach is to add this line directly to the \c .pro + file. + + \snippet examples/widgets/imageviewer/imageviewer.cpp 7 + \snippet examples/widgets/imageviewer/imageviewer.cpp 8 + + Then we present a print dialog allowing the user to choose a + printer and to set a few options. We construct a painter with a + QPrinter as the paint device. We set the painter's window + and viewport in such a way that the image is as large as possible + on the paper, but without altering its + \l{Qt::KeepAspectRatio}{aspect ratio}. + + In the end we draw the pixmap at position (0, 0). + + \snippet examples/widgets/imageviewer/imageviewer.cpp 9 + \snippet examples/widgets/imageviewer/imageviewer.cpp 10 + + We implement the zooming slots using the private \c scaleImage() + function. We set the scaling factors to 1.25 and 0.8, + respectively. These factor values ensure that a \gui {Zoom In} + action and a \gui {Zoom Out} action will cancel each other (since + 1.25 * 0.8 == 1), and in that way the normal image size can be + restored using the zooming features. + + The screenshots below show an image in its normal size, and the + same image after zooming in: + + \table + \row + \o \inlineimage imageviewer-original_size.png + \o \inlineimage imageviewer-zoom_in_1.png + \o \inlineimage imageviewer-zoom_in_2.png + \endtable + + \snippet examples/widgets/imageviewer/imageviewer.cpp 11 + \snippet examples/widgets/imageviewer/imageviewer.cpp 12 + + When zooming, we use the QLabel's ability to scale its contents. + Such scaling doesn't change the actual size hint of the contents. + And since the \l {QLabel::adjustSize()}{adjustSize()} function + use those size hint, the only thing we need to do to restore the + normal size of the currently displayed image is to call \c + adjustSize() and reset the scale factor to 1.0. + + \snippet examples/widgets/imageviewer/imageviewer.cpp 13 + \snippet examples/widgets/imageviewer/imageviewer.cpp 14 + + The \c fitToWindow() slot is called each time the user toggled + the \gui {Fit to Window} option. If the slot is called to turn on + the option, we tell the scroll area to resize its child widget + with the QScrollArea::setWidgetResizable() function. Then we + disable the \gui {Zoom In}, \gui {Zoom Out} and \gui {Normal + Size} menu entries using the private \c updateActions() function. + + If the \l {QScrollArea::widgetResizable} property is set to \c + false (the default), the scroll area honors the size of its child + widget. If this property is set to \c true, the scroll area will + automatically resize the widget in order to avoid scroll bars + where they can be avoided, or to take advantage of extra space. + But the scroll area will honor the minimum size hint of its child + widget independent of the widget resizable property. So in this + example we set \c {imageLabel}'s size policy to \l + {QSizePolicy::Ignored}{ignored} in the constructor, to avoid that + scroll bars appear when the scroll area becomes smaller than the + label's minimum size hint. + + The screenshots below shows an image in its normal size, and the + same image with the \gui {Fit to window} option turned on. + Enlarging the window will stretch the image further, as shown in + the third screenshot. + + \table + \row + \o \inlineimage imageviewer-original_size.png + \o \inlineimage imageviewer-fit_to_window_1.png + \o \inlineimage imageviewer-fit_to_window_2.png + \endtable + + If the slot is called to turn off the option, the + {QScrollArea::setWidgetResizable} property is set to \c false. We + also restore the image pixmap to its normal size by adjusting the + label's size to its content. And in the end we update the view + menu entries. + + \snippet examples/widgets/imageviewer/imageviewer.cpp 15 + \snippet examples/widgets/imageviewer/imageviewer.cpp 16 + + We implement the \c about() slot to create a message box + describing what the example is designed to show. + + \snippet examples/widgets/imageviewer/imageviewer.cpp 17 + \snippet examples/widgets/imageviewer/imageviewer.cpp 18 + + In the private \c createAction() function, we create the + actions providing the application features. + + We assign a short-cut key to each action and connect them to the + appropiate slots. We only enable the \c openAct and \c exitAxt at + the time of creation, the others are updated once an image has + been loaded into the application. In addition we make the \c + fitToWindowAct \l {QAction::checkable}{checkable}. + + \snippet examples/widgets/imageviewer/imageviewer.cpp 19 + \snippet examples/widgets/imageviewer/imageviewer.cpp 20 + + In the private \c createMenu() function, we add the previously + created actions to the \gui File, \gui View and \gui Help menus. + + The QMenu class provides a menu widget for use in menu bars, + context menus, and other popup menus. The QMenuBar class provides + a horizontal menu bar that consists of a list of pull-down menu + items. So at the end we put the menus in the \c {ImageViewer}'s + menu bar which we retrieve with the QMainWindow::menuBar() + function. + + \snippet examples/widgets/imageviewer/imageviewer.cpp 21 + \snippet examples/widgets/imageviewer/imageviewer.cpp 22 + + The private \c updateActions() function enables or disables the + \gui {Zoom In}, \gui {Zoom Out} and \gui {Normal Size} menu + entries depending on whether the \gui {Fit to Window} option is + turned on or off. + + \snippet examples/widgets/imageviewer/imageviewer.cpp 23 + \snippet examples/widgets/imageviewer/imageviewer.cpp 24 + + In \c scaleImage(), we use the \c factor parameter to calculate + the new scaling factor for the displayed image, and resize \c + imageLabel. Since we set the + \l{QLabel::scaledContents}{scaledContents} property to \c true in + the constructor, the call to QWidget::resize() will scale the + image displayed in the label. We also adjust the scroll bars to + preserve the focal point of the image. + + At the end, if the scale factor is less than 33.3% or greater + than 300%, we disable the respective menu entry to prevent the + image pixmap from becoming too large, consuming too much + resources in the window system. + + \snippet examples/widgets/imageviewer/imageviewer.cpp 25 + \snippet examples/widgets/imageviewer/imageviewer.cpp 26 + + Whenever we zoom in or out, we need to adjust the scroll bars in + consequence. It would have been tempting to simply call + + \snippet doc/src/snippets/code/doc_src_examples_imageviewer.qdoc 4 + + but this would make the top-left corner the focal point, not the + center. Therefore we need to take into account the scroll bar + handle's size (the \l{QScrollBar::pageStep}{page step}). +*/ diff --git a/doc/src/examples/itemviewspuzzle.qdoc b/doc/src/examples/itemviewspuzzle.qdoc new file mode 100644 index 0000000..99ef7d4 --- /dev/null +++ b/doc/src/examples/itemviewspuzzle.qdoc @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/puzzle + \title Item Views Puzzle Example + + The Puzzle example shows how to enable drag and drop with a custom model + to allow items to be transferred between a view and another widget. + + \image itemviewspuzzle-example.png + + This example is an implementation of a simple jigsaw puzzle game using the + built-in support for drag and drop provided by Qt's model/view framework. + The \l{Drag and Drop Puzzle Example}{Drag and Drop Puzzle} example shows + many of the same features, but takes an alternative approach that uses Qt's + drag and drop API at the application level to handle drag and drop + operations. +*/ diff --git a/doc/src/examples/licensewizard.qdoc b/doc/src/examples/licensewizard.qdoc new file mode 100644 index 0000000..a702c06 --- /dev/null +++ b/doc/src/examples/licensewizard.qdoc @@ -0,0 +1,232 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example dialogs/licensewizard + \title License Wizard Example + + The License Wizard example shows how to implement complex wizards in + Qt. + + \image licensewizard-example.png Screenshot of the License Wizard example + + Most wizards have a linear structure, with page 1 followed by + page 2 and so on until the last page. The + \l{dialogs/classwizard}{Class Wizard} example shows how to create + such wizards. + + Some wizards are more complex in that they allow different + traversal paths based on the information provided by the user. + The License Wizard example illustrates this. It provides five + wizard pages; depending on which options are selected, the user + can reach different pages. + + \image licensewizard-flow.png The License Wizard pages + + The example consists of the following classes: + + \list + \o \c LicenseWizard inherits QWizard and implements a non-linear + five-page wizard that leads the user through the process of + choosing a license agreement. + \o \c IntroPage, \c EvaluatePage, \c RegisterPage, \c + DetailsPage, and \c ConclusionPage are QWizardPage subclasses + that implement the wizard pages. + \endlist + + \section1 The LicenseWizard Class + + The \c LicenseWizard class derives from QWizard and provides a + five-page wizard that guides the user through the process of + registering their copy of a fictitious software product. Here's + the class definition: + + \snippet examples/dialogs/licensewizard/licensewizard.h 1 + + The class's public API is limited to a constructor and an enum. + The enum defines the IDs associated with the various pages: + + \table + \header \o Class name \o Enum value \o Page ID + \row \o \c IntroPage \o \c Page_Intro \o 0 + \row \o \c EvaluatePage \o \c Page_Evaluate \o 1 + \row \o \c RegisterPage \o \c Page_Register \o 2 + \row \o \c DetailsPage \o \c Page_Details \o 3 + \row \o \c ConclusionPage \o \c Page_Conclusion \o 4 + \endtable + + For this example, the IDs are arbitrary. The only constraints are + that they must be unique and different from -1. IDs allow us to + refer to pages. + + \snippet examples/dialogs/licensewizard/licensewizard.cpp 2 + + In the constructor, we create the five pages, insert them into + the wizard using QWizard::setPage(), and set \c Page_Intro to be + the first page. + + \snippet examples/dialogs/licensewizard/licensewizard.cpp 3 + \snippet examples/dialogs/licensewizard/licensewizard.cpp 4 + + We set the style to \l{QWizard::}{ModernStyle} on all platforms + except Mac OS X, + + \snippet examples/dialogs/licensewizard/licensewizard.cpp 5 + \snippet examples/dialogs/licensewizard/licensewizard.cpp 6 + + We configure the QWizard to show a \gui Help button, which is + connected to our \c showHelp() slot. We also set the + \l{QWizard::}{LogoPixmap} for all pages that have a header (i.e., + \c EvaluatePage, \c RegisterPage, and \c DetailsPage). + + \snippet examples/dialogs/licensewizard/licensewizard.cpp 9 + \snippet examples/dialogs/licensewizard/licensewizard.cpp 11 + \dots + \snippet examples/dialogs/licensewizard/licensewizard.cpp 13 + + In \c showHelp(), we display help texts that are appropiate for + the current page. If the user clicks \gui Help twice for the same + page, we say, "Sorry, I already gave what help I could. Maybe you + should try asking a human?" + + \section1 The IntroPage Class + + The pages are defined in \c licensewizard.h and implemented in \c + licensewizard.cpp, together with \c LicenseWizard. + + Here's the definition and implementation of \c{IntroPage}: + + \snippet examples/dialogs/licensewizard/licensewizard.h 4 + \codeline + \snippet examples/dialogs/licensewizard/licensewizard.cpp 16 + + A page inherits from QWizardPage. We set a + \l{QWizardPage::}{title} and a + \l{QWizard::WatermarkPixmap}{watermark pixmap}. By not setting + any \l{QWizardPage::}{subTitle}, we ensure that no header is + displayed for this page. (On Windows, it is customary for wizards + to display a watermark pixmap on the first and last pages, and to + have a header on the other pages.) + + \snippet examples/dialogs/licensewizard/licensewizard.cpp 17 + \snippet examples/dialogs/licensewizard/licensewizard.cpp 19 + + The \c nextId() function returns the ID for \c EvaluatePage if + the \gui{Evaluate the product for 30 days} option is checked; + otherwise it returns the ID for \c RegisterPage. + + \section1 The EvaluatePage Class + + The \c EvaluatePage is slightly more involved: + + \snippet examples/dialogs/licensewizard/licensewizard.h 5 + \codeline + \snippet examples/dialogs/licensewizard/licensewizard.cpp 20 + \dots + \snippet examples/dialogs/licensewizard/licensewizard.cpp 21 + \dots + \snippet examples/dialogs/licensewizard/licensewizard.cpp 22 + + First, we set the page's \l{QWizardPage::}{title} + and \l{QWizardPage::}{subTitle}. + + Then we create the child widgets, create \l{Registering and Using + Fields}{wizard fields} associated with them, and put them into + layouts. The fields are created with an asterisk (\c + *) next to their name. This makes them \l{mandatory fields}, that + is, fields that must be filled before the user can press the + \gui Next button (\gui Continue on Mac OS X). The fields' values + can be accessed from any other page using QWizardPage::field(). + + Resetting the page amounts to clearing the two text fields. + + \snippet examples/dialogs/licensewizard/licensewizard.cpp 23 + + The next page is always the \c ConclusionPage. + + \section1 The ConclusionPage Class + + The \c RegisterPage and \c DetailsPage are very similar to \c + EvaluatePage. Let's go directly to the \c ConclusionPage: + + \snippet examples/dialogs/licensewizard/licensewizard.h 6 + + This time, we reimplement QWizardPage::initializePage() and + QWidget::setVisible(), in addition to + \l{QWizardPage::}{nextId()}. We also declare a private slot: + \c printButtonClicked(). + + \snippet examples/dialogs/licensewizard/licensewizard.cpp 18 + + The default implementation of QWizardPage::nextId() returns + the page with the next ID, or -1 if the current page has the + highest ID. This behavior would work here, because \c + Page_Conclusion equals 5 and there is no page with a higher ID, + but to avoid relying on such subtle behavior, we reimplement + \l{QWizardPage::}{nextId()} to return -1. + + \snippet examples/dialogs/licensewizard/licensewizard.cpp 27 + + We use QWizard::hasVisitedPage() to determine the type of + license agreement the user has chosen. If the user filled the \c + EvaluatePage, the license text refers to an Evaluation License + Agreement. If the user filled the \c DetailsPage, the license + text is a First-Time License Agreement. If the user provided an + upgrade key and skipped the \c DetailsPage, the license text is + an Update License Agreement. + + \snippet examples/dialogs/licensewizard/licensewizard.cpp 28 + + We want to display a \gui Print button in the wizard when the \c + ConclusionPage is up. One way to accomplish this is to reimplement + QWidget::setVisible(): + + \list + \o If the page is shown, we set the \l{QWizard::}{CustomButton1} button's + text to \gui{\underline{P}rint}, we enable the \l{QWizard::}{HaveCustomButton1} + option, and we connect the QWizard's \l{QWizard::}{customButtonClicked()} + signal to our \c printButtonClicked() slot. + \o If the page is hidden, we disable the \l{QWizard::}{HaveCustomButton1} + option and disconnect the \c printButtonClicked() slot. + \endlist + + \sa QWizard, {Class Wizard Example}, {Trivial Wizard Example} +*/ diff --git a/doc/src/examples/lineedits.qdoc b/doc/src/examples/lineedits.qdoc new file mode 100644 index 0000000..ee702ae --- /dev/null +++ b/doc/src/examples/lineedits.qdoc @@ -0,0 +1,175 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/lineedits + \title Line Edits Example + + The Line Edits example demonstrates the many ways that QLineEdit can be used, and + shows the effects of various properties and validators on the input and output + supplied by the user. + + \image lineedits-example.png + + The example consists of a single \c Window class, containing a selection of + line edits with different input constraints and display properties that can be + changed by selecting items from comboboxes. Presenting these together helps + developers choose suitable properties to use with line edits, and makes it easy + to compare the effects of each validator on user input. + + \section1 Window Class Definition + + The \c Window class inherits QWidget and contains a constructor and several + slots: + + \snippet examples/widgets/lineedits/window.h 0 + + The slots are used to update the type of validator used for a given line edit when + a new validator has been selected in the associated combobox. The line edits + are stored in the window for use in these slots. + + \section1 Window Class Implementation + + The \c Window constructor is used to set up the line edits, validators, + and comboboxes, connect signals from the comboboxes to slots in the \c Window + class, and arrange the child widgets in layouts. + + We begin by constructing a \l{QGroupBox}{group box} to hold a label, combobox, + and line edit so that we can demonstrate the QLineEdit::echoMode property: + + \snippet examples/widgets/lineedits/window.cpp 0 + + At this point, none of these widgets have been arranged in layouts. Eventually, + the \c echoLabel, \c echoComboBox, and \c echoLineEdit will be placed in a + vertical layout inside the \c echoGroup group box. + + Similarly, we construct group boxes and collections of widgets to show the + effects of QIntValidator and QDoubleValidator on a line edit's contents: + + \snippet examples/widgets/lineedits/window.cpp 1 + + Text alignment is demonstrated by another group of widgets: + + \snippet examples/widgets/lineedits/window.cpp 2 + + QLineEdit supports the use of \l{QLineEdit::inputMask}{input masks}. + These only allow the user to type characters into the line edit that + follow a simple specification. We construct a group of widgets to + demonstrate a selection of predefined masks: + + \snippet examples/widgets/lineedits/window.cpp 3 + + Another useful feature of QLineEdit is its ability to make its contents + read-only. This property is used to control access to a line edit in the + following group of widgets: + + \snippet examples/widgets/lineedits/window.cpp 4 + + Now that all the child widgets have been constructed, we connect signals + from the comboboxes to slots in the \c Window object: + + \snippet examples/widgets/lineedits/window.cpp 5 + + Each of these connections use the QComboBox::activated() signal that + supplies an integer to the slot. This will be used to efficiently + make changes to the appropriate line edit in each slot. + + We place each combobox, line edit, and label in a layout for each group + box, beginning with the layout for the \c echoGroup group box: + + \snippet examples/widgets/lineedits/window.cpp 6 + + The other layouts are constructed in the same way: + + \snippet examples/widgets/lineedits/window.cpp 7 + + Finally, we place each group box in a grid layout for the \c Window object + and set the window title: + + \snippet examples/widgets/lineedits/window.cpp 8 + + The slots respond to signals emitted when the comboboxes are changed by the + user. + + When the combobox for the \gui{Echo} group box is changed, the \c echoChanged() + slot is called: + + \snippet examples/widgets/lineedits/window.cpp 9 + + The slot updates the line edit in the same group box to use an echo mode that + corresponds to the entry described in the combobox. + + When the combobox for the \gui{Validator} group box is changed, the + \c validatorChanged() slot is called: + + \snippet examples/widgets/lineedits/window.cpp 10 + + The slot either creates a new validator for the line edit to use, or it removes + the validator in use by calling QLineEdit::setValidator() with a zero pointer. + We clear the line edit in this case to ensure that the new validator is + initially given valid input to work with. + + When the combobox for the \gui{Alignment} group box is changed, the + \c alignmentChanged() slot is called: + + \snippet examples/widgets/lineedits/window.cpp 11 + + This changes the way that text is displayed in the line edit to correspond with + the description selected in the combobox. + + The \c inputMaskChanged() slot handles changes to the combobox in the + \gui{Input Mask} group box: + + \snippet examples/widgets/lineedits/window.cpp 12 + + Each entry in the relevant combobox is associated with an input mask. We set + a new mask by calling the QLineEdit::setMask() function with a suitable string; + the mask is disabled if an empty string is used. + + The \c accessChanged() slot handles changes to the combobox in the + \gui{Access} group box: + + \snippet examples/widgets/lineedits/window.cpp 13 + + Here, we simply associate the \gui{False} and \gui{True} entries in the combobox + with \c false and \c true values to be passed to QLineEdit::setReadOnly(). This + allows the user to enable and disable input to the line edit. +*/ diff --git a/doc/src/examples/localfortuneclient.qdoc b/doc/src/examples/localfortuneclient.qdoc new file mode 100644 index 0000000..b4489b1 --- /dev/null +++ b/doc/src/examples/localfortuneclient.qdoc @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example ipc/localfortuneclient + \title Local Fortune Client Example + + The Local Fortune Client example shows how to create a client for a simple + local service using QLocalSocket. It is intended to be run alongside the + \l{ipc/localfortuneserver}{Local Fortune Server} example. + + \image localfortuneclient-example.png Screenshot of the Local Fortune Client example + +*/ diff --git a/doc/src/examples/localfortuneserver.qdoc b/doc/src/examples/localfortuneserver.qdoc new file mode 100644 index 0000000..3b2395c --- /dev/null +++ b/doc/src/examples/localfortuneserver.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example ipc/localfortuneserver + \title Local Fortune Server Example + + The Local Fortune Server example shows how to create a server for a simple + local service. It is intended to be run alongside the + \l{ipc/localfortuneclient}{Local Fortune Client} example + + \image localfortuneserver-example.png Screenshot of the Local Fortune Server example + */ diff --git a/doc/src/examples/loopback.qdoc b/doc/src/examples/loopback.qdoc new file mode 100644 index 0000000..b100f71 --- /dev/null +++ b/doc/src/examples/loopback.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example network/loopback + \title Loopback Example + + The Loopback example shows how to communicate between simple clients and servers on a local + host. + + \image loopback-example.png +*/ diff --git a/doc/src/examples/mandelbrot.qdoc b/doc/src/examples/mandelbrot.qdoc new file mode 100644 index 0000000..d2a3ee1 --- /dev/null +++ b/doc/src/examples/mandelbrot.qdoc @@ -0,0 +1,382 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example threads/mandelbrot + \title Mandelbrot Example + + The Mandelbrot example shows how to use a worker thread to + perform heavy computations without blocking the main thread's + event loop. + + The heavy computation here is the Mandelbrot set, probably the + world's most famous fractal. These days, while sophisticated + programs such as \l{XaoS} that provide real-time zooming in the + Mandelbrot set, the standard Mandelbrot algorithm is just slow + enough for our purposes. + + \image mandelbrot-example.png Screenshot of the Mandelbrot example + + In real life, the approach described here is applicable to a + large set of problems, including synchronous network I/O and + database access, where the user interface must remain responsive + while some heavy operation is taking place. The \l + network/blockingfortuneclient example shows the same principle at + work in a TCP client. + + The Mandelbrot application supports zooming and scrolling using + the mouse or the keyboard. To avoid freezing the main thread's + event loop (and, as a consequence, the application's user + interface), we put all the fractal computation in a separate + worker thread. The thread emits a signal when it is done + rendering the fractal. + + During the time where the worker thread is recomputing the + fractal to reflect the new zoom factor position, the main thread + simply scales the previously rendered pixmap to provide immediate + feedback. The result doesn't look as good as what the worker + thread eventually ends up providing, but at least it makes the + application more responsive. The sequence of screenshots below + shows the original image, the scaled image, and the rerendered + image. + + \table + \row + \o \inlineimage mandelbrot_zoom1.png + \o \inlineimage mandelbrot_zoom2.png + \o \inlineimage mandelbrot_zoom3.png + \endtable + + Similarly, when the user scrolls, the previous pixmap is scrolled + immediately, revealing unpainted areas beyond the edge of the + pixmap, while the image is rendered by the worker thread. + + \table + \row + \o \inlineimage mandelbrot_scroll1.png + \o \inlineimage mandelbrot_scroll2.png + \o \inlineimage mandelbrot_scroll3.png + \endtable + + The application consists of two classes: + + \list + \o \c RenderThread is a QThread subclass that renders + the Mandelbrot set. + \o \c MandelbrotWidget is a QWidget subclass that shows the + Mandelbrot set on screen and lets the user zoom and scroll. + \endlist + + If you are not already familiar with Qt's thread support, we + recommend that you start by reading the \l{Thread Support in Qt} + overview. + + \section1 RenderThread Class Definition + + We'll start with the definition of the \c RenderThread class: + + \snippet examples/threads/mandelbrot/renderthread.h 0 + + The class inherits QThread so that it gains the ability to run in + a separate thread. Apart from the constructor and destructor, \c + render() is the only public function. Whenever the thread is done + rendering an image, it emits the \c renderedImage() signal. + + The protected \c run() function is reimplemented from QThread. It + is automatically called when the thread is started. + + In the \c private section, we have a QMutex, a QWaitCondition, + and a few other data members. The mutex protects the other data + member. + + \section1 RenderThread Class Implementation + + \snippet examples/threads/mandelbrot/renderthread.cpp 0 + + In the constructor, we initialize the \c restart and \c abort + variables to \c false. These variables control the flow of the \c + run() function. + + We also initialize the \c colormap array, which contains a series + of RGB colors. + + \snippet examples/threads/mandelbrot/renderthread.cpp 1 + + The destructor can be called at any point while the thread is + active. We set \c abort to \c true to tell \c run() to stop + running as soon as possible. We also call + QWaitCondition::wakeOne() to wake up the thread if it's sleeping. + (As we will see when we review \c run(), the thread is put to + sleep when it has nothing to do.) + + The important thing to notice here is that \c run() is executed + in its own thread (the worker thread), whereas the \c + RenderThread constructor and destructor (as well as the \c + render() function) are called by the thread that created the + worker thread. Therefore, we need a mutex to protect accesses to + the \c abort and \c condition variables, which might be accessed + at any time by \c run(). + + At the end of the destructor, we call QThread::wait() to wait + until \c run() has exited before the base class destructor is + invoked. + + \snippet examples/threads/mandelbrot/renderthread.cpp 2 + + The \c render() function is called by the \c MandelbrotWidget + whenever it needs to generate a new image of the Mandelbrot set. + The \c centerX, \c centerY, and \c scaleFactor parameters specify + the portion of the fractal to render; \c resultSize specifies the + size of the resulting QImage. + + The function stores the parameters in member variables. If the + thread isn't already running, it starts it; otherwise, it sets \c + restart to \c true (telling \c run() to stop any unfinished + computation and start again with the new parameters) and wakes up + the thread, which might be sleeping. + + \snippet examples/threads/mandelbrot/renderthread.cpp 3 + + \c run() is quite a big function, so we'll break it down into + parts. + + The function body is an infinite loop which starts by storing the + rendering parameters in local variables. As usual, we protect + accesses to the member variables using the class's mutex. Storing + the member variables in local variables allows us to minimize the + amout of code that needs to be protected by a mutex. This ensures + that the main thread will never have to block for too long when + it needs to access \c{RenderThread}'s member variables (e.g., in + \c render()). + + The \c forever keyword is, like \c foreach, a Qt pseudo-keyword. + + \snippet examples/threads/mandelbrot/renderthread.cpp 4 + \snippet examples/threads/mandelbrot/renderthread.cpp 5 + \snippet examples/threads/mandelbrot/renderthread.cpp 6 + \snippet examples/threads/mandelbrot/renderthread.cpp 7 + + Then comes the core of the algorithm. Instead of trying to create + a perfect Mandelbrot set image, we do multiple passes and + generate more and more precise (and computationally expensive) + approximations of the fractal. + + If we discover inside the loop that \c restart has been set to \c + true (by \c render()), we break out of the loop immediately, so + that the control quickly returns to the very top of the outer + loop (the \c forever loop) and we fetch the new rendering + parameters. Similarly, if we discover that \c abort has been set + to \c true (by the \c RenderThread destructor), we return from + the function immediately, terminating the thread. + + The core algorithm is beyond the scope of this tutorial. + + \snippet examples/threads/mandelbrot/renderthread.cpp 8 + \snippet examples/threads/mandelbrot/renderthread.cpp 9 + + Once we're done with all the iterations, we call + QWaitCondition::wait() to put the thread to sleep by calling, + unless \c restart is \c true. There's no use in keeping a worker + thread looping indefinitely while there's nothing to do. + + \snippet examples/threads/mandelbrot/renderthread.cpp 10 + + The \c rgbFromWaveLength() function is a helper function that + converts a wave length to a RGB value compatible with 32-bit + \l{QImage}s. It is called from the constructor to initialize the + \c colormap array with pleasing colors. + + \section1 MandelbrotWidget Class Defintion + + The \c MandelbrotWidget class uses \c RenderThread to draw the + Mandelbrot set on screen. Here's the class definition: + + \snippet examples/threads/mandelbrot/mandelbrotwidget.h 0 + + The widget reimplements many event handlers from QWidget. In + addition, it has an \c updatePixmap() slot that we'll connect to + the worker thread's \c renderedImage() signal to update the + display whenever we receive new data from the thread. + + Among the private variables, we have \c thread of type \c + RenderThread and \c pixmap, which contains the last rendered + image. + + \section1 MandelbrotWidget Class Implementation + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 0 + + The implementation starts with a few contants that we'll need + later on. + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 1 + + The interesting part of the constructor is the + qRegisterMetaType() and QObject::connect() calls. Let's start + with the \l{QObject::connect()}{connect()} call. + + Although it looks like a standard signal-slot connection between + two \l{QObject}s, because the signal is emitted in a different + thread than the receiver lives in, the connection is effectively a + \l{Qt::QueuedConnection}{queued connection}. These connections are + asynchronous (i.e., non-blocking), meaning that the slot will be + called at some point after the \c emit statement. What's more, the + slot will be invoked in the thread in which the receiver lives. + Here, the signal is emitted in the worker thread, and the slot is + executed in the GUI thread when control returns to the event loop. + + With queued connections, Qt must store a copy of the arguments + that were passed to the signal so that it can pass them to the + slot later on. Qt knows how to take of copy of many C++ and Qt + types, but QImage isn't one of them. We must therefore call the + template function qRegisterMetaType() before we can use QImage + as parameter in queued connections. + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 2 + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 3 + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 4 + + In \l{QWidget::paintEvent()}{paintEvent()}, we start by filling + the background with black. If we have nothing yet to paint (\c + pixmap is null), we print a message on the widget asking the user + to be patient and return from the function immediately. + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 5 + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 6 + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 7 + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 8 + + If the pixmap has the right scale factor, we draw the pixmap directly onto + the widget. Otherwise, we scale and translate the \l{The Coordinate + System}{coordinate system} before we draw the pixmap. By reverse mapping + the widget's rectangle using the scaled painter matrix, we also make sure + that only the exposed areas of the pixmap are drawn. The calls to + QPainter::save() and QPainter::restore() make sure that any painting + performed afterwards uses the standard coordinate system. + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 9 + + At the end of the paint event handler, we draw a text string and + a semi-transparent rectangle on top of the fractal. + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 10 + + Whenever the user resizes the widget, we call \c render() to + start generating a new image, with the same \c centerX, \c + centerY, and \c curScale parameters but with the new widget size. + + Notice that we rely on \c resizeEvent() being automatically + called by Qt when the widget is shown the first time to generate + the image the very first time. + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 11 + + The key press event handler provides a few keyboard bindings for + the benefit of users who don't have a mouse. The \c zoom() and \c + scroll() functions will be covered later. + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 12 + + The wheel event handler is reimplemented to make the mouse wheel + control the zoom level. QWheelEvent::delta() returns the angle of + the wheel mouse movement, in eights of a degree. For most mice, + one wheel step corresponds to 15 degrees. We find out how many + mouse steps we have and determine the zoom factor in consequence. + For example, if we have two wheel steps in the positive direction + (i.e., +30 degrees), the zoom factor becomes \c ZoomInFactor + to the second power, i.e. 0.8 * 0.8 = 0.64. + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 13 + + When the user presses the left mouse button, we store the mouse + pointer position in \c lastDragPos. + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 14 + + When the user moves the mouse pointer while the left mouse button + is pressed, we adjust \c pixmapOffset to paint the pixmap at a + shifted position and call QWidget::update() to force a repaint. + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 15 + + When the left mouse button is released, we update \c pixmapOffset + just like we did on a mouse move and we reset \c lastDragPos to a + default value. Then, we call \c scroll() to render a new image + for the new position. (Adjusting \c pixmapOffset isn't sufficient + because areas revealed when dragging the pixmap are drawn in + black.) + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 16 + + The \c updatePixmap() slot is invoked when the worker thread has + finished rendering an image. We start by checking whether a drag + is in effect and do nothing in that case. In the normal case, we + store the image in \c pixmap and reinitialize some of the other + members. At the end, we call QWidget::update() to refresh the + display. + + At this point, you might wonder why we use a QImage for the + parameter and a QPixmap for the data member. Why not stick to one + type? The reason is that QImage is the only class that supports + direct pixel manipulation, which we need in the worker thread. On + the other hand, before an image can be drawn on screen, it must + be converted into a pixmap. It's better to do the conversion once + and for all here, rather than in \c paintEvent(). + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 17 + + In \c zoom(), we recompute \c curScale. Then we call + QWidget::update() to draw a scaled pixmap, and we ask the worker + thread to render a new image corresponding to the new \c curScale + value. + + \snippet examples/threads/mandelbrot/mandelbrotwidget.cpp 18 + + \c scroll() is similar to \c zoom(), except that the affected + parameters are \c centerX and \c centerY. + + \section1 The main() Function + + The application's multithreaded nature has no impact on its \c + main() function, which is as simple as usual: + + \snippet examples/threads/mandelbrot/main.cpp 0 +*/ diff --git a/doc/src/examples/masterdetail.qdoc b/doc/src/examples/masterdetail.qdoc new file mode 100644 index 0000000..d7dc0e2 --- /dev/null +++ b/doc/src/examples/masterdetail.qdoc @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example sql/masterdetail + \title Master Detail Example + + The Master Detail Example shows how to present data from different + data sources in the same application. The album titles, and the + corresponding artists and release dates, are kept in a + database, while each album's tracks are stored in an XML + file. + + The example also shows how to add as well as remove data from both + the database and the associated XML file using the API provided by + the QtSql and QtXml modules, respectively. + + \image masterdetail-example.png +*/ diff --git a/doc/src/examples/mdi.qdoc b/doc/src/examples/mdi.qdoc new file mode 100644 index 0000000..f97db5e --- /dev/null +++ b/doc/src/examples/mdi.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example mainwindows/mdi + \title MDI Example + + The MDI example shows how to implement a Multiple Document Interface using Qt's + QMdiArea class. + + \image mdi-example.png + +*/ diff --git a/doc/src/examples/menus.qdoc b/doc/src/examples/menus.qdoc new file mode 100644 index 0000000..0500101 --- /dev/null +++ b/doc/src/examples/menus.qdoc @@ -0,0 +1,232 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example mainwindows/menus + \title Menus Example + + The Menus example demonstrates how menus can be used in a main + window application. + + A menu widget can be either a pull-down menu in a menu bar or a + standalone context menu. Pull-down menus are shown by the menu bar + when the user clicks on the respective item or presses the + specified shortcut key. Context menus are usually invoked by some + special keyboard key or by right-clicking. + + \image menus-example.png + + A menu consists of a list of \e action items. In applications, + many common commands can be invoked via menus, toolbar buttons as + well as keyboard shortcuts. Since the user expects the commands to + be performed in the same way, regardless of the user interface + used, it is useful to represent each command as an action. + + The Menus example consists of one single class, \c MainWindow, derived + from the QMainWindow class. When choosing one of the + action items in our application, it will display the item's path + in its central widget. + + \section1 MainWindow Class Definition + + QMainWindow provides a main application window, with a menu bar, + tool bars, dock widgets and a status bar around a large central + widget. + + \snippet examples/mainwindows/menus/mainwindow.h 0 + + In this example, we will see how to implement pull-down menus as + well as a context menu. In order to implement a custom context + menu we must reimplement QWidget's \l + {QWidget::}{contextMenuEvent()} function to receive the context + menu events for our main window. + + \snippet examples/mainwindows/menus/mainwindow.h 1 + + We must also implement a collection of private slots to respond to + the user activating any of our menu entries. Note that these + slots are left out of this documentation since they are trivial, + i.e., most of them are only displaying the action's path in the + main window's central widget. + + \snippet examples/mainwindows/menus/mainwindow.h 2 + + We have chosen to simplify the constructor by implementing two + private convenience functions to create the various actions, to + add them to menus and to insert the menus into our main window's + menu bar. + + \snippet examples/mainwindows/menus/mainwindow.h 3 + + Finally, we declare the various menus and actions as well as a + simple information label in the application wide scope. + + The QMenu class provides a menu widget for use in menu bars, + context menus, and other popup menus while the QAction class + provides an abstract user interface action that can be inserted + into widgets. + + In some situations it is useful to group actions together, e.g., + we have a \gui {Left Align} action, a \gui {Right Align} action, a + \gui {Justify} action, and a \gui {Center} action, and we want + only one of these actions to be active at any one time. One simple + way of achieving this is to group the actions together in an + action group using the QActionGroup class. + + \section1 MainWindow Class Implementation + + In the constructor, we start off by creating a regular QWidget and + make it our main window's central widget. Note that the main + window takes ownership of the widget pointer and deletes it at the + appropriate time. + + \snippet examples/mainwindows/menus/mainwindow.cpp 0 + \codeline + \snippet examples/mainwindows/menus/mainwindow.cpp 1 + + Then we create the information label as well as a top and bottom + filler that we add to a layout which we install on the central + widget. QMainWindow objects come with their own customized layout + and setting a layout on a the actual main window, or creating a + layout with a main window as a parent, is considered an error. You + should always set your own layout on the central widget instead. + + \snippet examples/mainwindows/menus/mainwindow.cpp 2 + + To create the actions and menus we call our two convenience + functions: \c createActions() and \c createMenus(). We will get + back to these shortly. + + QMainWindow's \l {QMainWindow::statusBar()}{statusBar()} function + returns the status bar for the main window (if the status bar does + not exist, this function will create and return an empty status + bar). We initialize the status bar and window title, resize the + window to an appropriate size as well as ensure that the main + window cannot be resized to a smaller size than the given + one. + + Now, let's take a closer look at the \c createActions() convenience + function that creates the various actions: + + \snippet examples/mainwindows/menus/mainwindow.cpp 4 + \dots + + A QAction object may contain an icon, a text, a shortcut, a status + tip, a "What's This?" text, and a tooltip. Most of these can be + set in the constructor, but they can also be set independently + using the provided convenience functions. + + In the \c createActions() function, we first create a \c newAct + action. We make \gui Ctrl+N its shortcut using the + QAction::setShortcut() function, and we set its status tip using the + QAction::setStatusTip() function (the status tip is displayed on all + status bars provided by the action's top-level parent widget). We + also connect its \l {QAction::}{triggered()} signal to the \c + newFile() slot. + + The rest of the actions are created in a similar manner. Please + see the source code for details. + + \snippet examples/mainwindows/menus/mainwindow.cpp 7 + + + Once we have created the \gui {Left Align}, \gui {Right Align}, + \gui {Justify}, and a \gui {Center} actions, we can also create + the previously mentioned action group. + + Each action is added to the group using QActionGroup's \l + {QActionGroup::}{addAction()} function. Note that an action also + can be added to a group by creating it with the group as its + parent. Since an action group is exclusive by default, only one of + the actions in the group is checked at any one time (this can be + altered using the QActionGroup::setExclusive() function). + + When all the actions are created, we use the \c createMenus() + function to add the actions to the menus and to insert the menus + into the menu bar: + + \snippet examples/mainwindows/menus/mainwindow.cpp 8 + + QMenuBar's \l {QMenuBar::addMenu()}{addMenu()} function appends a + new QMenu with the given title, to the menu bar (note that the + menu bar takes ownership of the menu). We use QWidget's \l + {QWidget::addAction()}{addAction()} function to add each action to + the corresponding menu. + + Alternatively, the QMenu class provides several \l + {QMenu::addAction()}{addAction()} convenience functions that create + and add new actions from given texts and/or icons. You can also + provide a member that will automatically connect to the new + action's \l {QAction::triggered()}{triggered()} signal, and a + shortcut represented by a QKeySequence instance. + + The QMenu::addSeparator() function creates and returns a new + separator action, i.e. an action for which QAction::isSeparator() + returns true, and adds the new action to the menu's list of + actions. + + \snippet examples/mainwindows/menus/mainwindow.cpp 12 + + Note the \gui Format menu. First of all, it is added as a submenu + to the \gui Edit Menu using QMenu's \l + {QMenu::addMenu()}{addMenu()} function. Secondly, take a look at the + alignment actions: In the \c createActions() function we added the + \c leftAlignAct, \c rightAlignAct, \c justifyAct and \c centerAct + actions to an action group. Nevertheless, we must add each action + to the menu separately while the action group does its magic + behind the scene. + + \snippet examples/mainwindows/menus/mainwindow.cpp 3 + + To provide a custom context menu, we must reimplement QWidget's \l + {QWidget::}{contextMenuEvent()} function to receive the widget's + context menu events (note that the default implementation simply + ignores these events). + + Whenever we receive such an event, we create a menu containing the + \gui Cut, \gui Copy and \gui Paste actions. Context menus can be + executed either asynchronously using the \l {QMenu::}{popup()} + function or synchronously using the \l {QMenu::}{exec()} + function. In this example, we have chosen to show the menu using + its \l {QMenu::}{exec()} function. By passing the event's position + as argument we ensure that the context menu appears at the + expected position. +*/ diff --git a/doc/src/examples/mousecalibration.qdoc b/doc/src/examples/mousecalibration.qdoc new file mode 100644 index 0000000..e271265 --- /dev/null +++ b/doc/src/examples/mousecalibration.qdoc @@ -0,0 +1,207 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example qws/mousecalibration + \title Mouse Calibration Example + + The Mouse Calibration example demonstrates how to write a simple + program using the mechanisms provided by the QWSMouseHandler class + to calibrate the mouse handler in \l{Qt for Embedded Linux}. + + Calibration is the process of mapping between physical + (i.e. device) coordinates and logical coordinates. + + The example consists of two classes in addition to the main program: + + \list + \o \c Calibration is a dialog widget that retrieves the device coordinates. + \o \c ScribbleWidget is a minimal drawing program used to let the user + test the new mouse settings. + \endlist + + First we will review the main program, then we will take a look at + the \c Calibration class. The \c ScribbleWidget class is only a + help tool in this context, and will not be covered here. + + \section1 The Main Program + + The program starts by presenting a message box informing the user + of what is going to happen: + + \snippet examples/qws/mousecalibration/main.cpp 0 + + The QMessageBox class provides a modal dialog with a range of + different messages, roughly arranged along two axes: severity and + complexity. The message box has a different icon for each of the + severity levels, but the icon must be specified explicitly. In our + case we use the default QMessageBox::NoIcon value. In addition we + use the default complexity, i.e. a message box showing the given + text and an \gui OK button. + + At this stage in the program, the mouse could be completely + uncalibrated, making the user unable to press the \gui OK button. For + that reason we use the static QTimer::singleShot() function to + make the message box disappear after 10 seconds. The QTimer class + provides repetitive and single-shot timers: The single shot + function calls the given slot after the specified interval. + + \snippet examples/qws/mousecalibration/main.cpp 1 + + Next, we create an instance of the \c Calibration class which is a + dialog widget retrieving the required sample coordinates: The + dialog sequentially presents five marks for the user to press, + storing the device coordinates for the mouse press events. + + \snippet examples/qws/mousecalibration/main.cpp 2 + + When the calibration dialog returns, we let the user test the new + mouse settings by drawing onto a \c ScribbleWidget object. Since + the mouse still can be uncalibrated, we continue to use the + QMessageBox and QTimer classes to inform the user about the + program's progress. + + An improved calibration tool would let the user choose between + accepting the new calibration, reverting to the old one, and + restarting the calibration. + + \section1 Calibration Class Definition + + The \c Calibration class inherits from QDialog and is responsible + for retrieving the device coordinates from the user. + + \snippet examples/qws/mousecalibration/calibration.h 0 + + We reimplement QDialog's \l {QDialog::exec()}{exec()} and \l + {QDialog::accept()}{accept()} slots, and QWidget's \l + {QWidget::paintEvent()}{paintEvent()} and \l + {QWidget::mouseReleaseEvent()}{mouseReleaseEvent()} functions. + + In addition, we declare a couple of private variables, \c data and + \c pressCount, holding the \c Calibration object's number of mouse + press events and current calibration data. The \c pressCount + variable is a convenience variable, while the \c data is a + QWSPointerCalibrationData object (storing the physical and logical + coordinates) that is passed to the mouse handler. The + QWSPointerCalibrationData class is simply a container for + calibration data. + + \section1 Calibration Class Implementation + + In the constructor we first ensure that the \c Calibration dialog + fills up the entire screen, has focus and will receive mouse + events (the latter by making the dialog modal): + + \snippet examples/qws/mousecalibration/calibration.cpp 0 + + Then we initialize the \l{QWSPointerCalibrationData::}{screenPoints} + array: + + \snippet examples/qws/mousecalibration/calibration.cpp 1 + + In order to specify the calibration, the + \l{QWSPointerCalibrationData::screenPoints}{screenPoints} array must + contain the screen coordinates for the logical positions + represented by the QWSPointerCalibrationData::Location enum + (e.g. QWSPointerCalibrationData::TopLeft). Since non-linearity is + expected to increase on the edge of the screen, all points are + kept 10 percent within the screen. The \c qt_screen pointer is a + reference to the screen device. There can only be one screen + device per application. + + \snippet examples/qws/mousecalibration/calibration.cpp 2 + + Finally, we initialize the variable which keeps track of the number of + mouse press events we have received. + + \snippet examples/qws/mousecalibration/calibration.cpp 3 + + The destructor is trivial. + + \snippet examples/qws/mousecalibration/calibration.cpp 4 + + The reimplementation of the QDialog::exec() slot is called from + the main program. + + First we clear the current calibration making the following mouse + event delivered in raw device coordinates. Then we call the + QWidget::grabMouse() function to make sure no mouse events are + lost, and the QWidget::activateWindow() function to make the + top-level widget containing this dialog, the active window. When + the call to the QDialog::exec() base function returns, we call + QWidget::releaseMouse() to release the mouse grab before the + function returns. + + \snippet examples/qws/mousecalibration/calibration.cpp 5 + + The QWidget::paintEvent() function is reimplemented to receive the + widget's paint events. A paint event is a request to repaint all + or parts of the widget. It can happen as a result of + QWidget::repaint() or QWidget::update(), or because the widget was + obscured and has now been uncovered, or for many other reasons. + In our reimplementation of the function we simply draw a cross at + the next point the user should press. + + \snippet examples/qws/mousecalibration/calibration.cpp 6 + + We then reimplement the QWidget::mouseReleaseEvent() function to + receive the widget's move events, using the QMouseEvent object + passed as parameter to find the coordinates the user pressed, and + update the QWSPointerCalibrationData::devPoints array. + + In order to complete the mapping between logical and physical + coordinates, the \l + {QWSPointerCalibrationData::devPoints}{devPoints} array must + contain the raw device coordinates for the logical positions + represented by the QWSPointerCalibrationData::Location enum + (e.g. QWSPointerCalibrationData::TopLeft) + + We continue by drawing the next cross, or close the dialog by + calling the QDialog::accept() slot if we have collected all the + required coordinate samples. + + \snippet examples/qws/mousecalibration/calibration.cpp 7 + + Our reimplementation of the QDialog::accept() slot simply activate + the new calibration data using the QWSMouseHandler::calibrate() + function. We also use the Q_ASSERT() macro to ensure that the number + of required samples are present. +*/ diff --git a/doc/src/examples/movie.qdoc b/doc/src/examples/movie.qdoc new file mode 100644 index 0000000..00e42c6 --- /dev/null +++ b/doc/src/examples/movie.qdoc @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/movie + \title Movie Example + + The Movie example demonstrates how to use QMovie and QLabel to + display animations. Now that Qt comes with \l{Phonon + Overview}{Phonon} (the multimedia framework), QMovie is mostly + useful if one wants to play a simple animation without the added + complexity of a multimedia framework to install and deploy. + + \image movie-example.png +*/ diff --git a/doc/src/examples/multipleinheritance.qdoc b/doc/src/examples/multipleinheritance.qdoc new file mode 100644 index 0000000..ff2f00f --- /dev/null +++ b/doc/src/examples/multipleinheritance.qdoc @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example uitools/multipleinheritance + \title Multiple Inheritance Example + + The Multiple Inheritance Example shows how to use a form created with \QD + in an application by subclassing both QWidget and the user interface + class, which is \c{Ui::CalculatorForm}. + + \image multipleinheritance-example.png + + To subclass the \c calculatorform.ui file and ensure that \c qmake + processes it with the \c uic, we have to include \c calculatorform.ui + in the \c .pro file, as shown below: + + \snippet examples/uitools/multipleinheritance/multipleinheritance.pro 0 + + When the project is compiled, the \c uic will generate a corresponding + \c ui_calculatorform.h. + + \section1 CalculatorForm Definition + + In the \c CalculatorForm definition, we include the \c ui_calculatorform.h + that was generated earlier. + + \snippet examples/uitools/multipleinheritance/calculatorform.h 0 + + As mentioned earlier, the class is a subclass of both QWidget and + \c{Ui::CalculatorForm}. + + \snippet examples/uitools/multipleinheritance/calculatorform.h 1 + + Two slots are defined according to the \l{Automatic Connections} + {automatic connection} naming convention required by \c uic. This is + to ensure that \l{QMetaObject}'s auto-connection facilities connect + all the signals and slots involved automatically. + + \section1 CalculatorForm Implementation + + In the constructor, we call \c setupUi() to load the user interface file. + Note that we do not need the \c{ui} prefix as \c CalculatorForm is a + subclass of the user interface class. + + \snippet examples/uitools/multipleinheritance/calculatorform.cpp 0 + + We include two slots, \c{on_inputSpinBox1_valueChanged()} and + \c{on_inputSpinBox2_valueChanged()}. These slots respond to the + \l{QSpinBox::valueChanged()}{valueChanged()} signal that both spin boxes + emit. Whenever there is a change in one spin box's value, we take that + value and add it to whatever value the other spin box has. + + \snippet examples/uitools/multipleinheritance/calculatorform.cpp 1 + \codeline + \snippet examples/uitools/multipleinheritance/calculatorform.cpp 2 + + \section1 \c main() Function + + The \c main() function instantiates QApplication and \c CalculatorForm. + The \c calculator object is displayed by invoking the \l{QWidget::show()} + {show()} function. + + \snippet examples/uitools/multipleinheritance/main.cpp 0 + + There are various approaches to include forms into applications. The + Multiple Inheritance approach is just one of them. See + \l{Using a Designer .ui File in Your Application} for more information on + the other approaches available. +*/ diff --git a/doc/src/examples/musicplayerexample.qdoc b/doc/src/examples/musicplayerexample.qdoc new file mode 100644 index 0000000..d23c1f1 --- /dev/null +++ b/doc/src/examples/musicplayerexample.qdoc @@ -0,0 +1,248 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example phonon/musicplayer + \title Music Player Example + + The Music Player Example shows how to use Phonon - the multimedia + framework that comes with Qt - to create a simple music player. + The player can play music files, and provides simple playback + control, such as pausing, stopping, and resuming the music. + + \image musicplayer.png + + The player has a button group with the play, pause, and stop + buttons familiar from most music players. The top-most slider + controls the position in the media stream, and the bottom slider + allows adjusting the sound volume. + + The user can use a file dialog to add music files to a table, + which displays meta information about the music - such as the + title, album, and artist. Each row contains information about a + single music file; to play it, the user selects that row and + presses the play button. Also, when a row is selected, the files + in the table are queued for playback. + + Phonon offers playback of sound using an available audio device, + e.g., a sound card or an USB headset. For the implementation, we + use two objects: a \l{Phonon::}{MediaObject}, which controls the + playback, and an \l{Phonon::}{AudioOutput}, which can output the + audio to a sound device. We will explain how they cooperate when + we encounter them in the code. For a high-level introduction to + Phonon, see its \l{Phonon Overview}{overview}. + + The API of Phonon is implemented through an intermediate + technology on each supported platform: DirectShow, QuickTime, and + GStreamer. The sound formats supported may therefore vary from + system to system. We do not in this example try to determine which + formats are supported, but let Phonon report an error if the user + tries to play an unsupported sound file. + + Our player consists of one class, \c MainWindow, which both + constructs the GUI and handles the playback. We will now go + through the parts of its definition and implementation that + concerns Phonon. + + \section1 MainWindow Class Definition + + Most of the API in \c MainWindow is private, as is often the case + for classes that represent self-contained windows. We list Phonon + objects and slots we connect to their signals; we take a closer + look at them when we walk through the \c MainWindow + implementation. + + \snippet examples/phonon/musicplayer/mainwindow.h 2 + + We use the \l{Phonon::}{SeekSlider} to move the current playback + position in the media stream, and the \l{Phonon::}{VolumeSlider} + controls the sound volume. Both of these widgets come ready made + with Phonon. We use another \l{Phonon::}{MediaObject}, + metaInformationProvider, to get the meta information from the + music files. More on this later. + + \snippet examples/phonon/musicplayer/mainwindow.h 1 + + The \l{Phonon::}{MediaObject} informs us of the state of the playback and + properties of the media it is playing back through a series of + signals. We connect the signals we need to slots in \c MainWindow. + The \c tableClicked() slot is connected to the table, so that we + know when the user requests playback of a new music file, by + clicking on the table. + + \section1 MainWindow Class Implementation + + The \c MainWindow class handles both the user interface and + Phonon. We will now take a look at the code relevant for Phonon. + The code required for setting up the GUI is explained elsewhere. + + We start with the constructor: + + \snippet examples/phonon/musicplayer/mainwindow.cpp 0 + + We start by instantiating our media and audio output objects. + As mentioned, the media object knows how to playback + multimedia (in our case sound files) while the audio output + can send it to a sound device. + + For the playback to work, the media and audio output objects need + to get in contact with each other, so that the media object can + send the sound to the audio output. Phonon is a graph based + framework, i.e., its objects are nodes that can be connected by + paths. Objects are connected using the \c createPath() function, + which is part of the Phonon namespace. + + \snippet examples/phonon/musicplayer/mainwindow.cpp 1 + + We also connect signals of the media object to slots in our \c + MainWindow. We will examine them shortly. + + \snippet examples/phonon/musicplayer/mainwindow.cpp 2 + + Finally, we call private helper functions to set up the GUI. + The \c setupUi() function contains code for setting up the seek + , and volume slider. We move on to \c setupUi(): + + \snippet examples/phonon/musicplayer/mainwindow.cpp 3 + \dots + \snippet examples/phonon/musicplayer/mainwindow.cpp 4 + + After creating the widgets, they must be supplied with the + \l{Phonon::}{MediaObject} and \l{Phonon::}{AudioOutput} objects + they should control. + + In the \c setupActions(), we connect the actions for the play, + pause, and stop tool buttons, to slots of the media object. + + \snippet examples/phonon/musicplayer/mainwindow.cpp 5 + + We move on to the the slots of \c MainWindow, starting with \c + addFiles(): + + \snippet examples/phonon/musicplayer/mainwindow.cpp 6 + + In the \c addFiles() slot, we add files selected by the user to + the \c sources list. We then set the first source selected on the + \c metaInformationProvider \l{Phonon::}{MediaObject}, which will + send a state changed signal when the meta information is resolved; + we have this signal connected to the \c metaStateChanged() slot. + + The media object informs us of state changes by sending the \c + stateChanged() signal. The \c stateChanged() slot is connected + to this signal. + + \snippet examples/phonon/musicplayer/mainwindow.cpp 9 + + The \l{Phonon::MediaObject::}{errorString()} function gives a + description of the error that is suitable for users of a Phonon + application. The two values of the \l{Phonon::}{ErrorState} enum + helps us determine whether it is possible to try to play the same + file again. + + \snippet examples/phonon/musicplayer/mainwindow.cpp 10 + + We update the GUI when the playback state changes, i.e., when it + starts, pauses, stops, or resumes. + + The media object will report other state changes, as defined by the + \l{Phonon::}{State} enum. + + The \c tick() slot is connected to a \l{Phonon::}{MediaObject} signal which is + emitted when the playback position changes: + + \snippet examples/phonon/musicplayer/mainwindow.cpp 11 + + The \c time is given in milliseconds. + + When the table is clicked on with the mouse, \c tableClick() + is invoked: + + \snippet examples/phonon/musicplayer/mainwindow.cpp 12 + + Since we stop the media object, we first check whether it is + currently playing. \c row contains the row in the table that was + clicked upon; the indices of \c sources follows the table, so we + can simply use \c row to find the new source. + + \snippet examples/phonon/musicplayer/mainwindow.cpp 13 + + When the media source changes, we simply need to select the + corresponding row in the table. + + \snippet examples/phonon/musicplayer/mainwindow.cpp 14 + + When \c metaStateChanged() is invoked, \c + metaInformationProvider has resolved the meta data for its current + source. A \l{Phonon::}{MediaObject} will do this before + entering \l{Phonon::}{StoppedState}. Note that we could also + have used the \l{Phonon::MediaObject::}{metaDataChanged()} signal for + this purpose. + + Some of the meta data is then chosen to be displayed in the + music table. A file might not contain the meta data requested, + in which case an empty string is returned. + + \snippet examples/phonon/musicplayer/mainwindow.cpp 15 + + If we have media sources in \c sources of which meta information + is not resolved, we set a new source on the \c + metaInformationProvider, which will invoke \c metaStateChanged() + again. + + We move on to the \c aboutToFinish() slot: + + \snippet examples/phonon/musicplayer/mainwindow.cpp 16 + + When a file is finished playing, the Music Player will move on and + play the next file in the table. This slot is connected to the + \l{Phonon::}{MediaObject}'s + \l{Phonon::MediaObject::}{aboutToFinish()} signal, which is + guaranteed to be emitted while there is still time to enqueue + another file for playback. + + \section1 The main() function. + + Phonon requires that the application has a name; it is set with + \l{QCoreApplication::}{setApplicationName()}. This is because + D-Bus, which is used by Phonon on Linux systems, demands this. + + \snippet examples/phonon/musicplayer/main.cpp 1 +*/ diff --git a/doc/src/examples/network-chat.qdoc b/doc/src/examples/network-chat.qdoc new file mode 100644 index 0000000..3caeb9a --- /dev/null +++ b/doc/src/examples/network-chat.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example network/network-chat + \title Network Chat Example + + The Network Chat example demonstrates a stateful peer-to-peer Chat client + that uses broadcasting with QUdpSocket and QNetworkInterface to discover + its peers. + + \image network-chat-example.png +*/ diff --git a/doc/src/examples/orderform.qdoc b/doc/src/examples/orderform.qdoc new file mode 100644 index 0000000..f6f2607 --- /dev/null +++ b/doc/src/examples/orderform.qdoc @@ -0,0 +1,378 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example richtext/orderform + \title Order Form Example + + The Order Form example shows how to generate rich text documents by + combining a simple template with data input by the user in a dialog. Data + is extracted from a \c DetailsDialog object and displayed on a QTextEdit + with a QTextCursor, using various formats. Each form generated is added + to a QTabWidget for easy access. + + \image orderform-example.png + + \section1 DetailsDialog Definition + + The \c DetailsDialog class is a subclass of QDialog, implementing a slot + \c verify() to allow contents of the \c DetailsDialog to be verified later. + This is further explained in \c DetailsDialog Implementation. + + \snippet examples/richtext/orderform/detailsdialog.h 0 + + The constructor of \c DetailsDialog accepts parameters \a title and + \a parent. The class defines four \e{getter} functions: \c orderItems(), + \c senderName(), \c senderAddress(), and \c sendOffers() to allow data + to be accessed externally. + + The class definition includes input widgets for the required + fields, \c nameEdit and \c addressEdit. Also, a QCheckBox and a + QDialogButtonBox are defined; the former to provide the user with the + option to receive information on products and offers, and the latter + to ensure that buttons used are arranged according to the user's native + platform. In addition, a QTableWidget, \c itemsTable, is used to hold + order details. + + The screenshot below shows the \c DetailsDialog we intend to create. + + \image orderform-example-detailsdialog.png + + \section1 DetailsDialog Implementation + + The constructor of \c DetailsDialog instantiates the earlier defined fields + and their respective labels. The label for \c offersCheckBox is set and the + \c setupItemsTable() function is invoked to setup and populate + \c itemsTable. The QDialogButtonBox object, \c buttonBox, is instantiated + with \gui OK and \gui Cancel buttons. This \c buttonBox's \c accepted() and + \c rejected() signals are connected to the \c verify() and \c reject() + slots in \c DetailsDialog. + + \snippet examples/richtext/orderform/detailsdialog.cpp 0 + + A QGridLayout is used to place all the objects on the \c DetailsDialog. + + \snippet examples/richtext/orderform/detailsdialog.cpp 1 + + The \c setupItemsTable() function instantiates the QTableWidget object, + \c itemsTable, and sets the number of rows based on the QStringList + object, \c items, which holds the type of items ordered. The number of + columns is set to 2, providing a "name" and "quantity" layout. A \c for + loop is used to populate the \c itemsTable and the \c name item's flag + is set to Qt::ItemIsEnabled or Qt::ItemIsSelectable. For demonstration + purposes, the \c quantity item is set to a 1 and all items in the + \c itemsTable have this value for quantity; but this can be modified by + editing the contents of the cells at run time. + + \snippet examples/richtext/orderform/detailsdialog.cpp 2 + + The \c orderItems() function extracts data from the \c itemsTable and + returns it in the form of a QList<QPair<QString,int>> where each QPair + corresponds to an item and the quantity ordered. + + \snippet examples/richtext/orderform/detailsdialog.cpp 3 + + The \c senderName() function is used to return the value of the QLineEdit + used to store the name field for the order form. + + \snippet examples/richtext/orderform/detailsdialog.cpp 4 + + The \c senderAddress() function is used to return the value of the + QTextEdit containing the address for the order form. + + \snippet examples/richtext/orderform/detailsdialog.cpp 5 + + The \c sendOffers() function is used to return a \c true or \c false + value that is used to determine if the customer in the order form + wishes to receive more information on the company's offers and promotions. + + \snippet examples/richtext/orderform/detailsdialog.cpp 6 + + The \c verify() function is an additionally implemented slot used to + verify the details entered by the user into the \c DetailsDialog. If + the details entered are incomplete, a QMessageBox is displayed + providing the user the option to discard the \c DetailsDialog. Otherwise, + the details are accepted and the \c accept() function is invoked. + + \snippet examples/richtext/orderform/detailsdialog.cpp 7 + + \section1 MainWindow Definition + + The \c MainWindow class is a subclass of QMainWindow, implementing two + slots - \c openDialog() and \c printFile(). It also contains a private + instance of QTabWidget, \c letters. + + \snippet examples/richtext/orderform/mainwindow.h 0 + + \section1 MainWindow Implementation + + The \c MainWindow constructor sets up the \c fileMenu and the required + actions, \c newAction and \c printAction. These actions' \c triggered() + signals are connected to the additionally implemented openDialog() slot + and the default close() slot. The QTabWidget, \c letters, is + instantiated and set as the window's central widget. + + \snippet examples/richtext/orderform/mainwindow.cpp 0 + + The \c createLetter() function creates a new QTabWidget with a QTextEdit, + \c editor, as the parent. This function accepts four parameters that + correspond to we obtained through \c DetailsDialog, in order to "fill" + the \c editor. + + \snippet examples/richtext/orderform/mainwindow.cpp 1 + + We then obtain the cursor for the \c editor using QTextEdit::textCursor(). + The \c cursor is then moved to the start of the document using + QTextCursor::Start. + + \snippet examples/richtext/orderform/mainwindow.cpp 2 + + Recall the structure of a \l{Rich Text Document Structure} + {Rich Text Document}, where sequences of frames and + tables are always separated by text blocks, some of which may contain no + information. + + In the case of the Order Form Example, the document structure for this portion + is described by the table below: + + \table + \row + \o {1, 8} frame with \e{referenceFrameFormat} + \row + \o block \o \c{A company} + \row + \o block + \row + \o block \o \c{321 City Street} + \row + \o block + \row + \o block \o \c{Industry Park} + \row + \o block + \row + \o block \o \c{Another country} + \endtable + + This is accomplished with the following code: + + \snippet examples/richtext/orderform/mainwindow.cpp 3 + + Note that \c topFrame is the \c {editor}'s top-level frame and is not shown + in the document structure. + + We then set the \c{cursor}'s position back to its last position in + \c topFrame and fill in the customer's name (provided by the constructor) + and address - using a \c foreach loop to traverse the QString, \c address. + + \snippet examples/richtext/orderform/mainwindow.cpp 4 + + The \c cursor is now back in \c topFrame and the document structure for + the above portion of code is: + + \table + \row + \o block \o \c{Donald} + \row + \o block \o \c{47338 Park Avenue} + \row + \o block \o \c{Big City} + \endtable + + For spacing purposes, we invoke \l{QTextCursor::insertBlock()} + {insertBlock()} twice. The \l{QDate::currentDate()}{currentDate()} is + obtained and displayed. We use \l{QTextFrameFormat::setWidth()} + {setWidth()} to increase the width of \c bodyFrameFormat and we insert + a new frame with that width. + + \snippet examples/richtext/orderform/mainwindow.cpp 5 + + The following code inserts standard text into the order form. + + \snippet examples/richtext/orderform/mainwindow.cpp 6 + \snippet examples/richtext/orderform/mainwindow.cpp 7 + + This part of the document structure now contains the date, a frame with + \c bodyFrameFormat, as well as the standard text. + + \table + \row + \o block + \row + \o block + \row + \o block \o \c{Date: 25 May 2007} + \row + \o block + \row + \o {1, 4} frame with \e{bodyFrameFormat} + \row + \o block \o \c{I would like to place an order for the following items:} + \row + \o block + \row + \o block + \endtable + + A QTextTableFormat object, \c orderTableFormat, is used to hold the type + of item and the quantity ordered. + + \snippet examples/richtext/orderform/mainwindow.cpp 8 + + We use \l{QTextTable::cellAt()}{cellAt()} to set the headers for the + \c orderTable. + + \snippet examples/richtext/orderform/mainwindow.cpp 9 + + Then, we iterate through the QList of QPair objects to populate + \c orderTable. + + \snippet examples/richtext/orderform/mainwindow.cpp 10 + + The resulting document structure for this section is: + + \table + \row + \o {1, 11} \c{orderTable} with \e{orderTableFormat} + \row + \o block \o \c{Product} + \row + \o block \o \c{Quantity} + \row + \o block \o \c{T-shirt} + \row + \o block \o \c{4} + \row + \o block \o \c{Badge} + \row + \o block \o \c{3} + \row + \o block \o \c{Reference book} + \row + \o block \o \c{2} + \row + \o block \o \c{Coffee cup} + \row + \o block \o \c{5} + \endtable + + The \c cursor is then moved back to \c{topFrame}'s + \l{QTextFrame::lastPosition()}{lastPosition()} and more standard text + is inserted. + + \snippet examples/richtext/orderform/mainwindow.cpp 11 + \snippet examples/richtext/orderform/mainwindow.cpp 12 + + Another QTextTable is inserted, to display the customer's + preference regarding offers. + + \snippet examples/richtext/orderform/mainwindow.cpp 13 + + The document structure for this portion is: + + \table + \row + \o block + \row + \o block\o \c{Please update my...} + \row + \o {1, 5} block + \row + \o {1, 4} \c{offersTable} + \row + \o block \o \c{I want to receive...} + \row + \o block \o \c{I do not want to recieve...} + \row + \o block \o \c{X} + \endtable + + The \c cursor is moved to insert "Sincerely" along with the customer's + name. More blocks are inserted for spacing purposes. The \c printAction + is enabled to indicate that an order form can now be printed. + + \snippet examples/richtext/orderform/mainwindow.cpp 14 + + The bottom portion of the document structure is: + + \table + \row + \o block + \row + \o {1, 5} block\o \c{Sincerely,} + \row + \o block + \row + \o block + \row + \o block + \row + \o block \o \c{Donald} + \endtable + + The \c createSample() function is used for illustration purposes, to create + a sample order form. + + \snippet examples/richtext/orderform/mainwindow.cpp 15 + + The \c openDialog() function opens a \c DetailsDialog object. If the + details in \c dialog are accepted, the \c createLetter() function is + invoked using the parameters extracted from \c dialog. + + \snippet examples/richtext/orderform/mainwindow.cpp 16 + + In order to print out the order form, a \c printFile() function is + included, as shown below: + + \snippet examples/richtext/orderform/mainwindow.cpp 17 + + This function also allows the user to print a selected area with + QTextCursor::hasSelection(), instead of printing the entire document. + + \section1 \c main() Function + + The \c main() function instantiates \c MainWindow and sets its size to + 640x480 pixels before invoking the \c show() function and + \c createSample() function. + + \snippet examples/richtext/orderform/main.cpp 0 + +*/ diff --git a/doc/src/examples/overpainting.qdoc b/doc/src/examples/overpainting.qdoc new file mode 100644 index 0000000..e19f54b --- /dev/null +++ b/doc/src/examples/overpainting.qdoc @@ -0,0 +1,249 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example opengl/overpainting + \title Overpainting Example + + The Overpainting example shows how QPainter can be used + to overpaint a scene rendered using OpenGL in a QGLWidget. + + \image overpainting-example.png + + QGLWidget provides a widget with integrated OpenGL graphics support + that enables 3D graphics to be displayed using normal OpenGL calls, + yet also behaves like any other standard Qt widget with support for + signals and slots, properties, and Qt's action system. + + Usually, QGLWidget is subclassed to display a pure 3D scene; the + developer reimplements \l{QGLWidget::initializeGL()}{initializeGL()} + to initialize any required resources, \l{QGLWidget::resizeGL()}{resizeGL()} + to set up the projection and viewport, and + \l{QGLWidget::paintGL()}{paintGL()} to perform the OpenGL calls needed + to render the scene. However, it is possible to subclass QGLWidget + differently to allow 2D graphics, drawn using QPainter, to be + painted over a scene rendered using OpenGL. + + In this example, we demonstrate how this is done by reusing the code + from the \l{Hello GL Example}{Hello GL} example to provide a 3D scene, + and painting over it with some translucent 2D graphics. Instead of + examining each class in detail, we only cover the parts of the + \c GLWidget class that enable overpainting, and provide more detailed + discussion in the final section of this document. + + \section1 GLWidget Class Definition + + The \c GLWidget class is a subclass of QGLWidget, based on the one used + in the \l{Hello GL Example}{Hello GL} example. Rather than describe the + class as a whole, we show the first few lines of the class and only + discuss the changes we have made to the rest of it: + + \snippet examples/opengl/overpainting/glwidget.h 0 + \dots + \snippet examples/opengl/overpainting/glwidget.h 1 + \dots + \snippet examples/opengl/overpainting/glwidget.h 4 + + As usual, the widget uses \l{QGLWidget::initializeGL()}{initializeGL()} + to set up objects for our scene and perform other OpenGL initialization tasks. + The \l{QGLWidget::resizeGL()}{resizeGL()} function is used to ensure that + the 3D graphics in the scene are transformed correctly to the 2D viewport + displayed in the widget. + + Instead of implementing \l{QGLWidget::paintGL()}{paintGL()} to handle updates + to the widget, we implement a normal QWidget::paintEvent(). This + allows us to mix OpenGL calls and QPainter operations in a controlled way. + + In this example, we also implement QWidget::showEvent() to help with the + initialization of the 2D graphics used. + + The new private member functions and variables relate exclusively to the + 2D graphics and animation. The \c animate() slot is called periodically by the + \c animationTimer to update the widget; the \c createBubbles() function + initializes the \c bubbles list with instances of a helper class used to + draw the animation; the \c drawInstructions() function is responsible for + a semi-transparent messages that is also overpainted onto the OpenGL scene. + + \section1 GLWidget Class Implementation + + Again, we only show the parts of the \c GLWidget implementation that are + relevant to this example. In the constructor, we initialize a QTimer to + control the animation: + + \snippet examples/opengl/overpainting/glwidget.cpp 0 + + We turn off the widget's \l{QWidget::autoFillBackground}{autoFillBackground} property to + instruct OpenGL not to paint a background for the widget when + \l{QPainter::begin()}{QPainter::begin()} is called. + + As in the \l{Hello GL Example}{Hello GL} example, the destructor is responsible + for freeing any OpenGL-related resources: + + \snippet examples/opengl/overpainting/glwidget.cpp 1 + + The \c initializeGL() function is fairly minimal, only setting up the display + list used in the scene. + + \snippet examples/opengl/overpainting/glwidget.cpp 2 + + To cooperate fully with QPainter, we defer matrix stack operations and attribute + initialization until the widget needs to be updated. + + In this example, we implement \l{QWidget::paintEvent()}{paintEvent()} rather + than \l{QGLWidget::paintGL()}{paintGL()} to render + our scene. When drawing on a QGLWidget, the paint engine used by QPainter + performs certain operations that change the states of the OpenGL + implementation's matrix and property stacks. Therefore, it is necessary to + make all the OpenGL calls to display the 3D graphics before we construct + a QPainter to draw the 2D overlay. + + We render a 3D scene by setting up model and projection transformations + and other attributes. We use an OpenGL stack operation to preserve the + original matrix state, allowing us to recover it later: + + \snippet examples/opengl/overpainting/glwidget.cpp 4 + + We define a color to use for the widget's background, and set up various + attributes that define how the scene will be rendered. + + \snippet examples/opengl/overpainting/glwidget.cpp 6 + + We call the \c setupViewport() private function to set up the + projection used for the scene. This is unnecessary in OpenGL + examples that implement the \l{QGLWidget::paintGL()}{paintGL()} + function because the matrix stacks are usually unmodified between + calls to \l{QGLWidget::resizeGL()}{resizeGL()} and + \l{QGLWidget::paintGL()}{paintGL()}. + + Since the widget's background is not drawn by the system or by Qt, we use + an OpenGL call to paint it before positioning the object defined earlier + in the scene: + + \snippet examples/opengl/overpainting/glwidget.cpp 7 + + Once the list containing the object has been executed, the matrix stack + needs to be restored to its original state at the start of this function + before we can begin overpainting: + + \snippet examples/opengl/overpainting/glwidget.cpp 8 + + With the 3D graphics done, we construct a QPainter for use on the widget + and simply overpaint the widget with 2D graphics; in this case, using a + helper class to draw a number of translucent bubbles onto the widget, + and calling \c drawInstructions() to overlay some instructions: + + \snippet examples/opengl/overpainting/glwidget.cpp 10 + + When QPainter::end() is called, suitable OpenGL-specific calls are made to + write the scene, and its additional contents, onto the widget. + + The implementation of the \l{QGLWidget::resizeGL()}{resizeGL()} function + sets up the dimensions of the viewport and defines a projection + transformation: + + \snippet examples/opengl/overpainting/glwidget.cpp 11 + + Ideally, we want to arrange the 2D graphics to suit the widget's dimensions. + To achieve this, we implement the \l{QWidget::showEvent()}{showEvent()} handler, + creating new graphic elements (bubbles) if necessary at appropriate positions + in the widget. + + \snippet examples/opengl/overpainting/glwidget.cpp 12 + + This function only has an effect if less than 20 bubbles have already been + created. + + The \c animate() slot is called every time the widget's \c animationTimer emits + the \l{QTimer::timeout()}{timeout()} signal. This keeps the bubbles moving + around. + + \snippet examples/opengl/overpainting/glwidget.cpp 13 + + We simply iterate over the bubbles in the \c bubbles list, updating the + widget before and after each of them is moved. + + The \c setupViewport() function is called from \c paintEvent() + and \c resizeGL(). + + \snippet examples/opengl/overpainting/glwidget.cpp 14 + + The \c drawInstructions() function is used to prepare some basic + instructions that will be painted with the other 2D graphics over + the 3D scene. + + \snippet examples/opengl/overpainting/glwidget.cpp 15 + + \section1 Summary + + When overpainting 2D content onto 3D content, we need to use a QPainter + \e and make OpenGL calls to achieve the desired effect. Since QPainter + itself uses OpenGL calls when used on a QGLWidget subclass, we need to + preserve the state of various OpenGL stacks when we perform our own + calls, using the following approach: + + \list + \o Reimplement QGLWidget::initializeGL(), but only perform minimal + initialization. QPainter will perform its own initialization + routines, modifying the matrix and property stacks, so it is better + to defer certain initialization tasks until just before you render + the 3D scene. + \o Reimplement QGLWidget::resizeGL() as in the pure 3D case. + \o Reimplement QWidget::paintEvent() to draw both 2D and 3D graphics. + \endlist + + The \l{QWidget::paintEvent()}{paintEvent()} implementation performs the + following tasks: + + \list + \o Push the current OpenGL modelview matrix onto a stack. + \o Perform initialization tasks usually done in the + \l{QGLWidget::initializeGL()}{initializeGL()} function. + \o Perform code that would normally be located in the widget's + \l{QGLWidget::resizeGL()}{resizeGL()} function to set the correct + perspective transformation and set up the viewport. + \o Render the scene using OpenGL calls. + \o Pop the OpenGL modelview matrix off the stack. + \o Construct a QPainter object. + \o Initialize it for use on the widget with the QPainter::begin() function. + \o Draw primitives using QPainter's member functions. + \o Call QPainter::end() to finish painting. + \endlist +*/ diff --git a/doc/src/examples/padnavigator.qdoc b/doc/src/examples/padnavigator.qdoc new file mode 100644 index 0000000..f43725b --- /dev/null +++ b/doc/src/examples/padnavigator.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example graphicsview/padnavigator + \title Pad Navigator Example + + The Pad Navigator Example shows how you can use Graphics View + together with embedded widgets to create a simple but useful + dynamic user interface for embedded devices. + + \image padnavigator-example.png +*/ diff --git a/doc/src/examples/painterpaths.qdoc b/doc/src/examples/painterpaths.qdoc new file mode 100644 index 0000000..fd27566 --- /dev/null +++ b/doc/src/examples/painterpaths.qdoc @@ -0,0 +1,432 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example painting/painterpaths + \title Painter Paths Example + + The Painter Paths example shows how painter paths can be used to + build complex shapes for rendering. + + \image painterpaths-example.png + + The QPainterPath class provides a container for painting + operations, enabling graphical shapes to be constructed and + reused. + + A painter path is an object composed of a number of graphical + building blocks (such as rectangles, ellipses, lines, and curves), + and can be used for filling, outlining, and clipping. The main + advantage of painter paths over normal drawing operations is that + complex shapes only need to be created once, but they can be drawn + many times using only calls to QPainter::drawPath(). + + The example consists of two classes: + + \list + \o The \c RenderArea class which is a custom widget displaying + a single painter path. + \o The \c Window class which is the applications main window + displaying several \c RenderArea widgets, and allowing the user + to manipulate the painter paths' filling, pen, color + and rotation angle. + \endlist + + First we will review the \c Window class, then we will take a look + at the \c RenderArea class. + + \section1 Window Class Definition + + The \c Window class inherits QWidget, and is the applications main + window displaying several \c RenderArea widgets, and allowing the + user to manipulate the painter paths' filling, pen, color and + rotation angle. + + \snippet examples/painting/painterpaths/window.h 0 + + We declare three private slots to respond to user input regarding + filling and color: \c fillRuleChanged(), \c fillGradientChanged() + and \c penColorChanged(). + + When the user changes the pen width and the rotation angle, the + new value is passed directly on to the \c RenderArea widgets using + the QSpinBox::valueChanged() signal. The reason why we must + implement slots to update the filling and color, is that QComboBox + doesn't provide a similar signal passing the new value as + argument; so we need to retrieve the new value, or values, before + we can update the \c RenderArea widgets. + + \snippet examples/painting/painterpaths/window.h 1 + + We also declare a couple of private convenience functions: \c + populateWithColors() populates a given QComboBox with items + corresponding to the color names Qt knows about, and \c + currentItemData() returns the current item for a given QComboBox. + + \snippet examples/painting/painterpaths/window.h 2 + + Then we declare the various components of the main window + widget. We also declare a convenience constant specifying the + number of \c RenderArea widgets. + + \section1 Window Class Implementation + + In the implementation of the \c Window class we first declare the + constant \c Pi with six significant figures: + + \snippet examples/painting/painterpaths/window.cpp 0 + + In the constructor, we then define the various painter paths and + create corresponding \c RenderArea widgets which will render the + graphical shapes: + + \snippet examples/painting/painterpaths/window.cpp 1 + + We construct a rectangle with sharp corners using the + QPainterPath::moveTo() and QPainterPath::lineTo() + functions. + + QPainterPath::moveTo() moves the current point to the point passed + as argument. A painter path is an object composed of a number of + graphical building blocks, i.e. subpaths. Moving the current point + will also start a new subpath (implicitly closing the previously + current path when the new one is started). The + QPainterPath::lineTo() function adds a straight line from the + current point to the given end point. After the line is drawn, the + current point is updated to be at the end point of the line. + + We first move the current point starting a new subpath, and we + draw three of the rectangle's sides. Then we call the + QPainterPath::closeSubpath() function which draws a line to the + beginning of the current subpath. A new subpath is automatically + begun when the current subpath is closed. The current point of the + new path is (0, 0). We could also have called + QPainterPath::lineTo() to draw the last line as well, and then + explicitly start a new subpath using the QPainterPath::moveTo() + function. + + QPainterPath also provide the QPainterPath::addRect() convenience + function, which adds a given rectangle to the path as a closed + subpath. The rectangle is added as a clockwise set of lines. The + painter path's current position after the rect has been added is + at the top-left corner of the rectangle. + + \snippet examples/painting/painterpaths/window.cpp 2 + + Then we construct a rectangle with rounded corners. As before, we + use the QPainterPath::moveTo() and QPainterPath::lineTo() + functions to draw the rectangle's sides. To create the rounded + corners we use the QPainterPath::arcTo() function. + + QPainterPath::arcTo() creates an arc that occupies the given + rectangle (specified by a QRect or the rectangle's coordinates), + beginning at the given start angle and extending the given degrees + counter-clockwise. Angles are specified in degrees. Clockwise arcs + can be specified using negative angles. The function connects the + current point to the starting point of the arc if they are not + already connected. + + \snippet examples/painting/painterpaths/window.cpp 3 + + We also use the QPainterPath::arcTo() function to construct the + ellipse path. First we move the current point starting a new + path. Then we call QPainterPath::arcTo() with starting angle 0.0 + and 360.0 degrees as the last argument, creating an ellipse. + + Again, QPainterPath provides a convenience function ( + QPainterPath::addEllipse()) which creates an ellipse within a + given bounding rectangle and adds it to the painter path. If the + current subpath is closed, a new subpath is started. The ellipse + is composed of a clockwise curve, starting and finishing at zero + degrees (the 3 o'clock position). + + \snippet examples/painting/painterpaths/window.cpp 4 + + When constructing the pie chart path we continue to use a + combination of the mentioned functions: First we move the current + point, starting a new subpath. Then we create a line from the + center of the chart to the arc, and the arc itself. When we close + the subpath, we implicitly construct the last line back to the + center of the chart. + + \snippet examples/painting/painterpaths/window.cpp 5 + + Constructing a polygon is equivalent to constructing a rectangle. + + QPainterPath also provide the QPainterPath::addPolygon() + convenience function which adds the given polygon to the path as a + new subpath. Current position after the polygon has been added is + the last point in polygon. + + \snippet examples/painting/painterpaths/window.cpp 6 + + Then we create a path consisting of a group of subpaths: First we + move the current point, and create a circle using the + QPainterPath::arcTo() function with starting angle 0.0, and 360 + degrees as the last argument, as we did when we created the + ellipse path. Then we move the current point again, starting a + new subpath, and construct three sides of a square using the + QPainterPath::lineTo() function. + + Now, when we call the QPainterPath::closeSubpath() fucntion the + last side is created. Remember that the + QPainterPath::closeSubpath() function draws a line to the + beginning of the \e current subpath, i.e the square. + + QPainterPath provide a convenience function, + QPainterPath::addPath() which adds a given path to the path that + calls the function. + + \snippet examples/painting/painterpaths/window.cpp 7 + + When creating the text path, we first create the font. Then we set + the font's style strategy which tells the font matching algorithm + what type of fonts should be used to find an appropriate default + family. QFont::ForceOutline forces the use of outline fonts. + + To construct the text, we use the QPainterPath::addText() function + which adds the given text to the path as a set of closed subpaths + created from the supplied font. The subpaths are positioned so + that the left end of the text's baseline lies at the specified + point. + + \snippet examples/painting/painterpaths/window.cpp 8 + + To create the Bezier path, we use the QPainterPath::cubicTo() + function which adds a Bezier curve between the current point and + the given end point with the given control point. After the curve + is added, the current point is updated to be at the end point of + the curve. + + In this case we omit to close the subpath so that we only have a + simple curve. But there is still a logical line from the curve's + endpoint back to the beginning of the subpath; it becomes visible + when filling the path as can be seen in the applications main + window. + + \snippet examples/painting/painterpaths/window.cpp 9 + + The final path that we construct shows that you can use + QPainterPath to construct rather complex shapes using only the + previous mentioned QPainterPath::moveTo(), QPainterPath::lineTo() + and QPainterPath::closeSubpath() functions. + + \snippet examples/painting/painterpaths/window.cpp 10 + + Now that we have created all the painter paths that we need, we + create a corresponding \c RenderArea widget for each. In the end, + we make sure that the number of render areas is correct using the + Q_ASSERT() macro. + + \snippet examples/painting/painterpaths/window.cpp 11 + + Then we create the widgets associated with the painter paths' fill + rule. + + There are two available fill rules in Qt: The Qt::OddEvenFill rule + determine whether a point is inside the shape by drawing a + horizontal line from the point to a location outside the shape, + and count the number of intersections. If the number of + intersections is an odd number, the point is inside the + shape. This rule is the default. + + The Qt::WindingFill rule determine whether a point is inside the + shape by drawing a horizontal line from the point to a location + outside the shape. Then it determines whether the direction of the + line at each intersection point is up or down. The winding number + is determined by summing the direction of each intersection. If + the number is non zero, the point is inside the shape. + + The Qt::WindingFill rule can in most cases be considered as the + intersection of closed shapes. + + \snippet examples/painting/painterpaths/window.cpp 12 + + We also create the other widgets associated with the filling, the + pen and the rotation angle. + + \snippet examples/painting/painterpaths/window.cpp 16 + + We connect the comboboxes \l {QComboBox::activated()}{activated()} + signals to the associated slots in the \c Window class, while we + connect the spin boxes \l + {QSpinBox::valueChanged()}{valueChanged()} signal directly to the + \c RenderArea widget's respective slots. + + \snippet examples/painting/painterpaths/window.cpp 17 + + We add the \c RenderArea widgets to a separate layout which we + then add to the main layout along with the rest of the widgets. + + \snippet examples/painting/painterpaths/window.cpp 18 + + Finally, we initialize the \c RenderArea widgets by calling the \c + fillRuleChanged(), \c fillGradientChanged() and \c + penColorChanged() slots, and we set the inital pen width and + window title. + + \snippet examples/painting/painterpaths/window.cpp 19 + \codeline + \snippet examples/painting/painterpaths/window.cpp 20 + \codeline + \snippet examples/painting/painterpaths/window.cpp 21 + + The private slots are implemented to retrieve the new value, or + values, from the associated comboboxes and update the RenderArea + widgets. + + First we determine the new value, or values, using the private \c + currentItemData() function and the qvariant_cast() template + function. Then we call the associated slot for each of the \c + RenderArea widgets to update the painter paths. + + \snippet examples/painting/painterpaths/window.cpp 22 + + The \c populateWithColors() function populates the given combobox + with items corresponding to the color names Qt knows about + provided by the static QColor::colorNames() function. + + \snippet examples/painting/painterpaths/window.cpp 23 + + The \c currentItemData() function simply return the current item + of the given combobox. + + \section1 RenderArea Class Definition + + The \c RenderArea class inherits QWidget, and is a custom widget + displaying a single painter path. + + \snippet examples/painting/painterpaths/renderarea.h 0 + + We declare several public slots updating the \c RenderArea + widget's associated painter path. In addition we reimplement the + QWidget::minimumSizeHint() and QWidget::sizeHint() functions to + give the \c RenderArea widget a reasonable size within our + application, and we reimplement the QWidget::paintEvent() event + handler to draw its painter path. + + \snippet examples/painting/painterpaths/renderarea.h 1 + + Each instance of the \c RenderArea class has a QPainterPath, a + couple of fill colors, a pen width, a pen color and a rotation + angle. + + \section1 RenderArea Class Implementation + + The constructor takes a QPainterPath as argument (in addition to + the optional QWidget parent): + + \snippet examples/painting/painterpaths/renderarea.cpp 0 + + In the constructor we initialize the \c RenderArea widget with the + QPainterPath parameter as well as initializing the pen width and + rotation angle. We also set the widgets \l + {QWidget::backgroundRole()}{background role}; QPalette::Base is + typically white. + + \snippet examples/painting/painterpaths/renderarea.cpp 1 + \codeline + \snippet examples/painting/painterpaths/renderarea.cpp 2 + + Then we reimplement the QWidget::minimumSizeHint() and + QWidget::sizeHint() functions to give the \c RenderArea widget a + reasonable size within our application. + + \snippet examples/painting/painterpaths/renderarea.cpp 3 + \codeline + \snippet examples/painting/painterpaths/renderarea.cpp 4 + \codeline + \snippet examples/painting/painterpaths/renderarea.cpp 5 + \codeline + \snippet examples/painting/painterpaths/renderarea.cpp 6 + \codeline + \snippet examples/painting/painterpaths/renderarea.cpp 7 + + The various public slots updates the \c RenderArea widget's + painter path by setting the associated property and make a call to + the QWidget::update() function, forcing a repaint of the widget + with the new rendering preferences. + + The QWidget::update() slot does not cause an immediate repaint; + instead it schedules a paint event for processing when Qt returns + to the main event loop. + + \snippet examples/painting/painterpaths/renderarea.cpp 8 + + A paint event is a request to repaint all or parts of the + widget. The paintEvent() function is an event handler that can be + reimplemented to receive the widget's paint events. We reimplement + the event handler to render the \c RenderArea widget's painter + path. + + First, we create a QPainter for the \c RenderArea instance, and + set the painter's render hints. The QPainter::RenderHints are used + to specify flags to QPainter that may, or may not, be respected by + any given engine. QPainter::Antialiasing indicates that the engine + should anti-alias the edges of primitives if possible, i.e. put + additional pixels around the original ones to smooth the edges. + + \snippet examples/painting/painterpaths/renderarea.cpp 9 + + Then we scale the QPainter's coordinate system to ensure that the + painter path is rendered in the right size, i.e that it grows with + the \c RenderArea widget when the application is resized. When we + constructed the various painter paths, they were all rnedered + within a square with a 100 pixel width wich is equivalent to \c + RenderArea::sizeHint(). The QPainter::scale() function scales the + coordinate system by the \c RenderArea widget's \e current width + and height divided by 100. + + Now, when we are sure that the painter path has the right size, we + can translate the coordinate system to make the painter path + rotate around the \c RenderArea widget's center. After we have + performed the rotation, we must remember to translate the + coordinate system back again. + + \snippet examples/painting/painterpaths/renderarea.cpp 10 + + Then we set the QPainter's pen with the instance's rendering + preferences. We create a QLinearGradient and set its colors + corresponding to the \c RenderArea widget's fill colors. Finally, + we set the QPainter's brush (the gradient is automatically + converted into a QBrush), and draw the \c RenderArea widget's + painter path using the QPainter::drawPath() function. +*/ diff --git a/doc/src/examples/pbuffers.qdoc b/doc/src/examples/pbuffers.qdoc new file mode 100644 index 0000000..347cf3d --- /dev/null +++ b/doc/src/examples/pbuffers.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example opengl/pbuffers + \title Pixel Buffers Example + + The Pixel Buffers example demonstrates how to use the + QGLPixelBuffer class to render into an off-screen buffer and use + the contents as a dynamic texture in a QGLWidget. + + \image pbuffers-example.png +*/ diff --git a/doc/src/examples/pbuffers2.qdoc b/doc/src/examples/pbuffers2.qdoc new file mode 100644 index 0000000..5426852 --- /dev/null +++ b/doc/src/examples/pbuffers2.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example opengl/pbuffers2 + \title Pixel Buffers 2 Example + + The Pixel Buffers 2 example demonstrates how to use the + QGLPixelBuffer class to render into an off-screen buffer and use + the contents as a dynamic texture in a QGLWidget. + + \image pbuffers2-example.png +*/ diff --git a/doc/src/examples/pixelator.qdoc b/doc/src/examples/pixelator.qdoc new file mode 100644 index 0000000..2a8b43d --- /dev/null +++ b/doc/src/examples/pixelator.qdoc @@ -0,0 +1,271 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/pixelator + \title Pixelator Example + + The Pixelator example shows how delegates can be used to customize the way that + items are rendered in standard item views. + + \image pixelator-example.png + + By default, QTreeView, QTableView, and QListView use a standard item delegate + to display and edit a set of common data types that are sufficient for many + applications. However, an application may need to represent items of data in a + particular way, or provide support for rendering more specialized data types, + and this often requires the use of a custom delegate. + + In this example, we show how to use custom delegates to modify the appearance + of standard views. To do this, we implement the following components: + + \list + \i A model which represents each pixel in an image as an item of data, where each + item contains a value for the brightness of the corresponding pixel. + \i A custom delegate that uses the information supplied by the model to represent + each pixel as a black circle on a white background, where the radius of the + circle corresponds to the darkness of the pixel. + \endlist + + This example may be useful for developers who want to implement their own table + models or custom delegates. The process of creating custom delegates for editing + item data is covered in the \l{Spin Box Delegate Example}{Spin Box Delegate} + example. + + \section1 ImageModel Class Definition + + The \c ImageModel class is defined as follows: + + \snippet examples/itemviews/pixelator/imagemodel.h 0 + + Since we only require a simple, read-only table model, we only need to implement + functions to indicate the dimensions of the image and supply data to other + components. + + For convenience, the image to be used is passed in the constructor. + + \section1 ImageModel Class Implementation + + The constructor is trivial: + + \snippet examples/itemviews/pixelator/imagemodel.cpp 0 + + The \c setImage() function sets the image that will be used by the model: + + \snippet examples/itemviews/pixelator/imagemodel.cpp 1 + + The QAbstractItemModel::reset() call tells the view(s) that the model + has changed. + + The \c rowCount() and \c columnCount() functions return the height and width of + the image respectively: + + \snippet examples/itemviews/pixelator/imagemodel.cpp 2 + \snippet examples/itemviews/pixelator/imagemodel.cpp 3 + + Since the image is a simple two-dimensional structure, the \c parent arguments + to these functions are unused. They both simply return the relevant size from + the underlying image object. + + The \c data() function returns data for the item that corresponds to a given + model index in a format that is suitable for a particular role: + + \snippet examples/itemviews/pixelator/imagemodel.cpp 4 + + In this implementation, we only check that the model index is valid, and that + the role requested is the \l{Qt::ItemDataRole}{DisplayRole}. If so, the function + returns the grayscale value of the relevant pixel in the image; otherwise, a null + model index is returned. + + This model can be used with QTableView to display the integer brightness values + for the pixels in the image. However, we will implement a custom delegate to + display this information in a more artistic way. + + The \c headerData() function is also reimplemented: + + \snippet examples/itemviews/pixelator/imagemodel.cpp 5 + + We return (1, 1) as the size hint for a header item. If we + didn't, the headers would default to a larger size, preventing + us from displaying really small items (which can be specified + using the \gui{Pixel size} combobox). + + \section1 PixelDelegate Class Definition + + The \c PixelDelegate class is defined as follows: + + \snippet examples/itemviews/pixelator/pixeldelegate.h 0 + + This class provides only basic features for a delegate so, unlike the + \l{Spin Box Delegate Example}{Spin Box Delegate} example, we subclass + QAbstractItemDelegate instead of QItemDelegate. + + We only need to reimplement \l{QAbstractItemDelegate::paint()}{paint()} and + \l{QAbstractItemDelegate::sizeHint()}{sizeHint()} in this class. + However, we also provide a delegate-specific \c setPixelSize() function so + that we can change the delegate's behavior via the signals and slots mechanism. + + \section1 PixelDelegate Class Implementation + + The \c PixelDelegate constructor is used to set up a default value for + the size of each "pixel" that it renders. The base class constructor is + also called to ensure that the delegate is set up with a parent object, + if one is supplied: + + \snippet examples/itemviews/pixelator/pixeldelegate.cpp 0 + + Each item is rendered by the delegate's + \l{QAbstractItemDelegate::paint()}{paint()} function. The view calls this + function with a ready-to-use QPainter object, style information that the + delegate should use to correctly draw the item, and an index to the item in + the model: + + \snippet examples/itemviews/pixelator/pixeldelegate.cpp 1 + + The first task the delegate has to perform is to draw the item's background + correctly. Usually, selected items appear differently to non-selected items, + so we begin by testing the state passed in the style option and filling the + background if necessary. + + The radius of each circle is calculated in the following lines of code: + + \snippet examples/itemviews/pixelator/pixeldelegate.cpp 3 + \snippet examples/itemviews/pixelator/pixeldelegate.cpp 4 + + First, the largest possible radius of the circle is determined by taking the + smallest dimension of the style option's \c rect attribute. + Using the model index supplied, we obtain a value for the brightness of the + relevant pixel in the image. The radius of the circle is calculated by + scaling the brightness to fit within the item and subtracting it from the + largest possible radius. + + \snippet examples/itemviews/pixelator/pixeldelegate.cpp 5 + \snippet examples/itemviews/pixelator/pixeldelegate.cpp 6 + \snippet examples/itemviews/pixelator/pixeldelegate.cpp 7 + + We save the painter's state, turn on antialiasing (to obtain smoother + curves), and turn off the pen. + + \snippet examples/itemviews/pixelator/pixeldelegate.cpp 8 + \snippet examples/itemviews/pixelator/pixeldelegate.cpp 9 + + The foreground of the item (the circle representing a pixel) must be + rendered using an appropriate brush. For unselected items, we will use a + solid black brush; selected items are drawn using a predefined brush from + the style option's palette. + + \snippet examples/itemviews/pixelator/pixeldelegate.cpp 10 + + Finally, we paint the circle within the rectangle specified by the style + option and we call \l{QPainter::}{restore()} on the painter. + + The \c paint() function does not have to be particularly complicated; it is + only necessary to ensure that the state of the painter when the function + returns is the same as it was when it was called. This usually + means that any transformations applied to the painter must be preceded by + a call to QPainter::save() and followed by a call to QPainter::restore(). + + The delegate's \l{QAbstractItemDelegate::}{sizeHint()} function + returns a size for the item based on the predefined pixel size, initially set + up in the constructor: + + \snippet examples/itemviews/pixelator/pixeldelegate.cpp 11 + + The delegate's size is updated whenever the pixel size is changed. + We provide a custom slot to do this: + + \snippet examples/itemviews/pixelator/pixeldelegate.cpp 12 + + \section1 Using The Custom Delegate + + In this example, we use a main window to display a table of data, using the + custom delegate to render each cell in a particular way. Much of the + \c MainWindow class performs tasks that are not related to item views. Here, + we only quote the parts that are relevant. You can look at the rest of the + implementation by following the links to the code at the top of this + document. + + In the constructor, we set up a table view, turn off its grid, and hide its + headers: + + \snippet examples/itemviews/pixelator/mainwindow.cpp 0 + \dots + \snippet examples/itemviews/pixelator/mainwindow.cpp 1 + + This enables the items to be drawn without any gaps between them. Removing + the headers also prevents the user from adjusting the sizes of individual + rows and columns. + + We also set the minimum section size to 1 on the headers. If we + didn't, the headers would default to a larger size, preventing + us from displaying really small items (which can be specified + using the \gui{Pixel size} combobox). + + The custom delegate is constructed with the main window as its parent, so + that it will be deleted correctly later, and we set it on the table view. + + \snippet examples/itemviews/pixelator/mainwindow.cpp 2 + + Each item in the table view will be rendered by the \c PixelDelegate + instance. + + We construct a spin box to allow the user to change the size of each "pixel" + drawn by the delegate: + + \snippet examples/itemviews/pixelator/mainwindow.cpp 3 + + This spin box is connected to the custom slot we implemented in the + \c PixelDelegate class. This ensures that the delegate always draws each + pixel at the currently specified size: + + \snippet examples/itemviews/pixelator/mainwindow.cpp 4 + \dots + \snippet examples/itemviews/pixelator/mainwindow.cpp 5 + + We also connect the spin box to a slot in the \c MainWindow class. This + forces the view to take into account the new size hints for each item; + these are provided by the delegate in its \c sizeHint() function. + + \snippet examples/itemviews/pixelator/mainwindow.cpp 6 + + We explicitly resize the columns and rows to match the + \gui{Pixel size} combobox. +*/ diff --git a/doc/src/examples/plugandpaint.qdoc b/doc/src/examples/plugandpaint.qdoc new file mode 100644 index 0000000..3cdd8a4 --- /dev/null +++ b/doc/src/examples/plugandpaint.qdoc @@ -0,0 +1,554 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/plugandpaint + \title Plug & Paint Example + + The Plug & Paint example demonstrates how to write Qt + applications that can be extended through plugins. + + \image plugandpaint.png Screenshot of the Plug & Paint example + + A plugin is a dynamic library that can be loaded at run-time to + extend an application. Qt makes it possible to create custom + plugins and to load them using QPluginLoader. To ensure that + plugins don't get lost, it is also possible to link them + statically to the executable. The Plug & Paint example uses + plugins to support custom brushes, shapes, and image filters. A + single plugin can provide multiple brushes, shapes, and/or + filters. + + If you want to learn how to make your own application extensible + through plugins, we recommend that you start by reading this + overview, which explains how to make an application use plugins. + Afterward, you can read the + \l{tools/plugandpaintplugins/basictools}{Basic Tools} and + \l{tools/plugandpaintplugins/extrafilters}{Extra Filters} + overviews, which show how to implement static and dynamic + plugins, respectively. + + Plug & Paint consists of the following classes: + + \list + \o \c MainWindow is a QMainWindow subclass that provides the menu + system and that contains a \c PaintArea as the central widget. + \o \c PaintArea is a QWidget that allows the user to draw using a + brush and to insert shapes. + \o \c PluginDialog is a dialog that shows information about the + plugins detected by the application. + \o \c BrushInterface, \c ShapeInterface, and \c FilterInterface are + abstract base classes that can be implemented by plugins to + provide custom brushes, shapes, and image filters. + \endlist + + \section1 The Plugin Interfaces + + We will start by reviewing the interfaces defined in \c + interfaces.h. These interfaces are used by the Plug & Paint + application to access extra functionality. They are implemented + in the plugins. + + + \snippet examples/tools/plugandpaint/interfaces.h 0 + + The \c BrushInterface class declares four pure virtual functions. + The first pure virtual function, \c brushes(), returns a list of + strings that identify the brushes provided by the plugin. By + returning a QStringList instead of a QString, we make it possible + for a single plugin to provide multiple brushes. The other + functions have a \c brush parameter to identify which brush + (among those returned by \c brushes()) is used. + + \c mousePress(), \c mouseMove(), and \c mouseRelease() take a + QPainter and one or two \l{QPoint}s, and return a QRect + identifying which portion of the image was altered by the brush. + + The class also has a virtual destructor. Interface classes + usually don't need such a destructor (because it would make + little sense to \c delete the object that implements the + interface through a pointer to the interface), but some compilers + emit a warning for classes that declare virtual functions but no + virtual destructor. We provide the destructor to keep these + compilers happy. + + \snippet examples/tools/plugandpaint/interfaces.h 1 + + The \c ShapeInterface class declares a \c shapes() function that + works the same as \c{BrushInterface}'s \c brushes() function, and + a \c generateShape() function that has a \c shape parameter. + Shapes are represented by a QPainterPath, a data type that can + represent arbitrary 2D shapes or combinations of shapes. The \c + parent parameter can be used by the plugin to pop up a dialog + asking the user to specify more information. + + \snippet examples/tools/plugandpaint/interfaces.h 2 + + The \c FilterInterface class declares a \c filters() function + that returns a list of filter names, and a \c filterImage() + function that applies a filter to an image. + + \snippet examples/tools/plugandpaint/interfaces.h 4 + + To make it possible to query at run-time whether a plugin + implements a given interface, we must use the \c + Q_DECLARE_INTERFACE() macro. The first argument is the name of + the interface. The second argument is a string identifying the + interface in a unique way. By convention, we use a "Java package + name" syntax to identify interfaces. If we later change the + interfaces, we must use a different string to identify the new + interface; otherwise, the application might crash. It is therefore + a good idea to include a version number in the string, as we did + above. + + The \l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin + and the \l{tools/plugandpaintplugins/extrafilters}{Extra Filters} + plugin shows how to derive from \c BrushInterface, \c + ShapeInterface, and \c FilterInterface. + + A note on naming: It might have been tempting to give the \c + brushes(), \c shapes(), and \c filters() functions a more generic + name, such as \c keys() or \c features(). However, that would + have made multiple inheritance impractical. When creating + interfaces, we should always try to give unique names to the pure + virtual functions. + + \section1 The MainWindow Class + + The \c MainWindow class is a standard QMainWindow subclass, as + found in many of the other examples (e.g., + \l{mainwindows/application}{Application}). Here, we'll + concentrate on the parts of the code that are related to plugins. + + \snippet examples/tools/plugandpaint/mainwindow.cpp 4 + + The \c loadPlugins() function is called from the \c MainWindow + constructor to detect plugins and update the \gui{Brush}, + \gui{Shapes}, and \gui{Filters} menus. We start by handling static + plugins (available through QPluginLoader::staticInstances()) + + To the application that uses the plugin, a Qt plugin is simply a + QObject. That QObject implements plugin interfaces using multiple + inheritance. + + \snippet examples/tools/plugandpaint/mainwindow.cpp 5 + + The next step is to load dynamic plugins. We initialize the \c + pluginsDir member variable to refer to the \c plugins + subdirectory of the Plug & Paint example. On Unix, this is just a + matter of initializing the QDir variable with + QApplication::applicationDirPath(), the path of the executable + file, and to do a \l{QDir::cd()}{cd()}. On Windows and Mac OS X, + this file is usually located in a subdirectory, so we need to + take this into account. + + \snippet examples/tools/plugandpaint/mainwindow.cpp 6 + \snippet examples/tools/plugandpaint/mainwindow.cpp 7 + \snippet examples/tools/plugandpaint/mainwindow.cpp 8 + + We use QDir::entryList() to get a list of all files in that + directory. Then we iterate over the result using \l foreach and + try to load the plugin using QPluginLoader. + + The QObject provided by the plugin is accessible through + QPluginLoader::instance(). If the dynamic library isn't a Qt + plugin, or if it was compiled against an incompatible version of + the Qt library, QPluginLoader::instance() returns a null pointer. + + If QPluginLoader::instance() is non-null, we add it to the menus. + + \snippet examples/tools/plugandpaint/mainwindow.cpp 9 + + At the end, we enable or disable the \gui{Brush}, \gui{Shapes}, + and \gui{Filters} menus based on whether they contain any items. + + \snippet examples/tools/plugandpaint/mainwindow.cpp 10 + + For each plugin (static or dynamic), we check which interfaces it + implements using \l qobject_cast(). First, we try to cast the + plugin instance to a \c BrushInterface; if it works, we call the + private function \c addToMenu() with the list of brushes returned + by \c brushes(). Then we do the same with the \c ShapeInterface + and the \c FilterInterface. + + \snippet examples/tools/plugandpaint/mainwindow.cpp 3 + + The \c aboutPlugins() slot is called on startup and can be + invoked at any time through the \gui{About Plugins} action. It + pops up a \c PluginDialog, providing information about the loaded + plugins. + + \image plugandpaint-plugindialog.png Screenshot of the Plugin dialog + + + The \c addToMenu() function is called from \c loadPlugin() to + create \l{QAction}s for custom brushes, shapes, or filters and + add them to the relevant menu. The QAction is created with the + plugin from which it comes from as the parent; this makes it + convenient to get access to the plugin later. + + \snippet examples/tools/plugandpaint/mainwindow.cpp 0 + + The \c changeBrush() slot is invoked when the user chooses one of + the brushes from the \gui{Brush} menu. We start by finding out + which action invoked the slot using QObject::sender(). Then we + get the \c BrushInterface out of the plugin (which we + conveniently passed as the QAction's parent) and we call \c + PaintArea::setBrush() with the \c BrushInterface and the string + identifying the brush. Next time the user draws on the paint + area, \c PaintArea will use this brush. + + \snippet examples/tools/plugandpaint/mainwindow.cpp 1 + + The \c insertShape() is invoked when the use chooses one of the + shapes from the \gui{Shapes} menu. We retrieve the QAction that + invoked the slot, then the \c ShapeInterface associated with that + QAction, and finally we call \c ShapeInterface::generateShape() + to obtain a QPainterPath. + + \snippet examples/tools/plugandpaint/mainwindow.cpp 2 + + The \c applyFilter() slot is similar: We retrieve the QAction + that invoked the slot, then the \c FilterInterface associated to + that QAction, and finally we call \c + FilterInterface::filterImage() to apply the filter onto the + current image. + + \section1 The PaintArea Class + + The \c PaintArea class contains some code that deals with \c + BrushInterface, so we'll review it briefly. + + \snippet examples/tools/plugandpaint/paintarea.cpp 0 + + In \c setBrush(), we simply store the \c BrushInterface and the + brush that are given to us by \c MainWindow. + + \snippet examples/tools/plugandpaint/paintarea.cpp 1 + + In the \l{QWidget::mouseMoveEvent()}{mouse move event handler}, + we call the \c BrushInterface::mouseMove() function on the + current \c BrushInterface, with the current brush. The mouse + press and mouse release handlers are very similar. + + \section1 The PluginDialog Class + + The \c PluginDialog class provides information about the loaded + plugins to the user. Its constructor takes a path to the plugins + and a list of plugin file names. It calls \c findPlugins() + to fill the QTreeWdiget with information about the plugins: + + \snippet examples/tools/plugandpaint/plugindialog.cpp 0 + + The \c findPlugins() is very similar to \c + MainWindow::loadPlugins(). It uses QPluginLoader to access the + static and dynamic plugins. Its helper function \c + populateTreeWidget() uses \l qobject_cast() to find out which + interfaces are implemented by the plugins: + + \snippet examples/tools/plugandpaint/plugindialog.cpp 1 + + \section1 Importing Static Plugins + + The \l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin + is built as a static plugin, to ensure that it is always + available to the application. This requires using the + Q_IMPORT_PLUGIN() macro somewhere in the application (in a \c + .cpp file) and specifying the plugin in the \c .pro file. + + For Plug & Paint, we have chosen to put Q_IMPORT_PLUGIN() in \c + main.cpp: + + \snippet examples/tools/plugandpaint/main.cpp 0 + + The argument to Q_IMPORT_PLUGIN() is the plugin's name, as + specified with Q_EXPORT_PLUGIN2() in the \l{Exporting the + Plugin}{plugin}. + + In the \c .pro file, we need to specify the static library. + Here's the project file for building Plug & Paint: + + \snippet examples/tools/plugandpaint/plugandpaint.pro 0 + + The \c LIBS line variable specifies the library \c pnp_basictools + located in the \c ../plugandpaintplugins/basictools directory. + (Although the \c LIBS syntax has a distinct Unix flavor, \c qmake + supports it on all platforms.) + + The \c CONFIG() code at the end is necessary for this example + because the example is part of the Qt distribution and Qt can be + configured to be built simultaneously in debug and in release + modes. You don't need to for your own plugin applications. + + This completes our review of the Plug & Paint application. At + this point, you might want to take a look at the + \l{tools/plugandpaintplugins/basictools}{Basic Tools} example + plugin. +*/ + +/*! + \example tools/plugandpaintplugins/basictools + \title Plug & Paint Basic Tools Example + + The Basic Tools example is a static plugin for the + \l{tools/plugandpaint}{Plug & Paint} example. It provides a set + of basic brushes, shapes, and filters. Through the Basic Tools + example, we will review the four steps involved in writing a Qt + plugin: + + \list 1 + \o Declare a plugin class. + \o Implement the interfaces provided by the plugin. + \o Export the plugin using the Q_EXPORT_PLUGIN2() macro. + \o Build the plugin using an adequate \c .pro file. + \endlist + + \section1 Declaration of the Plugin Class + + \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.h 0 + + We start by including \c interfaces.h, which defines the plugin + interfaces for the \l{tools/plugandpaint}{Plug & Paint} + application. For the \c #include to work, we need to add an \c + INCLUDEPATH entry to the \c .pro file with the path to Qt's \c + examples/tools directory. + + The \c BasicToolsPlugin class is a QObject subclass that + implements the \c BrushInterface, the \c ShapeInterface, and the + \c FilterInterface. This is done through multiple inheritance. + The \c Q_INTERFACES() macro is necessary to tell \l{moc}, Qt's + meta-object compiler, that the base classes are plugin + interfaces. Without the \c Q_INTERFACES() macro, we couldn't use + \l qobject_cast() in the \l{tools/plugandpaint}{Plug & Paint} + application to detect interfaces. + + \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.h 2 + + In the \c public section of the class, we declare all the + functions from the three interfaces. + + \section1 Implementation of the Brush Interface + + Let's now review the implementation of the \c BasicToolsPlugin + member functions inherited from \c BrushInterface. + + \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 0 + + The \c brushes() function returns a list of brushes provided by + this plugin. We provide three brushes: \gui{Pencil}, \gui{Air + Brush}, and \gui{Random Letters}. + + \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 1 + + On a mouse press event, we just call \c mouseMove() to draw the + spot where the event occurred. + + \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 2 + + In \c mouseMove(), we start by saving the state of the QPainter + and we compute a few variables that we'll need later. + + \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 3 + + Then comes the brush-dependent part of the code: + + \list + \o If the brush is \gui{Pencil}, we just call + QPainter::drawLine() with the current QPen. + + \o If the brush is \gui{Air Brush}, we start by setting the + painter's QBrush to Qt::Dense6Pattern to obtain a dotted + pattern. Then we draw a circle filled with that QBrush several + times, resulting in a thick line. + + \o If the brush is \gui{Random Letters}, we draw a random letter + at the new cursor position. Most of the code is for setting + the font to be bold and larger than the default font and for + computing an appropriate bounding rect. + \endlist + + At the end, we restore the painter state to what it was upon + entering the function and we return the bounding rectangle. + + \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 4 + + When the user releases the mouse, we do nothing and return an + empty QRect. + + \section1 Implementation of the Shape Interface + + \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 5 + + The plugin provides three shapes: \gui{Circle}, \gui{Star}, and + \gui{Text...}. The three dots after \gui{Text} are there because + the shape pops up a dialog asking for more information. We know + that the shape names will end up in a menu, so we include the + three dots in the shape name. + + A cleaner but more complicated design would have been to + distinguish between the internal shape name and the name used in + the user interface. + + \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 6 + + The \c generateShape() creates a QPainterPath for the specified + shape. If the shape is \gui{Text}, we pop up a QInputDialog to + let the user enter some text. + + \section1 Implementation of the Filter Interface + + \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 7 + + The plugin provides three filters: \gui{Invert Pixels}, \gui{Swap + RGB}, and \gui{Grayscale}. + + \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 8 + + The \c filterImage() function takes a filter name and a QImage as + parameters and returns an altered QImage. The first thing we do + is to convert the image to a 32-bit RGB format, to ensure that + the algorithms will work as expected. For example, + QImage::invertPixels(), which is used to implement the + \gui{Invert Pixels} filter, gives counterintuitive results for + 8-bit images, because they invert the indices into the color + table instead of inverting the color table's entries. + + \section1 Exporting the Plugin + + Whereas applications have a \c main() function as their entry + point, plugins need to contain exactly one occurrence of the + Q_EXPORT_PLUGIN2() macro to specify which class provides the + plugin: + + \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 9 + + This line may appear in any \c .cpp file that is part of the + plugin's source code. + + \section1 The .pro File + + Here's the project file for building the Basic Tools plugin: + + \snippet examples/tools/plugandpaintplugins/basictools/basictools.pro 0 + + The \c .pro file differs from typical \c .pro files in many + respects. First, it starts with a \c TEMPLATE entry specifying \c + lib. (The default template is \c app.) It also adds \c plugin to + the \c CONFIG variable. This is necessary on some platforms to + avoid generating symbolic links with version numbers in the file + name, which is appropriate for most dynamic libraries but not for + plugins. + + To make the plugin a static plugin, all that is required is to + specify \c static in addition to \c plugin. The + \l{tools/plugandpaintplugins/extrafilters}{Extra Filters} plugin, + which is compiled as a dynamic plugin, doesn't specify \c static + in its \c .pro file. + + The \c INCLUDEPATH variable sets the search paths for global + headers (i.e., header files included using \c{#include <...>}). + We add Qt's \c examples/tools directory (strictly speaking, + \c{examples/tools/plugandpaintplugins/basictools/../..}) to the + list, so that we can include \c <plugandpaint/interfaces.h>. + + The \c TARGET variable specifies which name we want to give the + target library. We use \c pnp_ as the prefix to show that the + plugin is designed to work with Plug & Paint. On Unix, \c lib is + also prepended to that name. On all platforms, a + platform-specific suffix is appended (e.g., \c .dll on Windows, + \c .a on Linux). + + The \c CONFIG() code at the end is necessary for this example + because the example is part of the Qt distribution and Qt can be + configured to be built simultaneously in debug and in release + modes. You don't need to for your own plugins. +*/ + +/*! + \example tools/plugandpaintplugins/extrafilters + \title Plug & Paint Extra Filters Example + + The Extra Filters example is a plugin for the + \l{tools/plugandpaint}{Plug & Paint} example. It provides a set + of filters in addition to those provided by the + \l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin. + + Since the approach is identical to + \l{tools/plugandpaintplugins/basictools}{Basic Tools}, we won't + review the code here. The only part of interes is the + \c .pro file, since Extra Filters is a dynamic plugin + (\l{tools/plugandpaintplugins/basictools}{Basic Tools} is + linked statically into the Plug & Paint executable). + + Here's the project file for building the Extra Filters plugin: + + \snippet examples/tools/plugandpaintplugins/extrafilters/extrafilters.pro 0 + + The \c .pro file differs from typical \c .pro files in many + respects. First, it starts with a \c TEMPLATE entry specifying \c + lib. (The default template is \c app.) It also adds \c plugin to + the \c CONFIG variable. This is necessary on some platforms to + avoid generating symbolic links with version numbers in the file + name, which is appropriate for most dynamic libraries but not for + plugins. + + The \c INCLUDEPATH variable sets the search paths for global + headers (i.e., header files included using \c{#include <...>}). + We add Qt's \c examples/tools directory (strictly speaking, + \c{examples/tools/plugandpaintplugins/basictools/../..}) to the + list, so that we can include \c <plugandpaint/interfaces.h>. + + The \c TARGET variable specifies which name we want to give the + target library. We use \c pnp_ as the prefix to show that the + plugin is designed to work with Plug & Paint. On Unix, \c lib is + also prepended to that name. On all platforms, a + platform-specific suffix is appended (e.g., \c .dll on Windows, + \c .so on Linux). + + The \c DESTDIR variable specifies where we want to install the + plugin. We put it in Plug & Paint's \c plugins subdirectory, + since that's where the application looks for dynamic plugins. + + The \c CONFIG() code at the end is necessary for this example + because the example is part of the Qt distribution and Qt can be + configured to be built simultaneously in debug and in release + modes. You don't need to for your own plugins. +*/ diff --git a/doc/src/examples/portedasteroids.qdoc b/doc/src/examples/portedasteroids.qdoc new file mode 100644 index 0000000..d32732f --- /dev/null +++ b/doc/src/examples/portedasteroids.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example graphicsview/portedasteroids + \title Ported Asteroids Example + + This GraphicsView example is a port of the + Asteroids game, which was based on QCanvas. + + \image portedasteroids-example.png +*/ diff --git a/doc/src/examples/portedcanvas.qdoc b/doc/src/examples/portedcanvas.qdoc new file mode 100644 index 0000000..76943df --- /dev/null +++ b/doc/src/examples/portedcanvas.qdoc @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example graphicsview/portedcanvas + \title Ported Canvas Example + + This GraphicsView example is a port of the old + QCanvas example from Qt 3. + + \sa {Porting to Graphics View} + + \image portedcanvas-example.png +*/ diff --git a/doc/src/examples/previewer.qdoc b/doc/src/examples/previewer.qdoc new file mode 100644 index 0000000..9cbeec1 --- /dev/null +++ b/doc/src/examples/previewer.qdoc @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example webkit/previewer + \title Previewer Example + + The Previewer example shows how to use QtWebKit's QWebView to preview + HTML data written in a QPlainTextEdit. + + \image previewer-example.png + + \section1 The User Interface + + Before we begin, we create a user interface using \QD. Two QGroupBox + objects - the editor group box and the previewer group box are separated + by a QSplitter. In the editor group box, we have a QPlainTextEdit object, + \c plainTextEdit, and two QPushButton objects. In the previewer group box, + we have a QWebView object, \c webView. + + \image previewer-ui.png + + \section1 Previewer Class Definition + + The \c Previewer class is a subclass of both QWidget and Ui::Form. + We subclass Ui::Form in order to embed the \QD user interface form + created earlier. This method of embedding forms is known as the + \l{The Multiple Inheritance Approach}{multiple inheritance approach}. + + In our \c previewer.h file, we have a constructor and a slot, + \c on_previewButton_clicked(). + + \snippet examples/webkit/previewer/previewer.h 0 + + \section1 Previewer Class Implementation + + The \c{Previewer}'s constructor is only responsible for setting up the + user interface. + + \snippet examples/webkit/previewer/previewer.cpp 0 + + The \c on_previewButton_clicked() is a slot corresponding to the + \c{previewButton}'s \l{QPushButton::}{clicked()} signal. When the + \c previewButton is clicked, we extract the contents of \c plainTextEdit, + and then invoke the \l{QWebView::}{setHtml()} function to display our + contents as HTML. + + \snippet examples/webkit/previewer/previewer.cpp 1 + + \section1 MainWindow Class Definition + + The \c MainWindow class for the Previewer example is a subclass of + QMainWindow with a constructor and five private slots: \c open(), + \c openUrl(), \c save(), \c about() and \c updateTextEdit(). + + \snippet examples/webkit/previewer/mainwindow.h 0 + + The private objects in \c MainWindow are \c centralWidget, which is + a \c Previewer object, \c fileMenu, \c helpMenu and the QAction objects + \c openAct, \c openUrlAct, \c saveAct, \c exitAct, \c aboutAct and + \c aboutQtAct. + + \snippet examples/webkit/previewer/mainwindow.h 1 + + There are three private functions: \c createActions(), \c createMenus() + and \c setStartupText(). The \c createActions() and \c createMenus() + functions are necessary to set up the main window's actions and + assign them to the \gui File and \gui Help menus. The \c setStartupText() + function, on the other hand, displays a description about the example + in its HTML Previewer window. + + \section1 MainWindow Class Implementation + + The \c{MainWindow}'s constructor invokes \c createActions() and + \c createMenus() to set up the \gui File menu and \gui Help menu. Then, + the \c Previewer object, \c centralWidget, is set to the main window's + central widget. Also, we connect \c webView's + \l{QWebView::}{loadFinished()} signal to our \c updateTextEdit() slot. + Finally, we call the \c setStartupText() function to display the + description of the example. + + \snippet examples/webkit/previewer/mainwindow.cpp 0 + + Within the \c createActions() function, we instantiate all our private + QAction objects which we declared in \c{mainwindow.h}. We set the + short cut and status tip for these actions and connect their + \l{QAction::}{triggered()} signal to appropriate slots. + + \snippet examples/webkit/previewer/mainwindow.cpp 1 + \dots + + The \c createMenus() function instantiates the QMenu items, \c fileMenu + and \c helpMenu and adds them to the main window's + \l{QMainWindow::menuBar()}{menu bar}. + + \snippet examples/webkit/previewer/mainwindow.cpp 2 + + The example also provides an \c about() slot to describe its purpose. + + \snippet examples/webkit/previewer/mainwindow.cpp 3 + + The \c MainWindow class provides two types of \gui Open functions: + \c open() and \c openUrl(). The \c open() function opens an HTML file + with \c fileName, and reads it with QTextStream. The function then + displays the output on \c plainTextEdit. The file's name is obtained + using QFileDialog's \l{QFileDialog::}{getOpenFileName()} function. + + \snippet examples/webkit/previewer/mainwindow.cpp 4 + + The \c openUrl() function, on the other hand, displays a QInputDialog + to obtain a URL, and displays it on \c webView. + + \snippet examples/webkit/previewer/mainwindow.cpp 5 + + In order to save a HTML file, the \c save() function first extracts the + contents of \c plainTextEdit and displays a QFileDialog to obtain + \c fileName. Then, we use a QTextStream object, \c in, to write to + \c file. + + \snippet examples/webkit/previewer/mainwindow.cpp 6 + + Earlier, in \c{MainWindow}'s constructor, we connected \c{webView}'s + \l{QWebView::}{loadFinished()} signal to our private \c updateTextEdit() + slot. This slot updates the contents of \c plainTextEdit with the HTML + source of the web page's main frame, obtained using \l{QWebFrame}'s + \l{QWebFrame::}{toHtml()} function. + + \snippet examples/webkit/previewer/mainwindow.cpp 7 + + To provide a description about the Previewer example, when it starts up, + we use the \c setStartupText() function, as shown below: + + \snippet examples/webkit/previewer/mainwindow.cpp 8 + + + \section1 The \c{main()} Function + + The \c main() function instantiates a \c MainWindow object, \c mainWindow, + and displays it with the \l{QWidget::}{show()} function. + + \snippet examples/webkit/previewer/main.cpp 0 + +*/
\ No newline at end of file diff --git a/doc/src/examples/qobjectxmlmodel.qdoc b/doc/src/examples/qobjectxmlmodel.qdoc new file mode 100644 index 0000000..ce1dab6 --- /dev/null +++ b/doc/src/examples/qobjectxmlmodel.qdoc @@ -0,0 +1,353 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/qobjectxmlmodel + \title QObject XML Model Example + + This example shows how to use QtXmlPatterns to query QObject trees + by modeling the non-XML data structure of a QObject tree to look + like XML. + + \tableofcontents + + \section1 Introduction + + This example illustrates two important points about using XQuery to + query non-XML data modeled to look like XML. The first point is that + a custom node model class doesn't always have to actually build the + node model. Sometimes the node model can be an already existing data + structure, like the QObject tree used in this example. The second + point is to explain what is required to make non-XML data look like + XML. + + In this example, we want to model a QObject tree to look like + XML. That is easy to do because a QObject tree maps to the XML tree + structure in a staightforward way. Each QObject node is modeled as + an XML element node. However, when we want to add the QMetaObject tree + to the QObject tree node model, we are trying to add a second tree to + the node model. The QMetaObject tree exists \e{behind} the QObject + tree. Adding the QMetaObject tree to the node model changes the two + dimensional tree into a three dimensional tree. + + The query engine can only traverse two dimensional trees, because an + XML document is always a two dimensional tree. If we want to add the + QMetaObject tree to the node model, we have to somehow flatten it + into the the same plane as the QObject tree. This requires that the + node model class must build an auxiliary data structure and make it + part of the two dimensional QObject node model. How to do this is + explained in \l{Including The QMetaObject Tree}. + + \section2 The User Interface + + The UI for this example was created using Qt Designer: + + \image qobjectxmlmodel-example.png + + \section1 Code Walk-Through + + The strategy for this example is different from the strategy for the + \l{File System Example}{file system example}. In the file system + example, the node model class had to actually build a node model + because the non-XML data to be traversed was the computer's file + system, a structure stored on disk in a form that the query engine + couldn't use. The node model class had to build an analog of the + computer's file system in memory. + + For this example, the data structure to be traversed already exists + in memory in a usable form. It is the QObject tree of the example + application itself. All we need is the pointer to the root of the + QObject tree. + + \note When we add the QMetaObject tree to the node model, the node + model class will have to build an auxiliary data structure to move + the QMetaObject tree into the same plane as the QObject tree. This + is explained later in \l{Including The QMetaObject Tree}. + + \section2 The Custom Node Model Class: QObjextXmlModel + + The node model class for this example is QObjextXmlModel, which is + derived from QSimpleXmlNodeModel. QObjextXmlModel implements the + callback interface functions that don't have implementations in + QSimpleXmlNodeModel: + + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.h 0 + + The node model class declares three data members: + + \target Three Data Members + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.h 2 + + The constructor sets \c m_baseURI to the QUrl constructed from the + \l{QCoreApplication::applicationFilePath()}{file path} of the + application executable. This is the value returned by + \l{QAbstractXmlNodeModel::documentUri()}{documentUri()}. The + constructor sets \c{m_root} to point to the QObject tree for the + example application. This is the node model that the query engine + will use. And the constructor calls a local function to build the + auxiliary data structure (\c{m_allMetaObjects}) for including the + QMetaObject tree in the node model. How this auxiliary data + structure is incorporated into the QObject node model is discussed + in \l{Including The QMetaObject Tree}. + + \section3 Accessing The Node Model + + Since the query engine knows nothing about QObject trees, it can + only access them by calling functions in the node model callback + interface. The query engine passes a QXmlNodeModelIndex to uniquely + identify a node in the node model. The QXmlNodeModelIndex is + constructed from a pointer to the QObject that represents the node. + \l{QAbstractXmlNodeModel::createIndex()}{createIndex()} creates the + QXmlNodeModelIndex, as in the local \c{root()} function, for example: + + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 0 + + A QObject represents an element node in the node model, but we also + need to represent attribute nodes. For example, the class name of a + QObject is an attribute of the QObject, so it should be an attribute + node in the node model. A QObject's class name is obtained from the + QObject. (Actually, it is in the QMetaObject, which is obtained from + the QObject). This means that a single QObject logically represents + multiple nodes in the node model: the element node and potentially + many attribute nodes. + + To uniquely identify an attribute node, we need the pointer to the + QObject containing the attribute, and an additional value that + identifies the attribute in the QObject. For this \e{additional + data} value, we use \c{enum QObjectNodeType}: + + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.h 3 + + Ignore the \c{MetaObjectXXX} values for now. They will be explained + in \l{Including The QMetaObject Tree}. Here we are interested in the + three node types for QObject nodes: \c{IsQObject}, which represents + the element node type for a QObject, and \c{QObjectProperty} and + \c{QObjectClassName}, which represent the attribute node types for + the attributes of a QObject. + + The \l{QAbstractXmlNodeModel::createIndex()}{createIndex()} + function called in the \c{root()} snippet above is the overload that + accepts a \c{void*} pointer and a second parameter, + \c{additionalData}, with default value 0 (\c{IsQObject}). Wherever + you see a call to \l{QAbstractXmlNodeModel::createIndex()} + {createIndex()} that only passes the QObject pointer, it is creating + the node index for a QObject element node. To create the node index + for the class name attribute, for example, the \l{QObject + attributes} {attributes()} function uses + \c{createIndex(object,QObjectClassName)}. + + \target QObject attributes + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 6 + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 8 + + \l{QObject attributes} {attributes()} is one of the callback + functions you have to implement in your custom node model class. It + returns a QVector of \l{QXmlNodeModelIndex} {node indexes} for all + the attribute nodes for QObject \c{n}. It calls + \l{QAbstractXmlNodeModel::createIndex()} {createIndex()} in two places. + Both calls use the QObject pointer from the current node \c{n} (the + element node), and just add a different value for the \e{additional data} + parameter. This makes sense because, in XML, the attributes of an + element are part of that element. + + \section3 Traversing The Node Model + + The query engine traverses the QObject tree by calling back to the + node model class's implementation of \l{QObject nextFromSimpleAxis} + {nextFromSimpleAxis()}. This function is the heart of the callback + interface, and it will probably be the most complex to implement in + your custom node model class. Below is a partial listing of the + implementation for this example. The full listing will be shown in + \l{Including The QMetaObject Tree}, where we discuss traversing the + QMetaObject tree. + + \target QObject nextFromSimpleAxis + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 2 + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 4 + + The main switch uses \c toNodeType(), which obtains the node + type from \l{QXmlNodeModelIndex::additionalData()}: + + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 1 + + \c{case IsObject} case is the most interesting. It switches again on + the value of the \c{axis} parameter, which specifies the direction + the query engine wants to take from the current node. It is one of + the four enum values of \l{QAbstractXmlNodeModel::SimpleAxis}. The + \l{QAbstractXmlNodeModel::Parent} {Parent} and + \l{QAbstractXmlNodeModel::FirstChild} {FirstChild} cases reduce to + calls to QObject::parent() and QObject::children() + respectively. Note that a default constructed QXmlNodeModelIndex is + returned in the \l{QAbstractXmlNodeModel::Parent} {Parent} case if + the current node is the root, and in the + \l{QAbstractXmlNodeModel::FirstChild} {FirstChild} case if the + current node has no children. + + For the \l{QAbstractXmlNodeModel::NextSibling} {NextSibling} and + \l{QAbstractXmlNodeModel::PreviousSibling} {PreviousSibling} axes, + the helper function \c{qObjectSibling()} is called, with +1 to + traverse to the \l{QAbstractXmlNodeModel::NextSibling} {NextSibling} + and -1 to traverse to the + \l{QAbstractXmlNodeModel::PreviousSibling} {PreviousSibling}. + + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 5 + + \c{qObjectSibling()} determines whether or not the node has any + siblings. It is called with \c{n}, the index of the current node. + If the current node is a child, then it has a parent with children + (the current node one of these). + So, we get the \l{QObject::parent()}{parent}, obtain the parent's + \l{QObject::children()} {child list}, find the current node in the + list, and construct the node index for the next or previous child + (sibling) and return it. + + \note In \l{QObject nextFromSimpleAxis} {nextFromSimpleAxis()}, the + special case of asking for the + \l{QAbstractXmlNodeModel::PreviousSibling} {PreviousSibling} of the + root node is discussed in \l{Including The QMetaObject Tree}. + + Traversing away from a \c{QObjectClassName} attribute node or a + \c{QObjectProperty} attribute node might seem a bit confusing at + first glance. The only move allowed from an attribute node is to the + \l{QAbstractXmlNodeModel::Parent} {Parent}, because attribute nodes + don't have children. But these two cases simply return the + \l{QXmlNodeModelIndex} {node index} of the current node. + + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 7 + + Since \c n is the QXmlNodeModelIndex of the current node, all this + does is create another QXmlNodeModelIndex for the current node and + return it. This was explained above in \l{Accessing The Node Model}, + where we saw that each QObject in the node model actually represents + an element node and potentially many attribute nodes. Traversing to + the parent node of an attribute simply creates a node index for the + same QObject, but with an \e{additional data} value of 0 + (\c{IsQObject}). + + If we only wanted to traverse the QObject tree with XQuery, we could + just implement the rest of the virtual callback functions listed + earlier and we would be done. The implementations for the remaining + functions are straightforward. But if we also want to use XQuery to + traverse the QMetaObject tree, we must include the QMetaObject tree + in the custom node model. + + \section3 Including The QMetaObject Tree + + The \l{Meta-Object System} {metaobject system} not only enables Qt's + \l{Signals and Slots} {signals and slots}, it also provides type + information that is useful at run-time; e.g., getting and setting + properties without knowing the property names at compile time. Each + QObject has an associated QMetaObject tree which contains all this + useful type information. Given a QObject, its QMetaObject is + obtained with QObject::metaObject(). Then QMetaObject::superClass() + can be called repeatedly to get the QMetaObject for each class in the + class hierarchy for the original QObject. + + However, the QMetaObject hierarchy is a second tree in a plan that + exists logically behind the plane of the QObject tree. The QtXmlPatterns + query engine can only traverse a two dimensional node model that + represents an XML tree. If we want to include the QMetaObject in the + same node model that represents the QObject tree, we must find a way + to flatten the QMetaObject tree into the same plane as the QObject + tree. + + The node model class declares \l{All MetaObjects}{m_allMetaObjects} + as a vector of pointers to QMetaObject: + + \target All MetaObjects + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.h 1 + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.h 4 + + This vector gets populated by the QObjectXmlModel constructor by + calling the private allMetaObjects() function: + + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 9 + + The first half of the function is an example of the standard code + pattern for using QtXmlPatterns to run an XQuery. First it creates an + instance of QXmlQuery. Then it \l{QXmlQuery::bindVariable()}{binds} + the XQuery variable \c{$root} to the root node of the of the node + model; i.e., the root of the QObject tree. Then it + \l{QXmlQuery::setQuery()} {sets the query} to be an XQuery that + returns all the QObjects in the node model. Finally, the query is + evaluated into a \l{QXmlResultItems} {result item list}. + + \note \l{QXmlQuery::bindVariable()} must be called before + \l{QXmlQuery::setQuery()}, because setting the query causes + QtXmlPatterns to \e compile the XQuery, which requires knowledge of + the variable bindings. + + The second half of the function traverses the \l{QXmlResultItems} + {result item list}, getting the QMetaObject hierarchy for each + QObject and appending it to \l{All MetaObjects} {m_allMetaObjects}, + if it isn't already there. But how do we include this vector of + pointers to QMetaObjects in the node model? The key insight is + shown in the full listing of \l{Full Listing of nextFromSimpleAxis} + {nextFromSimpleAxis()}, where we are interested now in the + \c{MetaObjectXXX} cases: + + \target Full Listing of nextFromSimpleAxis + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 2 + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 3 + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 4 + + But first, revisit the \c{PreviousSibling} case for the + \c{IsQObject} case: + + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 10 + + When asking for the previous sibling of the root of the QObject + tree, it creates a node model index with a null QObject pointer and + an \c{additionalData} value of \c{MetaObjects}. This effectively + allows the query engine to jump from the QObject tree to the + QMetaObject tree. + + The query engine can jump from the QMetaObject tree back to the + QObject tree in the \c{NextSibling} case of case \c{MetaObjects}, + where the \c{root()} function is called: + + \snippet examples/xmlpatterns/qobjectxmlmodel/qobjectxmlmodel.cpp 11 + + Having jumped from the QObject tree to the QMetaObject tree, the + query engine will use the \c{MetaObject}, \c{MetaObjectClassName}, + and \c{MetaObjectSuperClass} cases, which are similar to the cases + for \c{IsQObject}, \c{QObjectProperty}, and \c{QObjectClassName}. +*/ diff --git a/doc/src/examples/qtconcurrent-imagescaling.qdoc b/doc/src/examples/qtconcurrent-imagescaling.qdoc new file mode 100644 index 0000000..74b4be0 --- /dev/null +++ b/doc/src/examples/qtconcurrent-imagescaling.qdoc @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example qtconcurrent/imagescaling + \title QtConcurrent Image Scaling Example + + The QtConcurrent Map example shows how to use the asynchronous + QtConcurrent API to load and scale a collection of images. +*/ diff --git a/doc/src/examples/qtconcurrent-map.qdoc b/doc/src/examples/qtconcurrent-map.qdoc new file mode 100644 index 0000000..9f5295d --- /dev/null +++ b/doc/src/examples/qtconcurrent-map.qdoc @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example qtconcurrent/map + \title QtConcurrent Map Example + + The QtConcurrent Map example shows how to use the synchronous (blocking) + QtConcurrent API to scale a collection of images. +*/ diff --git a/doc/src/examples/qtconcurrent-progressdialog.qdoc b/doc/src/examples/qtconcurrent-progressdialog.qdoc new file mode 100644 index 0000000..41909fb --- /dev/null +++ b/doc/src/examples/qtconcurrent-progressdialog.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example qtconcurrent/progressdialog + \title QtConcurrent Progress Dialog Example + + The QtConcurrent Progress Dialog example shows how to use the + QFutureWatcher class to monitor the progress of a long-running operation. + + \image qtconcurrent-progressdialog.png +*/ diff --git a/doc/src/examples/qtconcurrent-runfunction.qdoc b/doc/src/examples/qtconcurrent-runfunction.qdoc new file mode 100644 index 0000000..5c40552 --- /dev/null +++ b/doc/src/examples/qtconcurrent-runfunction.qdoc @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example qtconcurrent/runfunction + \title QtConcurrent Run Function Example + + The QtConcurrent Run Function example shows how to apply concurrency to + a standard function, using QFuture instances to retrieve return values + at a later time. +*/ diff --git a/doc/src/examples/qtconcurrent-wordcount.qdoc b/doc/src/examples/qtconcurrent-wordcount.qdoc new file mode 100644 index 0000000..d7d3227 --- /dev/null +++ b/doc/src/examples/qtconcurrent-wordcount.qdoc @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example qtconcurrent/wordcount + \title QtConcurrent Word Count Example + + The QtConcurrent Word Count example demonstrates the use of the map-reduce + algorithm when applied to the problem of counting words in a collection + of files. +*/ diff --git a/doc/src/examples/qtscriptcalculator.qdoc b/doc/src/examples/qtscriptcalculator.qdoc new file mode 100644 index 0000000..1d713f8 --- /dev/null +++ b/doc/src/examples/qtscriptcalculator.qdoc @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example script/calculator + \title QtScript Calculator Example + \ingroup scripting + + In this simple QtScript example, we show how to implement the + functionality of a calculator widget. + + \image qtscript-calculator-example.png + + The program logic in this example is a fairly straight port of the logic in the C++ \l{Calculator Example}. + The graphical user interface is defined in a UI file. + + The C++ part of the example consists of four steps: + \list + \o Evaluate the script code that defines the \c{Calculator} class. + + \snippet examples/script/calculator/main.cpp 0a + \snippet examples/script/calculator/main.cpp 0b + + \o Create a widget from the UI file using QUiLoader. + + \snippet examples/script/calculator/main.cpp 1 + + \o Call the Calculator constructor function to create a new \c{Calculator} script object, passing the widget as argument. + + \snippet examples/script/calculator/main.cpp 2 + + \o Show the widget and start the application event loop. + + \snippet examples/script/calculator/main.cpp 3 + + \endlist + + On the script side, the \c{Calculator} constructor function + initializes the instance variables of the new \c{Calculator} + object, and connects the clicked() signal of the form's buttons + to corresponding functions defined in the \c{Calculator} prototype + object; the effect is that when a button is clicked, the proper + script function will be invoked to carry out the operation. + + \snippet examples/script/calculator/calculator.js 0 + + A \c{Calculator} object is just a plain script object; it is not + a widget. Instead, it stores a reference to the calculator form + (the widget) in an instance variable, \c{ui}. The calculator + script functions can access components of the form by referring + to the proper children of the \c{ui} member. + + \snippet examples/script/calculator/calculator.js 1 + + The digitClicked() function uses the special local variable + __qt_sender__ to access the object that triggered the signal; + this gives us a simple way to retrieve the value of the digit + that was clicked. + + \snippet examples/script/calculator/calculator.js 2 + + The changeSign() function shows how we retrieve the text property + of the calculator's display, change it appropriately, and write + back the new value. + + +*/ diff --git a/doc/src/examples/qtscriptcustomclass.qdoc b/doc/src/examples/qtscriptcustomclass.qdoc new file mode 100644 index 0000000..f8d85a2 --- /dev/null +++ b/doc/src/examples/qtscriptcustomclass.qdoc @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example script/customclass + \title Custom Script Class Example + + The Custom Script Class example shows how to use QScriptClass and QScriptClassPropertyIterator + to implement a custom script class. + + The script class we are going to implement is called \c{ByteArray}. It provides a wrapper around + the QByteArray class in Qt, with a simplified API. Why do we need such a class? Well, neither the + ECMAScript \c{Array} class or \c{String} class is appropriate to use when working with arrays of + bytes. Our \c{ByteArray} class will have the right semantics; objects will use only the amount of + memory that is really needed (a byte is stored as a byte, not as a floating-point number or a + Unicode character) and can be passed directly to C++ slots taking QByteArray arguments (no costly + conversion necessary). + + \section1 ByteArray Class In Use + + When the \c{ByteArray} class has been made available to the + scripting environment, \c{ByteArray} objects can be constructed like + so: + + \snippet doc/src/snippets/code/doc_src_examples_qtscriptcustomclass.qdoc 0 + + \c{ByteArray} objects behave similar to normal \c{Array} objects. Every \c{ByteArray} object has + a \c{length} property, that holds the length of the array. If a new value is assigned to the \c{length} + property, the array is resized. If the array is enlarged, the new bytes are initialized to 0. + (This is a difference from normal \c{Array} objects; \c{ByteArray} objects are always dense arrays.) + Use normal array operations to read or write bytes in the array. The following code sets all the + bytes of an array to a certain value: + + \snippet doc/src/snippets/code/doc_src_examples_qtscriptcustomclass.qdoc 1 + + When assigning a value to an array element, the value is truncated to eight bits: + + \snippet doc/src/snippets/code/doc_src_examples_qtscriptcustomclass.qdoc 2 + + Like normal \c{Array} objects, if the array index is greater than the current length + of the array, the array is resized accordingly: + + \snippet doc/src/snippets/code/doc_src_examples_qtscriptcustomclass.qdoc 3 + + Property names that aren't valid array indexes are treated + like normal object properties (again, the same is the case for normal \c{Array} objects); + in other words, it's perfectly fine to do something like this: + + \snippet doc/src/snippets/code/doc_src_examples_qtscriptcustomclass.qdoc 4 + + The above assignment won't affect the contents of the array, but will rather assign a value + to the object property named "foo". + + \c{ByteArray} objects have a set of methods: chop(), equals(), left(), mid(), toBase64() and so on. + These map directly onto the corresponding methods in QByteArray. + + \snippet doc/src/snippets/code/doc_src_examples_qtscriptcustomclass.qdoc 5 + + \section1 ByteArray Class Implementation + + To implement the \c{ByteArray} script class in C++, we create a subclass of QScriptClass, + called ByteArrayClass, and reimplement the virtual functions from QScriptClass. We also provide + a Qt Script constructor function suitable for being added to a QScriptEngine's environment. + + The ByteArrayClass constructor prepares the script class: + + \snippet examples/script/customclass/bytearrayclass.cpp 0 + + First, the constructor registers a pair of conversion functions, so that C++ QByteArray objects + and Qt Script \c{ByteArray} objects can move seamlessly between the C++ side and the script side. + For example, if a \c{ByteArray} object is passed to a C++ slot that takes a QByteArray + argument, the actual QByteArray that the \c{ByteArray} object wraps will be passed correctly. + + Second, we store a handle to the string "length", so that we can quickly compare a given property name + to "length" later on. + + Third, we initialize the standard \c{ByteArray} prototype, to be returned by our prototype() + reimplementation later on. (The implementation of the prototype is discussed later.) + + Fourth, we initialize a constructor function for \c{ByteArray}, to be returned by the + constructor() function. We set the internal data of the constructor to be a pointer to + this ByteArrayClass object, so that the constructor, when it is invoked, can extract the + pointer and use it to create a new \c{ByteArray} object. + + \snippet examples/script/customclass/bytearrayclass.cpp 1 + + The newInstance() function isn't part of the QScriptClass API; its purpose is to offer + a convenient way to construct a \c{ByteArray} object from an existing QByteArray. We store the + QByteArray as the internal data of the new object, and return the new object. + QScriptEngine::newObject() will call the prototype() function of our class, ensuring that + the prototype of the new object will be the standard \c{ByteArray} prototype. + + \snippet examples/script/customclass/bytearrayclass.cpp 2 + + construct() is the native function that will act as a constructor for \c{ByteArray} + in scripts. We extract the pointer to the class, then call a newInstance() overload + that takes an initial size as argument, and return the new script object. + + \snippet examples/script/customclass/bytearrayclass.cpp 3 + + queryProperty() is the function that Qt Script will call whenever someone tries to access + a property of a \c{ByteArray} object. We first get a pointer to the underlying QByteArray. + We check if the property being accessed is the special \c{length} property; if so, we + return, indicating that we will handle every kind of access to this property (e.g. both + read and write). Otherwise, we attempt to convert the property name to an array index. If + this fails, we return, indicating that we don't want to handle this property. Otherwise, we + have a valid array index, and store it in the \c{id} argument, so that we don't have to + recompute it in e.g. property() or setProperty(). If the index is greater than or equal to + the QByteArray's size, we indicate that we don't want to handle read access (but we still want + to handle writes, if requested). + + \snippet examples/script/customclass/bytearrayclass.cpp 4 + + In the property() reimplementation, we do similar checks as in queryProperty() to find out + which property is being requested, and then return the value of that property. + + \snippet examples/script/customclass/bytearrayclass.cpp 5 + + The setProperty() reimplementation has a structure that is similar to property(). If the \c{length} property + is being set, we resize the underlying QByteArray to the given length. Otherwise, we grab the + array index that was calculated in the queryProperty() function, enlarge the array if necessary, + and write the given value to the array. + + \snippet examples/script/customclass/bytearrayclass.cpp 6 + + The propertyFlags() reimplementation specifies that the \c{length} property can't be deleted, + and that it is not enumerable. Array elements can't be deleted. + + \snippet examples/script/customclass/bytearrayclass.cpp 7 + + We want the array elements to show up when a \c{ByteArray} object is used in for-in + statements and together with QScriptValueIterator. Therefore, we reimplement the + newIterator() function and have it return a new iterator for a given \c{ByteArray}. + + \section1 ByteArray Iterator Implementation + + \snippet examples/script/customclass/bytearrayclass.cpp 8 + + The \c{ByteArrayClassPropertyIterator} class is simple. It maintains an index into the + underlying QByteArray, and checks and updates the index in hasNext(), next() and so on. + + \section1 ByteArray Prototype Implementation + + The prototype class, ByteArrayPrototype, implements the \c{ByteArray} functions as slots. + + \snippet examples/script/customclass/bytearrayprototype.h 0 + + There is a small helper function, thisByteArray(), that returns a pointer to the QByteArray + being operated upon: + + \snippet examples/script/customclass/bytearrayprototype.cpp 0 + + The slots simply forward the calls to the QByteArray. Examples: + + \snippet examples/script/customclass/bytearrayprototype.cpp 1 + + The remove() function is noteworthy; if we look at QByteArray::remove(), we see that it + should return a reference to the QByteArray itself (i.e. not a copy). To get the same + behavior in scripts, we return the script object (thisObject()). +*/ diff --git a/doc/src/examples/qtscripttetrix.qdoc b/doc/src/examples/qtscripttetrix.qdoc new file mode 100644 index 0000000..c96db6a --- /dev/null +++ b/doc/src/examples/qtscripttetrix.qdoc @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example script/qstetrix + \title Qt Script Tetrix Example + + The QSTetrix example is a Qt Script version of the classic Tetrix game. + + \image tetrix-example.png + + \section1 Overview + + The program logic in this example is a fairly straight port of the + logic in the C++ \l{Tetrix Example}. You may find it useful to compare + the implementations of the \c TetrixBoard, \c TetrixPiece and + \c TetrixWindow classes to see how Qt Script is used to implement + methods, call Qt functions, and emit signals. + + \section1 Setting up the GUI + + The graphical user interface is defined in a \c{.ui} file, creating + using Qt Designer, and is set up in the example's C++ \c{main.cpp} file. + + \snippet examples/script/qstetrix/main.cpp 0 + + We define a custom UI loader that handles our \c TetrixBoard widget; this + is the main component of the UI (where the pieces are drawn). + + \snippet examples/script/qstetrix/main.cpp 1 + + We initialize the script engine to have the Qt namespace, so that + e.g., \l{Qt::Key_Left}{Qt.Key_Left} will be available to script code. + We also make the application object available (for the + \l{QApplication::}{quit()} slot). + + \snippet examples/script/qstetrix/main.cpp 2 + + Several scripts are evaluated as part of the engine setup process. + The \c{tetrixpiece.js} file contains the definition of the \c TetrixPiece + class, which is used to populate the play field. The \c{tetrixboard.js} + file contains the definition of the \c TetrixBoard class, which contains + the main game logic. Finally, \c{tetrixwindow.js} contains the definition + of the \c TetrixWindow class, which wires up the top-level widget. + + \snippet examples/script/qstetrix/main.cpp 3 + + A form is created from the UI file. A new \c TetrixWindow script object + is then constructed, passing the form as its argument. + + \snippet examples/script/qstetrix/main.cpp 4 + + The form is shown, and the event loop is entered. +*/ diff --git a/doc/src/examples/querymodel.qdoc b/doc/src/examples/querymodel.qdoc new file mode 100644 index 0000000..296f609 --- /dev/null +++ b/doc/src/examples/querymodel.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example sql/querymodel + \title Query Model Example + + The Query Model example shows how to make customized versions of + data obtained from a SQL query, using a model that encapsulates + the query and table views to display the results. + + \image querymodel-example.png +*/ diff --git a/doc/src/examples/queuedcustomtype.qdoc b/doc/src/examples/queuedcustomtype.qdoc new file mode 100644 index 0000000..bbd1427 --- /dev/null +++ b/doc/src/examples/queuedcustomtype.qdoc @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example threads/queuedcustomtype + \title Queued Custom Type Example + + The Queued Custom Type example shows how to send custom types between + threads with queued signals and slots. + + \image queuedcustomtype-example.png + + Contents: + + \tableofcontents + + \section1 Overview + + In the \l{Custom Type Sending Example}, we showed how to use a custom type + with signal-slot communication within the same thread. + + In this example, we create a new value class, \c Block, and register it + with the meta-object system to enable us to send instances of it between + threads using queued signals and slots. + + \section1 The Block Class + + The \c Block class is similar to the \c Message class described in the + \l{Custom Type Example}. It provides the default constructor, copy + constructor and destructor in the public section of the class that the + meta-object system requires. It describes a colored rectangle. + + \snippet examples/threads/queuedcustomtype/block.h custom type definition and meta-type declaration + + We will still need to register it with the meta-object system at + run-time by calling the qRegisterMetaType() template function before + we make any signal-slot connections that use this type. + Even though we do not intend to use the type with QVariant in this example, + it is good practice to also declare the new type with Q_DECLARE_METATYPE(). + + The implementation of the \c Block class is trivial, so we avoid quoting + it here. + + \section1 The Window Class + + We define a simple \c Window class with a public slot that accepts a + \c Block object. The rest of the class is concerned with managing the + user interface and handling images. + + \snippet examples/threads/queuedcustomtype/window.h Window class definition + + The \c Window class also contains a worker thread, provided by a + \c RenderThread object. This will emit signals to send \c Block objects + to the window's \c addBlock(Block) slot. + + The parts of the \c Window class that are most relevant are the constructor + and the \c addBlock(Block) slot. + + The constructor creates a thread for rendering images, sets up a user + interface containing a label and two push buttons that are connected to + slots in the same class. + + \snippet examples/threads/queuedcustomtype/window.cpp Window constructor start + \snippet examples/threads/queuedcustomtype/window.cpp set up widgets and connections + \snippet examples/threads/queuedcustomtype/window.cpp connecting signal with custom type + + In the last of these connections, we connect a signal in the + \c RenderThread object to the \c addBlock(Block) slot in the window. + + \dots + \snippet examples/threads/queuedcustomtype/window.cpp Window constructor finish + + The rest of the constructor simply sets up the layout of the window. + + The \c addBlock(Block) slot receives blocks from the rendering thread via + the signal-slot connection set up in the constructor: + + \snippet examples/threads/queuedcustomtype/window.cpp Adding blocks to the display + + We simply paint these onto the label as they arrive. + + \section1 The RenderThread Class + + The \c RenderThread class processes an image, creating \c Block objects + and using the \c sendBlock(Block) signal to send them to other components + in the example. + + \snippet examples/threads/queuedcustomtype/renderthread.h RenderThread class definition + + The constructor and destructor are not quoted here. These take care of + setting up the thread's internal state and cleaning up when it is destroyed. + + Processing is started with the \c processImage() function, which calls the + \c RenderThread class's reimplementation of the QThread::run() function: + + \snippet examples/threads/queuedcustomtype/renderthread.cpp processing the image (start) + + Ignoring the details of the way the image is processed, we see that the + signal containing a block is emitted in the usual way: + + \dots + \snippet examples/threads/queuedcustomtype/renderthread.cpp processing the image (finish) + + Each signal that is emitted will be queued and delivered later to the + window's \c addBlock(Block) slot. + + \section1 Registering the Type + + In the example's \c{main()} function, we perform the registration of the + \c Block class as a custom type with the meta-object system by calling the + qRegisterMetaType() template function: + + \snippet examples/threads/queuedcustomtype/main.cpp main function + + This call is placed here to ensure that the type is registered before any + signal-slot connections are made that use it. + + The rest of the \c{main()} function is concerned with setting a seed for + the pseudo-random number generator, creating and showing the window, and + setting a default image. See the source code for the implementation of the + \c createImage() function. + + \section1 Further Reading + + This example showed how a custom type can be registered with the + meta-object system so that it can be used with signal-slot connections + between threads. For ordinary communication involving direct signals and + slots, it is enough to simply declare the type in the way described in the + \l{Custom Type Sending Example}. + + In practice, both the Q_DECLARE_METATYPE() macro and the qRegisterMetaType() + template function can be used to register custom types, but + qRegisterMetaType() is only required if you need to perform signal-slot + communication or need to create and destroy objects of the custom type + at run-time. + + More information on using custom types with Qt can be found in the + \l{Creating Custom Qt Types} document. +*/ diff --git a/doc/src/examples/qxmlstreambookmarks.qdoc b/doc/src/examples/qxmlstreambookmarks.qdoc new file mode 100644 index 0000000..7059043 --- /dev/null +++ b/doc/src/examples/qxmlstreambookmarks.qdoc @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xml/streambookmarks + \title QXmlStream Bookmarks Example + + The QXmlStream Bookmarks example provides a reader for XML Bookmark + Exchange Language (XBEL) files using Qt's QXmlStreamReader class + for reading, and QXmlStreamWriter class for writing the files. + + \image xmlstreamexample-screenshot.png + + \section1 XbelWriter Class Definition + + The \c XbelWriter class is a subclass of QXmlStreamReader, which provides + an XML parser with a streaming API. \c XbelWriter also contains a private + instance of QTreeWidget in order to display the bookmarks according to + hierarchies. + + \snippet examples/xml/streambookmarks/xbelwriter.h 0 + + \section1 XbelWriter Class Implementation + + The \c XbelWriter constructor accepts a \a treeWidget to initialize within + its definition. We enable \l{QXmlStreamWriter}'s auto-formatting property + to ensure line-breaks and indentations are added automatically to empty + sections between elements, increasing readability as the data is split into + several lines. + + \snippet examples/xml/streambookmarks/xbelwriter.cpp 0 + + The \c writeFile() function accepts a QIODevice object and sets it using + \c setDevice(). This function then writes the document type + definition(DTD), the start element, the version, and \c{treeWidget}'s + top-level items. + + \snippet examples/xml/streambookmarks/xbelwriter.cpp 1 + + The \c writeItem() function accepts a QTreeWidget object and writes it + to the stream, depending on its \c tagName, which can either be a "folder", + "bookmark", or "separator". + + \snippet examples/xml/streambookmarks/xbelwriter.cpp 2 + + \section1 XbelReader Class Definition + + The \c XbelReader class is a subclass of QXmlStreamReader, the pendent + class for QXmlStreamWriter. \c XbelReader contains a private instance + of QTreeWidget to group bookmarks according to their hierarchies. + + \snippet examples/xml/streambookmarks/xbelreader.h 0 + + \section1 XbelReader Class Implementation + + The \c XbelReader constructor accepts a QTreeWidget to initialize the + \c treeWidget within its definition. A QStyle object is used to set + \c{treeWidget}'s style property. The \c folderIcon is set to QIcon::Normal + mode where the pixmap is only displayed when the user is not interacting + with the icon. The QStyle::SP_DirClosedIcon, QStyle::SP_DirOpenIcon, and + QStyle::SP_FileIcon correspond to standard pixmaps that follow the style + of your GUI. + + \snippet examples/xml/streambookmarks/xbelreader.cpp 0 + + The \c read() function accepts a QIODevice and sets it using + \l{QXmlStreamReader::setDevice()}{setDevice()}. The actual process + of reading only takes place in event the file is a valid XBEL 1.0 + file. Otherwise, the \l{QXmlStreamReader::raiseError()} + {raiseError()} function is used to display an error message. + + \snippet examples/xml/streambookmarks/xbelreader.cpp 1 + + The \c readUnknownElement() function reads an unknown element. The + Q_ASSERT() macro is used to provide a pre-condition for the function. + + \snippet examples/xml/streambookmarks/xbelreader.cpp 2 + + The \c readXBEL() function reads the name of a startElement and calls + the appropriate function to read it, depending on whether if its a + "folder", "bookmark" or "separator". Otherwise, it calls + \c readUnknownElement(). + + \snippet examples/xml/streambookmarks/xbelreader.cpp 3 + + The \c readTitle() function reads the bookmark's title. + + \snippet examples/xml/streambookmarks/xbelreader.cpp 4 + + The \c readSeparator() function creates a separator and sets its flags. + The text is set to 30 "0xB7", the HEX equivalent for period, and then + read using \c readElementText(). + + \snippet examples/xml/streambookmarks/xbelreader.cpp 5 + + \section1 MainWindow Class Definition + + The \c MainWindow class is a subclass of QMainWindow, with a + \c File menu and a \c Help menu. + + \snippet examples/xml/streambookmarks/mainwindow.h 0 + + \section1 MainWindow Class Implementation + + The \c MainWindow constructor instantiates the QTreeWidget object, \c + treeWidget and sets its header with a QStringList object, \c labels. + The constructor also invokes \c createActions() and \c createMenus() + to set up the menus and their corresponding actions. The \c statusBar() + is used to display the message "Ready" and the window's size is fixed + to 480x320 pixels. + + \snippet examples/xml/streambookmarks/mainwindow.cpp 0 + + The \c open() function enables the user to open an XBEL file using + QFileDialog::getOpenFileName(). A warning message is displayed along + with the \c fileName and \c errorString if the file cannot be read or + if there is a parse error. + + \snippet examples/xml/streambookmarks/mainwindow.cpp 1 + + The \c saveAs() function displays a QFileDialog, prompting the user for + a \c fileName using QFileDialog::getSaveFileName(). Similar to the + \c open() function, this function also displays a warning message if + the file cannot be written to. + + \snippet examples/xml/streambookmarks/mainwindow.cpp 2 + + The \c about() function displays a QMessageBox with a brief description + of the example. + + \snippet examples/xml/streambookmarks/mainwindow.cpp 3 + + In order to implement the \c open(), \c saveAs(), \c exit(), \c about() + and \c aboutQt() functions, we connect them to QAction objects and + add them to the \c fileMenu and \c helpMenu. The connections are as shown + below: + + \snippet examples/xml/streambookmarks/mainwindow.cpp 4 + + The \c createMenus() function creates the \c fileMenu and \c helpMenu + and adds the QAction objects to them in order to create the menu shown + in the screenshot below: + + \table + \row + \o \inlineimage xmlstreamexample-filemenu.png + \o \inlineimage xmlstreamexample-helpmenu.png + \endtable + + \snippet examples/xml/streambookmarks/mainwindow.cpp 5 + + \section1 \c{main()} Function + + The \c main() function instantiates \c MainWindow and invokes the \c show() + function. + + \snippet examples/xml/streambookmarks/main.cpp 0 + + See the \l{http://pyxml.sourceforge.net/topics/xbel/} + {XML Bookmark Exchange Language Resource Page} for more information + about XBEL files. +*/ diff --git a/doc/src/examples/recentfiles.qdoc b/doc/src/examples/recentfiles.qdoc new file mode 100644 index 0000000..185cbf1 --- /dev/null +++ b/doc/src/examples/recentfiles.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example mainwindows/recentfiles + \title Recent Files Example + + The Recent Files example shows how a standard File menu can be extended to show + the most recent files loaded by a main window application. + + \image recentfiles-example.png +*/ diff --git a/doc/src/examples/recipes.qdoc b/doc/src/examples/recipes.qdoc new file mode 100644 index 0000000..ba06b7e --- /dev/null +++ b/doc/src/examples/recipes.qdoc @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/recipes + \title Recipes Example + + The recipes example shows how to use QtXmlPatterns to query XML data + loaded from a file. + + \tableofcontents + + \section1 Introduction + + In this case, the XML data represents a cookbook, \c{cookbook.xml}, + which contains \c{<cookbook>} as its document element, which in turn + contains a sequence of \c{<recipe>} elements. This XML data is + searched using queries stored in XQuery files (\c{*.xq}). + + \section2 The User Interface + + The UI for this example was created using \l{Qt Designer Manual} {Qt + Designer}: + + \image recipes-example.png + + The UI consists of three \l{QGroupBox} {group boxes} arranged + vertically. The top one contains a \l{QTextEdit} {text viewer} that + displays the XML text from the cookbook file. The middle group box + contains a \l{QComboBox} {combo box} for choosing the \l{A Short + Path to XQuery} {XQuery} to run and a \l{QTextEdit} {text viewer} + for displaying the text of the selected XQuery. The \c{.xq} files in + the file list above are shown in the combo box menu. Choosing an + XQuery loads, parses, and runs the selected XQuery. The query result + is shown in the bottom group box's \l{QTextEdit} {text viewer}. + + \section2 Running your own XQueries + + You can write your own XQuery files and run them in the example + program. The file \c{xmlpatterns/recipes/recipes.qrc} is the \l{The + Qt Resource System} {resource file} for this example. It is used in + \c{main.cpp} (\c{Q_INIT_RESOURCE(recipes);}). It lists the XQuery + files (\c{.xq}) that can be selected in the combobox. + + \quotefromfile examples/xmlpatterns/recipes/recipes.qrc + \printuntil + + To add your own queries to the example's combobox, store your + \c{.xq} files in the \c{examples/xmlpatterns/recipes/files} + directory and add them to \c{recipes.qrc} as shown above. + + \section1 Code Walk-Through + + The example's main() function creates the standard instance of + QApplication. Then it creates an instance of the UI class, shows it, + and starts the Qt event loop: + + \snippet examples/xmlpatterns/recipes/main.cpp 0 + + \section2 The UI Class: QueryMainWindow + + The example's UI is a conventional Qt GUI application inheriting + QMainWindow and the class generated by \l{Qt Designer Manual} {Qt + Designer}: + + \snippet examples/xmlpatterns/recipes/querymainwindow.h 0 + + The constructor finds the window's \l{QComboBox} {combo box} child + widget and connects its \l{QComboBox::currentIndexChanged()} + {currentIndexChanged()} signal to the window's \c{displayQuery()} + slot. It then calls \c{loadInputFile()} to load \c{cookbook.xml} and + display its contents in the top group box's \l{QTextEdit} {text + viewer} . Finally, it finds the XQuery files (\c{.xq}) and adds each + one to the \l{QComboBox} {combo box} menu. + + \snippet examples/xmlpatterns/recipes/querymainwindow.cpp 0 + + The work is done in the \l{displayQuery() slot} {displayQuery()} + slot and the \l{evaluate() function} {evaluate()} function it + calls. \l{displayQuery() slot} {displayQuery()} loads and displays + the selected query file and passes the XQuery text to \l{evaluate() + function} {evaluate()}. + + \target displayQuery() slot + \snippet examples/xmlpatterns/recipes/querymainwindow.cpp 1 + + \l{evaluate() function} {evaluate()} demonstrates the standard + QtXmlPatterns usage pattern. First, an instance of QXmlQuery is + created (\c{query}). The \c{query's} \l{QXmlQuery::bindVariable()} + {bindVariable()} function is then called to bind the \c cookbook.xml + file to the XQuery variable \c inputDocument. \e{After} the variable + is bound, \l{QXmlQuery::setQuery()} {setQuery()} is called to pass + the XQuery text to the \c query. + + \note \l{QXmlQuery::setQuery()} {setQuery()} must be called + \e{after} \l{QXmlQuery::bindVariable()} {bindVariable()}. + + Passing the XQuery to \l{QXmlQuery::setQuery()} {setQuery()} causes + QtXmlPatterns to parse the XQuery. \l{QXmlQuery::isValid()} is + called to ensure that the XQuery was correctly parsed. + + \target evaluate() function + \snippet examples/xmlpatterns/recipes/querymainwindow.cpp 2 + + If the XQuery is valid, an instance of QXmlFormatter is created to + format the query result as XML into a QBuffer. To evaluate the + XQuery, an overload of \l{QXmlQuery::evaluateTo()} {evaluateTo()} is + called that takes a QAbstractXmlReceiver for its output + (QXmlFormatter inherits QAbstractXmlReceiver). Finally, the + formatted XML result is displayed in the UI's bottom text view. + + \note Each XQuery \c{.xq} file must declare the \c{$inputDocument} + variable to represent the \c cookbook.xml document: + + \code + (: All ingredients for Mushroom Soup. :) + declare variable $inputDocument external; + + doc($inputDocument)/cookbook/recipe[@xml:id = "MushroomSoup"]/ingredient/ + <p>{@name, @quantity}</p> + \endcode + + \note If you add add your own query.xq files, you must declare the + \c{$inputDocument} and use it as shown above. + +*/ diff --git a/doc/src/examples/regexp.qdoc b/doc/src/examples/regexp.qdoc new file mode 100644 index 0000000..de6cbfc --- /dev/null +++ b/doc/src/examples/regexp.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/regexp + \title Regular Expressions Example + + The Regular Expressions (RegExp) example shows how regular expressions in Qt are + applied to text by providing an environment in which new regular expressions can be + created and tested on custom text strings. + + \image regexp-example.png +*/ diff --git a/doc/src/examples/relationaltablemodel.qdoc b/doc/src/examples/relationaltablemodel.qdoc new file mode 100644 index 0000000..5e944c2 --- /dev/null +++ b/doc/src/examples/relationaltablemodel.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example sql/relationaltablemodel + \title Relational Table Model Example + + The Relational Table Model example shows how to use table views with a relational + model to visualize the relations between items in a database. + + \image relationaltablemodel-example.png +*/ diff --git a/doc/src/examples/remotecontrol.qdoc b/doc/src/examples/remotecontrol.qdoc new file mode 100644 index 0000000..698ad1f --- /dev/null +++ b/doc/src/examples/remotecontrol.qdoc @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example help/remotecontrol + \title Remote Control Example + + This example shows how to use and control Qt Assistant + as a help viewer. +*/
\ No newline at end of file diff --git a/doc/src/examples/rsslisting.qdoc b/doc/src/examples/rsslisting.qdoc new file mode 100644 index 0000000..73ff68c --- /dev/null +++ b/doc/src/examples/rsslisting.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xml/rsslisting + \title RSS-Listing Example + + This example shows how to create a widget that displays news items + from RDF news sources. + + \image rsslistingexample.png +*/ diff --git a/doc/src/examples/samplebuffers.qdoc b/doc/src/examples/samplebuffers.qdoc new file mode 100644 index 0000000..1c8202c --- /dev/null +++ b/doc/src/examples/samplebuffers.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example opengl/samplebuffers + \title Sample Buffers Example + + The Sample Buffers example demonstrates how to use and enable + sample buffers in a QGLWidget. + + \image samplebuffers-example.png +*/ diff --git a/doc/src/examples/saxbookmarks.qdoc b/doc/src/examples/saxbookmarks.qdoc new file mode 100644 index 0000000..3db87d6 --- /dev/null +++ b/doc/src/examples/saxbookmarks.qdoc @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xml/saxbookmarks + \title SAX Bookmarks Example + + The SAX Bookmarks example provides a reader for XML Bookmark Exchange Language (XBEL) + files that uses Qt's SAX-based API to read and parse the files. The DOM Bookmarks + example provides an alternative way to read this type of file. + + \image saxbookmarks-example.png + + See the \l{XML Bookmark Exchange Language Resource Page} for more + information about XBEL files. +*/ diff --git a/doc/src/examples/screenshot.qdoc b/doc/src/examples/screenshot.qdoc new file mode 100644 index 0000000..b989a32 --- /dev/null +++ b/doc/src/examples/screenshot.qdoc @@ -0,0 +1,262 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example desktop/screenshot + \title Screenshot Example + + The Screenshot example shows how to take a screenshot of the + desktop using QApplication and QDesktopWidget. It also shows how + to use QTimer to provide a single-shot timer, and how to + reimplement the QWidget::resizeEvent() event handler to make sure + that an application resizes smoothly and without data loss. + + \image screenshot-example.png + + With the application the users can take a screenshot of their + desktop. They are provided with a couple of options: + + \list + \o Delaying the screenshot, giving them time to rearrange + their desktop. + \o Hiding the application's window while the screenshot is taken. + \endlist + + In addition the application allows the users to save their + screenshot if they want to. + + \section1 Screenshot Class Definition + + \snippet examples/desktop/screenshot/screenshot.h 0 + + The \c Screenshot class inherits QWidget and is the application's + main widget. It displays the application options and a preview of + the screenshot. + + We reimplement the QWidget::resizeEvent() function to make sure + that the preview of the screenshot scales properly when the user + resizes the application widget. We also need several private slots + to facilitate the options: + + \list + \o The \c newScreenshot() slot prepares a new screenshot. + \o The \c saveScreenshot() slot saves the last screenshot. + \o The \c shootScreen() slot takes the screenshot. + \o The \c updateCheckBox() slot enables or disables the + \gui {Hide This Window} option. + \endlist + + We also declare some private functions: We use the \c + createOptionsGroupBox(), \c createButtonsLayout() and \c + createButton() functions when we construct the widget. And we call + the private \c updateScreenshotLabel() function whenever a new + screenshot is taken or when a resize event changes the size of the + screenshot preview label. + + In addition we need to store the screenshot's original pixmap. The + reason is that when we display the preview of the screenshot, we + need to scale its pixmap, storing the original we make sure that + no data are lost in that process. + + \section1 Screenshot Class Implementation + + \snippet examples/desktop/screenshot/screenshot.cpp 0 + + In the constructor we first create the QLabel displaying the + screenshot preview. + + We set the QLabel's size policy to be QSizePolicy::Expanding both + horizontally and vertically. This means that the QLabel's size + hint is a sensible size, but the widget can be shrunk and still be + useful. Also, the widget can make use of extra space, so it should + get as much space as possible. Then we make sure the QLabel is + aligned in the center of the \c Screenshot widget, and set its + minimum size. + + We create the applications's buttons and the group box containing + the application's options, and put it all into a main + layout. Finally we take the initial screenshot, and set the inital + delay and the window title, before we resize the widget to a + suitable size. + + \snippet examples/desktop/screenshot/screenshot.cpp 1 + + The \c resizeEvent() function is reimplemented to receive the + resize events dispatched to the widget. The purpose is to scale + the preview screenshot pixmap without deformation of its content, + and also make sure that the application can be resized smoothly. + + To achieve the first goal, we scale the screenshot pixmap using + Qt::KeepAspectRatio. We scale the pixmap to a rectangle as large + as possible inside the current size of the screenshot preview + label, preserving the aspect ratio. This means that if the user + resizes the application window in only one direction, the preview + screenshot keeps the same size. + + To reach our second goal, we make sure that the preview screenshot + only is repainted (using the private \c updateScreenshotLabel() + function) when it actually changes its size. + + \snippet examples/desktop/screenshot/screenshot.cpp 2 + + The private \c newScreenshot() slot is called when the user + requests a new screenshot; but the slot only prepares a new + screenshot. + + First we see if the \gui {Hide This Window} option is checked, if + it is we hide the \c Screenshot widget. Then we disable the \gui + {New Screenshot} button, to make sure the user only can request + one screenshot at a time. + + We create a timer using the QTimer class which provides repetitive + and single-shot timers. We set the timer to time out only once, + using the static QTimer::singleShot() function. This function + calls the private \c shootScreen() slot after the time interval + specified by the \gui {Screenshot Delay} option. It is \c + shootScreen() that actually performs the screenshot. + + \snippet examples/desktop/screenshot/screenshot.cpp 3 + + The \c saveScreenshot() slot is called when the user push the \gui + Save button, and it presents a file dialog using the QFileDialog + class. + + QFileDialog enables a user to traverse the file system in order to + select one or many files or a directory. The easiest way to create + a QFileDialog is to use the convenience static + functions. + + We define the default file format to be png, and we make the file + dialog's initial path the path the application is run from. We + create the file dialog using the static + QFileDialog::getSaveFileName() function which returns a file name + selected by the user. The file does not have to exist. If the file + name is valid, we use the QPixmap::save() function to save the + screenshot's original pixmap in that file. + + \snippet examples/desktop/screenshot/screenshot.cpp 4 + + The \c shootScreen() slot is called to take the screenshot. If the + user has chosen to delay the screenshot, we make the application + beep when the screenshot is taken using the static + QApplication::beep() function. + + The QApplication class manages the GUI application's control flow + and main settings. It contains the main event loop, where all + events from the window system and other sources are processed and + dispatched. + + \snippet examples/desktop/screenshot/screenshot.cpp 5 + + We take the screenshot using the static QPixmap::grabWindow() + function. The function grabs the contents of the window passed as + an argument, makes a pixmap out of it and returns that pixmap. + + We identify the argument window using the QWidget::winID() + function which returns the window system identifier. Here it + returns the identifier of the current QDesktopWidget retrieved by + the QApplication::desktop() function. The QDesktopWidget class + provides access to screen information, and inherits + QWidget::winID(). + + We update the screenshot preview label using the private \c + updateScreenshotLabel() function. Then we enable the \gui {New + Screenshot} button, and finally we make the \c Screenshot widget + visible if it was hidden during the screenshot. + + \snippet examples/desktop/screenshot/screenshot.cpp 6 + + The \gui {Hide This Window} option is enabled or disabled + depending on the delay of the screenshot. If there is no delay, + the application window cannot be hidden and the option's checkbox + is disabled. + + The \c updateCheckBox() slot is called whenever the user changes + the delay using the \gui {Screenshot Delay} option. + + \snippet examples/desktop/screenshot/screenshot.cpp 7 + + The private \c createOptionsGroupBox() function is called from the + constructor. + + First we create a group box that will contain all of the options' + widgets. Then we create a QSpinBox and a QLabel for the \gui + {Screenshot Delay} option, and connect the spinbox to the \c + updateCheckBox() slot. Finally, we create a QCheckBox for the \gui + {Hide This Window} option, add all the options' widgets to a + QGridLayout and install the layout on the group box. + + Note that we don't have to specify any parents for the widgets + when we create them. The reason is that when we add a widget to a + layout and install the layout on another widget, the layout's + widgets are automatically reparented to the widget the layout is + installed on. + + \snippet examples/desktop/screenshot/screenshot.cpp 8 + + The private \c createButtonsLayout() function is called from the + constructor. We create the application's buttons using the private + \c createButton() function, and add them to a QHBoxLayout. + + \snippet examples/desktop/screenshot/screenshot.cpp 9 + + The private \c createButton() function is called from the \c + createButtonsLayout() function. It simply creates a QPushButton + with the provided text, connects it to the provided receiver and + slot, and returns a pointer to the button. + + \snippet examples/desktop/screenshot/screenshot.cpp 10 + + The private \c updateScreenshotLabel() function is called whenever + the screenshot changes, or when a resize event changes the size of + the screenshot preview label. It updates the screenshot preview's + label using the QLabel::setPixmap() and QPixmap::scaled() + functions. + + QPixmap::scaled() returns a copy of the given pixmap scaled to a + rectangle of the given size according to the given + Qt::AspectRatioMode and Qt::TransformationMode. + + We scale the original pixmap to fit the current screenshot label's + size, preserving the aspect ratio and giving the resulting pixmap + smoothed edges. +*/ + diff --git a/doc/src/examples/scribble.qdoc b/doc/src/examples/scribble.qdoc new file mode 100644 index 0000000..4dc1783 --- /dev/null +++ b/doc/src/examples/scribble.qdoc @@ -0,0 +1,432 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/scribble + \title Scribble Example + + The Scribble example shows how to reimplement some of QWidget's + event handlers to receive the events generated for the + application's widgets. + + We reimplement the mouse event handlers to implement drawing, the + paint event handler to update the application and the resize event + handler to optimize the application's appearance. In addition we + reimplement the close event handler to intercept the close events + before terminating the application. + + The example also demonstrates how to use QPainter to draw an image + in real time, as well as to repaint widgets. + + \image scribble-example.png Screenshot of the Scribble example + + With the Scribble application the users can draw an image. The + \gui File menu gives the users the possibility to open and edit an + existing image file, save an image and exit the application. While + drawing, the \gui Options menu allows the users to to choose the + pen color and pen width, as well as clear the screen. In addition + the \gui Help menu provides the users with information about the + Scribble example in particular, and about Qt in general. + + The example consists of two classes: + + \list + \o \c ScribbleArea is a custom widget that displays a QImage and + allows to the user to draw on it. + \o \c MainWindow provides a menu above the \c ScribbleArea. + \endlist + + We will start by reviewing the \c ScribbleArea class, which + contains the interesting, then we will take a look at the \c + MainWindow class that uses it. + + \section1 ScribbleArea Class Definition + + \snippet examples/widgets/scribble/scribblearea.h 0 + + The \c ScribbleArea class inherits from QWidget. We reimplement + the \c mousePressEvent(), \c mouseMoveEvent() and \c + mouseReleaseEvent() functions to implement the drawing. We + reimplement the \c paintEvent() function to update the scribble + area, and the \c resizeEvent() function to ensure that the QImage + on which we draw is at least as large as the widget at any time. + + We need several public functions: \c openImage() loads an image + from a file into the scribble area, allowing the user to edit the + image; \c save() writes the currently displayed image to file; \c + clearImage() slot clears the image displayed in the scribble + area. We need the private \c drawLineTo() function to actually do + the drawing, and \c resizeImage() to change the size of a + QImage. The \c print() slot handles printing. + + We also need the following private variables: + + \list + \o \c modified is \c true if there are unsaved + changes to the image displayed in the scribble area. + \o \c scribbling is \c true while the user is pressing + the left mouse button within the scribble area. + \o \c penWidth and \c penColor hold the currently + set width and color for the pen used in the application. + \o \c image stores the image drawn by the user. + \o \c lastPoint holds the position of the cursor at the last + mouse press or mouse move event. + \endlist + + \section1 ScribbleArea Class Implementation + + \snippet examples/widgets/scribble/scribblearea.cpp 0 + + In the constructor, we set the Qt::WA_StaticContents + attribute for the widget, indicating that the widget contents are + rooted to the top-left corner and don't change when the widget is + resized. Qt uses this attribute to optimize paint events on + resizes. This is purely an optimization and should only be used + for widgets whose contents are static and rooted to the top-left + corner. + + \snippet examples/widgets/scribble/scribblearea.cpp 1 + \snippet examples/widgets/scribble/scribblearea.cpp 2 + + In the \c openImage() function, we load the given image. Then we + resize the loaded QImage to be at least as large as the widget in + both directions using the private \c resizeImage() function and + we set the \c image member variable to be the loaded image. At + the end, we call QWidget::update() to schedule a repaint. + + \snippet examples/widgets/scribble/scribblearea.cpp 3 + \snippet examples/widgets/scribble/scribblearea.cpp 4 + + The \c saveImage() function creates a QImage object that covers + only the visible section of the actual \c image and saves it using + QImage::save(). If the image is successfully saved, we set the + scribble area's \c modified variable to \c false, because there is + no unsaved data. + + \snippet examples/widgets/scribble/scribblearea.cpp 5 + \snippet examples/widgets/scribble/scribblearea.cpp 6 + \codeline + \snippet examples/widgets/scribble/scribblearea.cpp 7 + \snippet examples/widgets/scribble/scribblearea.cpp 8 + + The \c setPenColor() and \c setPenWidth() functions set the + current pen color and width. These values will be used for future + drawing operations. + + \snippet examples/widgets/scribble/scribblearea.cpp 9 + \snippet examples/widgets/scribble/scribblearea.cpp 10 + + The public \c clearImage() slot clears the image displayed in the + scribble area. We simply fill the entire image with white, which + corresponds to RGB value (255, 255, 255). As usual when we modify + the image, we set \c modified to \c true and schedule a repaint. + + \snippet examples/widgets/scribble/scribblearea.cpp 11 + \snippet examples/widgets/scribble/scribblearea.cpp 12 + + For mouse press and mouse release events, we use the + QMouseEvent::button() function to find out which button caused + the event. For mose move events, we use QMouseEvent::buttons() + to find which buttons are currently held down (as an OR-combination). + + If the users press the left mouse button, we store the position + of the mouse cursor in \c lastPoint. We also make a note that the + user is currently scribbling. (The \c scribbling variable is + necessary because we can't assume that a mouse move and mouse + release event is always preceded by a mouse press event on the + same widget.) + + If the user moves the mouse with the left button pressed down or + releases the button, we call the private \c drawLineTo() function + to draw. + + \snippet examples/widgets/scribble/scribblearea.cpp 13 + \snippet examples/widgets/scribble/scribblearea.cpp 14 + + In the reimplementation of the \l + {QWidget::paintEvent()}{paintEvent()} function, we simply create + a QPainter for the scribble area, and draw the image. + + At this point, you might wonder why we don't just draw directly + onto the widget instead of drawing in a QImage and copying the + QImage onto screen in \c paintEvent(). There are at least three + good reasons for this: + + \list + \o The window system requires us to be able to redraw the widget + \e{at any time}. For example, if the window is minimized and + restored, the window system might have forgotten the contents + of the widget and send us a paint event. In other words, we + can't rely on the window system to remember our image. + + \o Qt normally doesn't allow us to paint outside of \c + paintEvent(). In particular, we can't paint from the mouse + event handlers. (This behavior can be changed using the + Qt::WA_PaintOnScreen widget attribute, though.) + + \o If initialized properly, a QImage is guaranteed to use 8-bit + for each color channel (red, green, blue, and alpha), whereas + a QWidget might have a lower color depth, depending on the + monitor configuration. This means that if we load a 24-bit or + 32-bit image and paint it onto a QWidget, then copy the + QWidget into a QImage again, we might lose some information. + \endlist + + \snippet examples/widgets/scribble/scribblearea.cpp 15 + \snippet examples/widgets/scribble/scribblearea.cpp 16 + + When the user starts the Scribble application, a resize event is + generated and an image is created and displayed in the scribble + area. We make this initial image slightly larger than the + application's main window and scribble area, to avoid always + resizing the image when the user resizes the main window (which + would be very inefficient). But when the main window becomes + larger than this initial size, the image needs to be resized. + + \snippet examples/widgets/scribble/scribblearea.cpp 17 + \snippet examples/widgets/scribble/scribblearea.cpp 18 + + In \c drawLineTo(), we draw a line from the point where the mouse + was located when the last mouse press or mouse move occurred, we + set \c modified to true, we generate a repaint event, and we + update \c lastPoint so that next time \c drawLineTo() is called, + we continue drawing from where we left. + + We could call the \c update() function with no parameter, but as + an easy optimization we pass a QRect that specifies the rectangle + inside the scribble are needs updating, to avoid a complete + repaint of the widget. + + \snippet examples/widgets/scribble/scribblearea.cpp 19 + \snippet examples/widgets/scribble/scribblearea.cpp 20 + + QImage has no nice API for resizing an image. There's a + QImage::copy() function that could do the trick, but when used to + expand an image, it fills the new areas with black, whereas we + want white. + + So the trick is to create a brand new QImage with the right size, + to fill it with white, and to draw the old image onto it using + QPainter. The new image is given the QImage::Format_RGB32 + format, which means that each pixel is stored as 0xffRRGGBB + (where RR, GG, and BB are the red, green and blue + color channels, ff is the hexadecimal value 255). + + Printing is handled by the \c print() slot: + + \snippet examples/widgets/scribble/scribblearea.cpp 21 + + We construct a high resolution QPrinter object for the required + output format, using a QPrintDialog to ask the user to specify a + page size and indicate how the output should be formatted on the page. + + If the dialog is accepted, we perform the task of printing to the paint + device: + + \snippet examples/widgets/scribble/scribblearea.cpp 22 + + Printing an image to a file in this way is simply a matter of + painting onto the QPrinter. We scale the image to fit within the + available space on the page before painting it onto the paint + device. + + \section1 MainWindow Class Definition + + \snippet examples/widgets/scribble/mainwindow.h 0 + + The \c MainWindow class inherits from QMainWindow. We reimplement + the \l{QWidget::closeEvent()}{closeEvent()} handler from QWidget. + The \c open(), \c save(), \c penColor() and \c penWidth() + slots correspond to menu entries. In addition we create four + private functions. + + We use the boolean \c maybeSave() function to check if there are + any unsaved changes. If there are unsaved changes, we give the + user the opportunity to save these changes. The function returns + \c false if the user clicks \gui Cancel. We use the \c saveFile() + function to let the user save the image currently displayed in + the scribble area. + + \section1 MainWindow Class Implementation + + \snippet examples/widgets/scribble/mainwindow.cpp 0 + + In the constructor, we create a scribble area which we make the + central widget of the \c MainWindow widget. Then we create the + associated actions and menus. + + \snippet examples/widgets/scribble/mainwindow.cpp 1 + \snippet examples/widgets/scribble/mainwindow.cpp 2 + + Close events are sent to widgets that the users want to close, + usually by clicking \gui{File|Exit} or by clicking the \gui X + title bar button. By reimplementing the event handler, we can + intercept attempts to close the application. + + In this example, we use the close event to ask the user to save + any unsaved changes. The logic for that is located in the \c + maybeSave() function. If \c maybeSave() returns true, there are + no modifications or the users successfully saved them, and we + accept the event. The application can then terminate normally. If + \c maybeSave() returns false, the user clicked \gui Cancel, so we + "ignore" the event, leaving the application unaffected by it. + + \snippet examples/widgets/scribble/mainwindow.cpp 3 + \snippet examples/widgets/scribble/mainwindow.cpp 4 + + In the \c open() slot we first give the user the opportunity to + save any modifications to the currently displayed image, before a + new image is loaded into the scribble area. Then we ask the user + to choose a file and we load the file in the \c ScribbleArea. + + \snippet examples/widgets/scribble/mainwindow.cpp 5 + \snippet examples/widgets/scribble/mainwindow.cpp 6 + + The \c save() slot is called when the users choose the \gui {Save + As} menu entry, and then choose an entry from the format menu. The + first thing we need to do is to find out which action sent the + signal using QObject::sender(). This function returns the sender + as a QObject pointer. Since we know that the sender is an action + object, we can safely cast the QObject. We could have used a + C-style cast or a C++ \c static_cast<>(), but as a defensive + programming technique we use a qobject_cast(). The advantage is + that if the object has the wrong type, a null pointer is + returned. Crashes due to null pointers are much easier to diagnose + than crashes due to unsafe casts. + + Once we have the action, we extract the chosen format using + QAction::data(). (When the actions are created, we use + QAction::setData() to set our own custom data attached to the + action, as a QVariant. More on this when we review \c + createActions().) + + Now that we know the format, we call the private \c saveFile() + function to save the currently displayed image. + + \snippet examples/widgets/scribble/mainwindow.cpp 7 + \snippet examples/widgets/scribble/mainwindow.cpp 8 + + We use the \c penColor() slot to retrieve a new color from the + user with a QColorDialog. If the user chooses a new color, we + make it the scribble area's color. + + \snippet examples/widgets/scribble/mainwindow.cpp 9 + \snippet examples/widgets/scribble/mainwindow.cpp 10 + + To retrieve a new pen width in the \c penWidth() slot, we use + QInputDialog. The QInputDialog class provides a simple + convenience dialog to get a single value from the user. We use + the static QInputDialog::getInteger() function, which combines a + QLabel and a QSpinBox. The QSpinBox is initialized with the + scribble area's pen width, allows a range from 1 to 50, a step of + 1 (meaning that the up and down arrow increment or decrement the + value by 1). + + The boolean \c ok variable will be set to \c true if the user + clicked \gui OK and to \c false if the user pressed \gui Cancel. + + \snippet examples/widgets/scribble/mainwindow.cpp 11 + \snippet examples/widgets/scribble/mainwindow.cpp 12 + + We implement the \c about() slot to create a message box + describing what the example is designed to show. + + \snippet examples/widgets/scribble/mainwindow.cpp 13 + \snippet examples/widgets/scribble/mainwindow.cpp 14 + + In the \c createAction() function we create the actions + representing the menu entries and connect them to the appropiate + slots. In particular we create the actions found in the \gui + {Save As} sub-menu. We use QImageWriter::supportedImageFormats() + to get a list of the supported formats (as a QList<QByteArray>). + + Then we iterate through the list, creating an action for each + format. We call QAction::setData() with the file format, so we + can retrieve it later as QAction::data(). We could also have + deduced the file format from the action's text, by truncating the + "...", but that would have been inelegant. + + \snippet examples/widgets/scribble/mainwindow.cpp 15 + \snippet examples/widgets/scribble/mainwindow.cpp 16 + + In the \c createMenu() function, we add the previously created + format actions to the \c saveAsMenu. Then we add the rest of the + actions as well as the \c saveAsMenu sub-menu to the \gui File, + \gui Options and \gui Help menus. + + The QMenu class provides a menu widget for use in menu bars, + context menus, and other popup menus. The QMenuBar class provides + a horizontal menu bar with a list of pull-down \l{QMenu}s. At the + end we put the \gui File and \gui Options menus in the \c + {MainWindow}'s menu bar, which we retrieve using the + QMainWindow::menuBar() function. + + \snippet examples/widgets/scribble/mainwindow.cpp 17 + \snippet examples/widgets/scribble/mainwindow.cpp 18 + + In \c mayBeSave(), we check if there are any unsaved changes. If + there are any, we use QMessageBox to give the user a warning that + the image has been modified and the opportunity to save the + modifications. + + As with QColorDialog and QFileDialog, the easiest way to create a + QMessageBox is to use its static functions. QMessageBox provides + a range of different messages arranged along two axes: severity + (question, information, warning and critical) and complexity (the + number of necessary response buttons). Here we use the \c + warning() function sice the message is rather important. + + If the user chooses to save, we call the private \c saveFile() + function. For simplicitly, we use PNG as the file format; the + user can always press \gui Cancel and save the file using another + format. + + The \c maybeSave() function returns \c false if the user clicks + \gui Cancel; otherwise it returns \c true. + + \snippet examples/widgets/scribble/mainwindow.cpp 19 + \snippet examples/widgets/scribble/mainwindow.cpp 20 + + In \c saveFile(), we pop up a file dialog with a file name + suggestion. The static QFileDialog::getSaveFileName() function + returns a file name selected by the user. The file does not have + to exist. +*/ diff --git a/doc/src/examples/sdi.qdoc b/doc/src/examples/sdi.qdoc new file mode 100644 index 0000000..cfe351c --- /dev/null +++ b/doc/src/examples/sdi.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example mainwindows/sdi + \title SDI Example + + The SDI example shows how to create a Single Document Interface. It uses a number of + top-level windows to display the contents of different text files. + + \image sdi-example.png +*/ diff --git a/doc/src/examples/securesocketclient.qdoc b/doc/src/examples/securesocketclient.qdoc new file mode 100644 index 0000000..e93bf20 --- /dev/null +++ b/doc/src/examples/securesocketclient.qdoc @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example network/securesocketclient + \title Secure Socket Client Example + + The Secure Socket Client example shows how to use QSslSocket to + communicate over an encrypted (SSL) connection. It also demonstrates how + to deal with authenticity problems, and how to display security and + certificate information. + + \image securesocketclient.png + \image securesocketclient2.png +*/ diff --git a/doc/src/examples/semaphores.qdoc b/doc/src/examples/semaphores.qdoc new file mode 100644 index 0000000..a387350 --- /dev/null +++ b/doc/src/examples/semaphores.qdoc @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example threads/semaphores + \title Semaphores Example + + The Semaphores example shows how to use QSemaphore to control + access to a circular buffer shared by a producer thread and a + consumer thread. + + The producer writes data to the buffer until it reaches the end + of the buffer, at which point it restarts from the beginning, + overwriting existing data. The consumer thread reads the data as + it is produced and writes it to standard error. + + Semaphores make it possible to have a higher level of concurrency + than mutexes. If accesses to the buffer were guarded by a QMutex, + the consumer thread couldn't access the buffer at the same time + as the producer thread. Yet, there is no harm in having both + threads working on \e{different parts} of the buffer at the same + time. + + The example comprises two classes: \c Producer and \c Consumer. + Both inherit from QThread. The circular buffer used for + communicating between these two classes and the semaphores that + protect it are global variables. + + An alternative to using QSemaphore to solve the producer-consumer + problem is to use QWaitCondition and QMutex. This is what the + \l{threads/waitconditions}{Wait Conditions} example does. + + \section1 Global Variables + + Let's start by reviewing the circular buffer and the associated + semaphores: + + \snippet examples/threads/semaphores/semaphores.cpp 0 + + \c DataSize is the amout of data that the producer will generate. + To keep the example as simple as possible, we make it a constant. + \c BufferSize is the size of the circular buffer. It is less than + \c DataSize, meaning that at some point the producer will reach + the end of the buffer and restart from the beginning. + + To synchronize the producer and the consumer, we need two + semaphores. The \c freeBytes semaphore controls the "free" area + of the buffer (the area that the producer hasn't filled with data + yet or that the consumer has already read). The \c usedBytes + semaphore controls the "used" area of the buffer (the area that + the producer has filled but that the consumer hasn't read yet). + + Together, the semaphores ensure that the producer is never more + than \c BufferSize bytes ahead of the consumer, and that the + consumer never reads data that the producer hasn't generated yet. + + The \c freeBytes semaphore is initialized with \c BufferSize, + because initially the entire buffer is empty. The \c usedBytes + semaphore is initialized to 0 (the default value if none is + specified). + + \section1 Producer Class + + Let's review the code for the \c Producer class: + + \snippet examples/threads/semaphores/semaphores.cpp 1 + \snippet examples/threads/semaphores/semaphores.cpp 2 + + The producer generates \c DataSize bytes of data. Before it + writes a byte to the circular buffer, it must acquire a "free" + byte using the \c freeBytes semaphore. The QSemaphore::acquire() + call might block if the consumer hasn't kept up the pace with the + producer. + + At the end, the producer releases a byte using the \c usedBytes + semaphore. The "free" byte has successfully been transformed into + a "used" byte, ready to be read by the consumer. + + \section1 Consumer Class + + Let's now turn to the \c Consumer class: + + \snippet examples/threads/semaphores/semaphores.cpp 3 + \snippet examples/threads/semaphores/semaphores.cpp 4 + + The code is very similar to the producer, except that this time + we acquire a "used" byte and release a "free" byte, instead of + the opposite. + + \section1 The main() Function + + In \c main(), we create the two threads and call QThread::wait() + to ensure that both threads get time to finish before we exit: + + \snippet examples/threads/semaphores/semaphores.cpp 5 + \snippet examples/threads/semaphores/semaphores.cpp 6 + + So what happens when we run the program? Initially, the producer + thread is the only one that can do anything; the consumer is + blocked waiting for the \c usedBytes semaphore to be released (its + initial \l{QSemaphore::available()}{available()} count is 0). + Once the producer has put one byte in the buffer, + \c{freeBytes.available()} is \c BufferSize - 1 and + \c{usedBytes.available()} is 1. At that point, two things can + happen: Either the consumer thread takes over and reads that + byte, or the consumer gets to produce a second byte. + + The producer-consumer model presented in this example makes it + possible to write highly concurrent multithreaded applications. + On a multiprocessor machine, the program is potentially up to + twice as fast as the equivalent mutex-based program, since the + two threads can be active at the same time on different parts of + the buffer. + + Be aware though that these benefits aren't always realized. + Acquiring and releasing a QSemaphore has a cost. In practice, it + would probably be worthwhile to divide the buffer into chunks and + to operate on chunks instead of individual bytes. The buffer size + is also a parameter that must be selected carefully, based on + experimentation. +*/ diff --git a/doc/src/examples/settingseditor.qdoc b/doc/src/examples/settingseditor.qdoc new file mode 100644 index 0000000..5ce1e49 --- /dev/null +++ b/doc/src/examples/settingseditor.qdoc @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/settingseditor + \title Settings Editor Example + + The Settings Editor example shows how Qt's standard settings support is used in an + application by providing an editor that enables the user to view the settings for + installed applications, and modify those that can be edited. + + \image settingseditor-example.png +*/ diff --git a/doc/src/examples/shapedclock.qdoc b/doc/src/examples/shapedclock.qdoc new file mode 100644 index 0000000..369553b --- /dev/null +++ b/doc/src/examples/shapedclock.qdoc @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/shapedclock + \title Shaped Clock Example + + The Shaped Clock example shows how to apply a widget mask to a top-level + widget to produce a shaped window. + + \image shapedclock-example.png + + Widget masks are used to customize the shapes of top-level widgets by restricting + the available area for painting. On some window systems, setting certain window flags + will cause the window decoration (title bar, window frame, buttons) to be disabled, + allowing specially-shaped windows to be created. In this example, we use this feature + to create a circular window containing an analog clock. + + Since this example's window does not provide a \gui File menu or a close + button, we provide a context menu with an \gui Exit entry so that the example + can be closed. Click the right mouse button over the window to open this menu. + + \section1 ShapedClock Class Definition + + The \c ShapedClock class is based on the \c AnalogClock class defined in the + \l{Analog Clock Example}{Analog Clock} example. The whole class definition is + presented below: + + \snippet examples/widgets/shapedclock/shapedclock.h 0 + + The \l{QWidget::paintEvent()}{paintEvent()} implementation is the same as that found + in the \c AnalogClock class. We implement \l{QWidget::sizeHint()}{sizeHint()} + so that we don't have to resize the widget explicitly. We also provide an event + handler for resize events. This allows us to update the mask if the clock is resized. + + Since the window containing the clock widget will have no title bar, we provide + implementations for \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()} and + \l{QWidget::mousePressEvent()}{mousePressEvent()} to allow the clock to be dragged + around the screen. The \c dragPosition variable lets us keep track of where the user + last clicked on the widget. + + \section1 ShapedClock Class Implementation + + The \c ShapedClock constructor performs many of the same tasks as the \c AnalogClock + constructor. We set up a timer and connect it to the widget's update() slot: + + \snippet examples/widgets/shapedclock/shapedclock.cpp 0 + + We inform the window manager that the widget is not to be decorated with a window + frame by setting the Qt::FramelessWindowHint flag on the widget. As a result, we need + to provide a way for the user to move the clock around the screen. + + Mouse button events are delivered to the \c mousePressEvent() handler: + + \snippet examples/widgets/shapedclock/shapedclock.cpp 1 + + If the left mouse button is pressed over the widget, we record the displacement in + global (screen) coordinates between the top-left position of the widget's frame (even + when hidden) and the point where the mouse click occurred. This displacement will be + used if the user moves the mouse while holding down the left button. Since we acted + on the event, we accept it by calling its \l{QEvent::accept()}{accept()} function. + + \image shapedclock-dragging.png + + The \c mouseMoveEvent() handler is called if the mouse is moved over the widget. + + \snippet examples/widgets/shapedclock/shapedclock.cpp 2 + + If the left button is held down while the mouse is moved, the top-left corner of the + widget is moved to the point given by subtracting the \c dragPosition from the current + cursor position in global coordinates. If we drag the widget, we also accept the event. + + The \c paintEvent() function is given for completeness. See the + \l{Analog Clock Example}{Analog Clock} example for a description of the process used + to render the clock. + + \snippet examples/widgets/shapedclock/shapedclock.cpp 3 + + In the \c resizeEvent() handler, we re-use some of the code from the \c paintEvent() + to determine the region of the widget that is visible to the user: + + \snippet examples/widgets/shapedclock/shapedclock.cpp 4 + + Since the clock face is a circle drawn in the center of the widget, this is the region + we use as the mask. + + Although the lack of a window frame may make it difficult for the user to resize the + widget on some platforms, it will not necessarily be impossible. The \c resizeEvent() + function ensures that the widget mask will always be updated if the widget's dimensions + change, and additionally ensures that it will be set up correctly when the widget is + first displayed. + + Finally, we implement the \c sizeHint() for the widget so that it is given a reasonable + default size when it is first shown: + + \snippet examples/widgets/shapedclock/shapedclock.cpp 5 + + \section1 Notes on Widget Masks + + Since QRegion allows arbitrarily complex regions to be created, widget masks can be + made to suit the most unconventionally-shaped windows, and even allow widgets to be + displayed with holes in them. + + Widget masks can also be constructed by using the contents of pixmap to define the + opaque part of the widget. For a pixmap with an alpha channel, a suitable mask can be + obtained with QPixmap::mask(). +*/ diff --git a/doc/src/examples/sharedmemory.qdoc b/doc/src/examples/sharedmemory.qdoc new file mode 100644 index 0000000..f323977 --- /dev/null +++ b/doc/src/examples/sharedmemory.qdoc @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example ipc/sharedmemory + \title Shared Memory Example + + The Shared Memory example shows how to use the QSharedMemory class + to implement inter-process communication using shared memory. To + build the example, run make. To run the example, start two instances + of the executable. The main() function creates an \l {QApplication} + {application} and an instance of our example's Dialog class. The + dialog is displayed and then control is passed to the application in + the standard way. + + \snippet examples/ipc/sharedmemory/main.cpp 0 + + Two instances of class Dialog appear. + + \image sharedmemory-example_1.png Screenshot of the Shared Memory example + + Class Dialog inherits QDialog. It encapsulates the user interface + and an instance of QSharedMemory. It also has two public slots, + loadFromFile() and loadFromMemory() that correspond to the two + buttons on the dialog. + + \snippet examples/ipc/sharedmemory/dialog.h 0 + + The constructor builds the user interface widgets and connects the + clicked() signal of each button to the corresponding slot function. + + \snippet examples/ipc/sharedmemory/dialog.cpp 0 + + Note that "QSharedMemoryExample" is passed to the \l {QSharedMemory} + {QSharedMemory()} constructor to be used as the key. This will be + used by the system as the identifier of the underlying shared memory + segment. + + Click the \tt {Load Image From File...} button on one of the + dialogs. The loadFromFile() slot is invoked. First, it tests whether + a shared memory segment is already attached to the process. If so, + that segment is detached from the process, so we can be assured of + starting off the example correctly. + + \snippet examples/ipc/sharedmemory/dialog.cpp 1 + + The user is then asked to select an image file using + QFileDialog::getOpenFileName(). The selected file is loaded into a + QImage. Using a QImage lets us ensure that the selected file is a + valid image, and it also allows us to immediately display the image + in the dialog using setPixmap(). + + Next the image is streamed into a QBuffer using a QDataStream. This + gives us the size, which we then use to \l {QSharedMemory::} + {create()} our shared memory segment. Creating a shared memory + segment automatically \l {QSharedMemory::attach()} {attaches} the + segment to the process. Using a QBuffer here lets us get a pointer + to the image data, which we then use to do a memcopy() from the + QBuffer into the shared memory segment. + + \snippet examples/ipc/sharedmemory/dialog.cpp 2 + + Note that we \l {QSharedMemory::} {lock()} the shared memory segment + before we copy into it, and we \l {QSharedMemory::} {unlock()} it + again immediately after the copy. This ensures we have exclusive + access to the shared memory segment to do our memcopy(). If some + other process has the segment lock, then our process will block + until the lock becomes available. + + Note also that the function does not \l {QSharedMemory::} {detach()} + from the shared memory segment after the memcopy() and + unlock(). Recall that when the last process detaches from a shared + memory segment, the segment is released by the operating + system. Since this process only one that is attached to the shared + memory segment at the moment, if loadFromFile() detached from the + shared memory segment, the segment would be destroyed before we get + to the next step. + + When the function returns, if the file you selected was qt.png, your + first dialog looks like this. + + \image sharedmemory-example_2.png Screenshot of the Shared Memory example + + In the second dialog, click the \tt {Display Image From Shared + Memory} button. The loadFromMemory() slot is invoked. It first \l + {QSharedMemory::attach()} {attaches} the process to the same shared + memory segment created by the first process. Then it \l + {QSharedMemory::lock()} {locks} the segment for exclusive access and + links a QBuffer to the image data in the shared memory segment. It + then streams the data into a QImage and \l {QSharedMemory::unlock()} + {unlocks} the segment. + + \snippet examples/ipc/sharedmemory/dialog.cpp 3 + + In this case, the function does \l {QSharedMemory::} {detach()} from + the segment, because now we are effectively finished using + it. Finally, the QImage is displayed. At this point, both dialogs + should be showing the same image. When you close the first dialog, + the Dialog destructor calls the QSharedMemory destructor, which + detaches from the shared memory segment. Since this is the last + process to be detached from the segment, the operating system will + now release the shared memory. + + */ diff --git a/doc/src/examples/simpledecoration.qdoc b/doc/src/examples/simpledecoration.qdoc new file mode 100644 index 0000000..fe8700a --- /dev/null +++ b/doc/src/examples/simpledecoration.qdoc @@ -0,0 +1,266 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example qws/simpledecoration + \title Simple Decoration Example + \ingroup qt-embedded + + The Simple Decoration example shows how to create a custom window decoration + for embedded applications. + + \image embedded-simpledecoration-example.png + + By default, Qt for Embedded Linux applications display windows with one of + the standard window decorations provided by Qt which are perfectly suitable + for many situations. Nonetheless, for certain applications and devices, it + is necessary to provide custom window decorations. + + In this document, we examine the fundamental features of custom window + decorations, and create a simple decoration as an example. + + \section1 Styles and Window Decorations + + On many platforms, the style used for the contents of a window (including + scroll bars) and the style used for the window decorations (the title bar, + window borders, close, maximize and other buttons) are handled differently. + This is usually because each application is responsible for rendering the + contents of its own windows and the window manager renders the window + decorations. + + Although the situation is not quite like this on Qt for Embedded Linux + because QApplication automatically handles window decorations as well, + there are still two style mechanisms at work: QStyle and its associated + classes are responsible for rendering widgets and subclasses of QDecoration + are responsible for rendering window decorations. + + \image embedded-simpledecoration-example-styles.png + + Three decorations are provided with Qt for Embedded Linux: \e default is + a basic style, \e windows resembles the classic Windows look and feel, + and \e styled uses the QStyle classes for QMdiSubWindow to draw window + decorations. Of these, \e styled is the most useful if you want to impose + a consistent look and feel, but the window decorations may be too large + for some use cases. + + If none of these built-in decorations are suitable, a custom style can + easily be created and used. To do this, we simply need to create a + subclass of QDecorationDefault and apply it to a QApplication instance + in a running application. + + \section1 MyDecoration Class Definition + + The \c MyDecoration class is a subclass of QDecorationDefault, a subclass + of QDecoration that provides reasonable default behavior for a decoration: + + \snippet examples/qws/simpledecoration/mydecoration.h decoration class definition + + We only need to implement a constructor and reimplement the + \l{QDecorationDefault::}{region()} and \l{QDecorationDefault::}{paint()} + functions to provide our own custom appearance for window decorations. + + To make things fairly general, we provide a number of private variables + to hold parameters which control certain aspects of the decoration's + appearance. We also define some data structures that we will use to + relate buttons in the window decorations to regions. + + \section1 MyDecoration Class Implementation + + In the constructor of the \c MyDecoration class, we set up some default + values for the decoration, specifying a thin window border, a title + bar that is just taller than the buttons it will hold, and we create a + list of buttons that we support: + + \snippet examples/qws/simpledecoration/mydecoration.cpp constructor start + + We map each of these Qt::WindowFlags to QDecoration::DecorationRegion + enum values to help with the implementation of the + \l{#Finding Regions}{region() function implementation}. + + \snippet examples/qws/simpledecoration/mydecoration.cpp map window flags to decoration regions + + In this decoration, we implement the buttons used in the decoration as + pixmaps. To help us relate regions of the window to these, we define + mappings between each \l{QDecoration::}{DecorationRegion} and its + corresponding pixmap for two situations: when a window is shown normally + and when it has been maximized. This is purely for cosmetic purposes. + + \snippet examples/qws/simpledecoration/mydecoration.cpp map decoration regions to pixmaps + + We finish the constructor by defining the regions for buttons that we + understand. This will be useful when we are asked to give regions for + window decoration buttons. + + \snippet examples/qws/simpledecoration/mydecoration.cpp constructor end + + \section2 Finding Regions + + Each decoration needs to be able to describe the regions used for parts + of the window furniture, such as the close button, window borders and + title bar. We reimplement the \l{QDecorationDefault::}{region()} function + to do this for our decoration. This function returns a QRegion object + that describes an arbitrarily-shaped region of the screen that can itself + be made up of several distinct areas. + + \snippet examples/qws/simpledecoration/mydecoration.cpp region start + + The function is called for a given \e widget, occupying a region specified + by \e insideRect, and is expected to return a region for the collection of + \l{QDecoration::}{DecorationRegion} enum values supplied in the + \e decorationRegion parameter. + + We begin by figuring out how much space in the decoration we will need to + allocate for buttons, and where to place them: + + \snippet examples/qws/simpledecoration/mydecoration.cpp calculate the positions of buttons based on the window flags used + + In a more sophisticated implementation, we might test the \e decorationRegion + supplied for regions related to buttons and the title bar, and only perform + this space allocation if asked for regions related to these. + + We also use the information about the area occupied by buttons to determine + how large an area we can use for the window title: + + \snippet examples/qws/simpledecoration/mydecoration.cpp calculate the extent of the title + + With these basic calculations done, we can start to compose a region, first + checking whether we have been asked for all of the window, and we return + immediately if so. + + \snippet examples/qws/simpledecoration/mydecoration.cpp check for all regions + + We examine each decoration region in turn, adding the corresponding region + to the \c region object created earlier. We take care to avoid "off by one" + errors in the coordinate calculations. + + \snippet examples/qws/simpledecoration/mydecoration.cpp compose a region based on the decorations specified + + Unlike the window borders and title bar, the regions occupied by buttons + many of the window decorations do not occupy fixed places in the window. + Instead, their locations depend on which other buttons are present. + We only add regions for buttons we can handle (defined in the \c stateRegions) + member variable, and only for those that are present (defined in the + \c buttons hash). + + \snippet examples/qws/simpledecoration/mydecoration.cpp add a region for each button only if it is present + + The fully composed region can then be returned: + + \snippet examples/qws/simpledecoration/mydecoration.cpp region end + + The information returned by this function is used when the decoration is + painted. Ideally, this function should be implemented to perform all the + calculations necessary to place elements of the decoration; this makes + the implementation of the \c paint() function much easier. + + \section2 Painting the Decoration + + The \c paint() function is responsible for drawing each window element + for a given widget. Information about the decoration region, its state + and the widget itself is provided along with a QPainter object to use. + + The first check we make is for a call with no regions: + + \snippet examples/qws/simpledecoration/mydecoration.cpp paint start + + We return false to indicate that we have not painted anything. If we paint + something, we must return true so that the window can be composed, if + necessary. + + Just as with the \c region() function, we test the decoration region to + determine which elements need to be drawn. If we paint anything, we set + the \c handled variable to true so that we can return the correct value + when we have finished. + + \snippet examples/qws/simpledecoration/mydecoration.cpp paint different regions + + Note that we use our own \c region() implementation to determine where + to draw decorations. + + Since the \c region() function performs calculations to place buttons, we + can simply test the window flags against the buttons we support (using the + \c buttonHintMap defined in the constructor), and draw each button in the + relevant region: + + \snippet examples/qws/simpledecoration/mydecoration.cpp paint buttons + + Finally, we return the value of \c handled to indicate whether any painting + was performed: + + \snippet examples/qws/simpledecoration/mydecoration.cpp paint end + + We now have a decoration class that we can use in an application. + + \section1 Using the Decoration + + In the \c main.cpp file, we set up the application as usual, but we also + create an instance of our decoration and set it as the standard decoration + for the application: + + \snippet examples/qws/simpledecoration/main.cpp create application + + This causes all windows opened by this application to use our decoration. + To demonstrate this, we show the analog clock widget from the + \l{Analog Clock Example}, which we build into the application: + + \snippet examples/qws/simpledecoration/main.cpp start application + + The application can be run either + \l{Running Qt for Embedded Linux Applications}{as a server or a client + application}. In both cases, it will use our decoration rather than the + default one provided with Qt. + + \section1 Notes + + This example does not cache any information about the state or buttons + used for each window. This means that the \c region() function calculates + the locations and regions of buttons in cases where it could re-use + existing information. + + If you run the application as a window server, you may expect client + applications to use our decoration in preference to the default Qt + decoration. However, it is up to each application to draw its own + decoration, so this will not happen automatically. One way to achieve + this is to compile the decoration with each application that needs it; + another way is to build the decoration as a plugin, using the + QDecorationPlugin class, and load it into the server and client + applications. +*/ diff --git a/doc/src/examples/simpledommodel.qdoc b/doc/src/examples/simpledommodel.qdoc new file mode 100644 index 0000000..8d2d102 --- /dev/null +++ b/doc/src/examples/simpledommodel.qdoc @@ -0,0 +1,294 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/simpledommodel + \title Simple DOM Model Example + + The Simple DOM Model example shows how an existing class can be adapted for use with + the model/view framework. + + \image simpledommodel-example.png + + Qt provides two complementary sets of classes for reading XML files: The classes based + around QXmlReader provide a SAX-style API for incremental reading of large files, and + the classes based around QDomDocument enable developers to access the contents of XML + files using a Document Object Model (DOM) API. + + In this example, we create a model that uses the DOM API to expose the structure and + contents of XML documents to views via the standard QAbstractModel interface. + + \section1 Design and Concepts + + Reading an XML document with Qt's DOM classes is a straightforward process. Typically, + the contents of a file are supplied to QDomDocument, and nodes are accessed using the + functions provided by QDomNode and its subclasses. + + \omit + For example, the following code + snippet reads the contents of a file into a QDomDocument object and traverses the + document, reading all the plain text that can be found: + + \snippet doc/src/snippets/code/doc_src_examples_simpledommodel.qdoc 0 + + In principle, the functions provided by QDomNode can be used to navigate from any + given starting point in a document to the piece of data requested by another component. + Since QDomDocument maintains information about the structure of a document, we can + use this to implement the required virtual functions in a QAbstractItemModel subclass. + \endomit + + The aim is to use the structure provided by QDomDocument by wrapping QDomNode objects + in item objects similar to the \c TreeItem objects used in the + \l{Simple Tree Model Example}{Simple Tree Model} example. + + \section1 DomModel Class Definition + + Let us begin by examining the \c DomModel class: + + \snippet examples/itemviews/simpledommodel/dommodel.h 0 + + The class definition contains all the basic functions that are needed for a + read-only model. Only the constructor and \c document() function are specific to + this model. The private \c domDocument variable is used to hold the document + that is exposed by the model; the \c rootItem variable contains a pointer to + the root item in the model. + + \section1 DomItem Class Definition + + The \c DomItem class is used to hold information about a specific QDomNode in + the document: + + \snippet examples/itemviews/simpledommodel/domitem.h 0 + + Each \c DomItem provides a wrapper for a QDomNode obtained from the underlying + document which contains a reference to the node, it's location in the parent node's + list of child nodes, and a pointer to a parent wrapper item. + + The \c parent(), \c child(), and \c row() functions are convenience functions for + the \c DomModel to use that provide basic information about the item to be discovered + quickly. The node() function provides access to the underlying QDomNode object. + + As well as the information supplied in the constructor, the class maintains a cache + of information about any child items. This is used to provide a collection of + persistent item objects that the model can identify consistently and improve the + performance of the model when accessing child items. + + \section1 DomItem Class Implementation + + Since the \c DomItem class is only a thin wrapper around QDomNode objects, with a + few additional features to help improve performance and memory usage, we can provide + a brief outline of the class before discussing the model itself. + + The constructor simply records details of the QDomNode that needs to be wrapped: + + \snippet examples/itemviews/simpledommodel/domitem.cpp 0 + \snippet examples/itemviews/simpledommodel/domitem.cpp 1 + + As a result, functions to provide the parent wrapper, the row number occupied by + the item in its parent's list of children, and the underlying QDomNode for each item + are straightforward to write: + + \snippet examples/itemviews/simpledommodel/domitem.cpp 4 + \codeline + \snippet examples/itemviews/simpledommodel/domitem.cpp 6 + \codeline + \snippet examples/itemviews/simpledommodel/domitem.cpp 3 + + It is necessary to maintain a collection of items which can be consistently identified + by the model. For that reason, we maintain a hash of child wrapper items that, to + minimize memory usage, is initially empty. The model uses the item's \c child() + function to help create model indexes, and this constructs wrappers for the children + of the item's QDomNode, relating the row number of each child to the newly-constructed + wrapper: + + \snippet examples/itemviews/simpledommodel/domitem.cpp 5 + + If a QDomNode was previously wrapped, the cached wrapper is returned; otherwise, a + new wrapper is constructed and stored for valid children, and zero is returned for + invalid ones. + + The class's destructor deletes all the child items of the wrapper: + + \snippet examples/itemviews/simpledommodel/domitem.cpp 2 + + These, in turn, will delete their children and free any QDomNode objects in use. + + \section1 DomModel Class Implementation + + The structure provided by the \c DomItem class makes the implementation of \c DomModel + similar to the \c TreeModel shown in the + \l{Simple Tree Model Example}{Simple Tree Model} example. + + The constructor accepts an existing document and a parent object for the model: + + \snippet examples/itemviews/simpledommodel/dommodel.cpp 0 + + A shallow copy of the document is stored for future reference, and a root item is + created to provide a wrapper around the document. We assign the root item a row + number of zero only to be consistent since the root item will have no siblings. + + Since the model only contains information about the root item, the destructor only + needs to delete this one item: + + \snippet examples/itemviews/simpledommodel/dommodel.cpp 1 + + All of the child items in the tree will be deleted by the \c DomItem destructor as + their parent items are deleted. + + \section2 Basic Properties of The Model + + Some aspects of the model do not depend on the structure of the underlying document, + and these are simple to implement. + + The number of columns exposed by the model is returned by the \c columnCount() + function: + + \snippet examples/itemviews/simpledommodel/dommodel.cpp 2 + + This value is fixed, and does not depend on the location or type of the underlying + node in the document. We will use these three columns to display different kinds of + data from the underlying document. + + Since we only implement a read-only model, the \c flags() function is straightforward + to write: + + \snippet examples/itemviews/simpledommodel/dommodel.cpp 5 + + Since the model is intended for use in a tree view, the \c headerData() function only + provides a horizontal header: + + \snippet examples/itemviews/simpledommodel/dommodel.cpp 6 + + The model presents the names of nodes in the first column, element attributes in the + second, and any node values in the third. + + \section2 Navigating The Document + + The index() function creates a model index for the item with the given row, column, + and parent in the model: + + \snippet examples/itemviews/simpledommodel/dommodel.cpp 7 + + The function first has to relate the parent index to an item that contains a node + from the underlying document. If the parent index is invalid, it refers to the root + node in the document, so we retrieve the root item that wraps it; otherwise, we + obtain a pointer to the relevant item using the QModelIndex::internalPointer() + function. We are able to extract a pointer in this way because any valid model index + will have been created by this function, and we store pointers to item objects in + any new indexes that we create with QAbstractItemModel::createIndex(): + + \snippet examples/itemviews/simpledommodel/dommodel.cpp 8 + + A child item for the given row is provided by the parent item's \c child() function. + If a suitable child item was found then we call + \l{QAbstractItemModel::createIndex()}{createIndex()} to produce a model index for the + requested row and column, passing a pointer to the child item for it to store + internally. If no suitable child item is found, an invalid model index is returned. + + Note that the items themselves maintain ownership of their child items. This means + that the model does not need to keep track of the child items that have been created, + and can let the items themselves tidy up when they are deleted. + + The number of rows beneath a given item in the model is returned by the \c rowCount() + function, and is the number of child nodes contained by the node that corresponds to + the specified model index: + + \snippet examples/itemviews/simpledommodel/dommodel.cpp 10 + + To obtain the relevant node in the underlying document, we access the item via the + internal pointer stored in the model index. If an invalid index is supplied, the + root item is used instead. We use the item's \c node() function to access the node + itself, and simply count the number of child nodes it contains. + + Since the model is used to represent a hierarchical data structure, it needs to + provide an implementation for the \c parent() function. This returns a model index + that corresponds to the parent of a child model index supplied as its argument: + + \snippet examples/itemviews/simpledommodel/dommodel.cpp 9 + + For valid indexes other than the index corresponding to the root item, we obtain + a pointer to the relevant item using the method described in the \c index() function, + and use the item's \c parent() function to obtain a pointer to the parent item. + + If no valid parent item exists, or if the parent item is the root item, we can simply + follow convention and return an invalid model index. For all other parent items, we + create a model index containing the appropriate row and column numbers, and a pointer + to the parent item we just obtained. + + Data is provided by the \c data() function. For simplicity, we only provide data for + the \l{Qt::DisplayRole}{display role}, returning an invalid variant for all other + requests: + + \snippet examples/itemviews/simpledommodel/dommodel.cpp 3 + + As before, we obtain an item pointer for the index supplied, and use it to obtain + the underlying document node. Depending on the column specified, the data we return + is obtained in different ways: + + \snippet examples/itemviews/simpledommodel/dommodel.cpp 4 + + For the first column, we return the node's name. For the second column, we read any + attributes that the node may have, and return a string that contains a space-separated + list of attribute-value assignments. For the third column, we return any value that + the node may have; this allows the contents of text nodes to be displayed in a view. + + If data from any other column is requested, an invalid variant is returned. + + \section1 Implementation Notes + + Ideally, we would rely on the structure provided by QDomDocument to help us write + the \l{QAbstractItemModel::parent()}{parent()} and + \l{QAbstractItemModel::index()}{index()} functions that are required when subclassing + QAbstractItemModel. However, since Qt's DOM classes use their own system for + dynamically allocating memory for DOM nodes, we cannot guarantee that the QDomNode + objects returned for a given piece of information will be the same for subsequent + accesses to the document. + + We use item wrappers for each QDomNode to provide consistent pointers that the model + can use to navigate the document structure. + \omit + Since these items contain value references to the QDomNode objects themselves, this + has the side effect that the DOM nodes themselves can be used to reliably navigate + the document [not sure about this - QDom* may return different QDomNode objects for + the same piece of information]. However, this advantage is redundant since we need to + use wrapper items to obtain it. [Possible use of QDomNode cache in the model itself.] + \endomit +*/ diff --git a/doc/src/examples/simpletextviewer.qdoc b/doc/src/examples/simpletextviewer.qdoc new file mode 100644 index 0000000..2a5e45c0 --- /dev/null +++ b/doc/src/examples/simpletextviewer.qdoc @@ -0,0 +1,466 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example help/simpletextviewer + \title Simple Text Viewer Example + + The Simple Text Viewer example shows how to use \QA as a customized + help viewer for your application. + + This is done in two stages. Firstly, documentation is created and \QA + is customized; secondly, the functionality to launch and control + \QA is added to the application. + + \image simpletextviewer-example.png + + The Simple Text Viewer application lets the user select and view + existing files. + + The application provides its own custom documentation that is + available from the \gui Help menu in the main window's menu bar + or by clicking the \gui Help button in the application's find file + dialog. + + The example consists of four classes: + + \list + \o \c Assistant provides functionality to launch \QA. + \o \c MainWindow is the main application window. + \o \c FindFileDialog allows the user to search for + files using wildcard matching. + \o \c TextEdit provides a rich text browser that makes + sure that images referenced in HTML documents are + displayed properly. + \endlist + + Note that we will only comment on the parts of the implementation + that are relevant to the main issue, that is making Qt Assistant + act as a customized help viewer for our Simple Text Viewer + application. + + \section1 Creating Documentation and Customizing \QA + + How to create the actual documentation in the form of HTML pages is + not in the scope of this example. In general, HTML pages can either + be written by hand or generated with the help of documentation tools + like qdoc or Doxygen. For the purposes of this example we assume that + the HTML files have already been created. So, the only thing that + remains to be done is to tell \QA how to structure and display the + help information. + + \section2 Organizing Documentation for \QA + + Plain HTML files only contain text or documentation about specific topics, + but they usually include no information about how several HTML documents + relate to each other or in which order they are supposed to be read. + What is missing is a table of contents along with an index to access + certain help contents quickly, without having to browse through a lot + of documents in order to find a piece of information. + + To organize the documentation and make it available for \QA, we have + to create a Qt help project (.qhp) file. The first and most important + part of the project file is the definition of the namespace. The namespace + has to be unique and will be the first part of the page URL in \QA. + In addition, we have to set a virtual folder which acts as a common + folder for documentation sets. This means, that two documentation sets + identified by two different namespaces can cross reference HTML files + since those files are in one big virtual folder. However, for this + example, we'll only have one documentation set available, so the + virtual folder name and functionality are not important. + + \code + <?xml version="1.0" encoding="UTF-8"?> + <QtHelpProject version="1.0"> + <namespace>com.trolltech.examples.simpletextviewer</namespace> + <virtualFolder>doc</virtualFolder> + \endcode + + The next step is to define the filter section. A filter section + contains the table of contents, indices and a complete list of + all documentation files, and can have any number of filter attributes + assigned to it. A filter attribute is an ordinary string which can + be freely chosen. Later in \QA, users can then define a custom + filter referencing those attributes. If the attributes of a filter + section match the attributes of the custom filter the documentation + will be shown, otherwise \QA will hide the documentation. + + Again, since we'll only have one documentation set, we do not need + the filtering functionality of \QA and can therefore skip the + filter attributes. + + Now, we build up the table of contents. An item in the table is + defined by the \c section tag which contains the attributes for the + item title as well as link to the actual page. Section tags can be + nested infinitely, but for practical reasons it is not recommended + to nest them deeper than three or four levels. For our example we + want to use the following outline for the table of contents: + + \list + \o Simple Text Viewer + \list + \o Find File + \list + \o File Dialog + \o Wildcard Matching + \o Browse + \endlist + \o Open File + \endlist + \endlist + + In the help project file, the outline is represented by: + + \code + <filterSection> + <toc> + <section title="Simple Text Viewer" ref="index.html"> + <section title="Find File" ref="./findfile.html"> + <section title="File Dialog" ref="./filedialog.html"></section> + <section title="Wildcard Matching" ref="./wildcardmatching.html"></section> + <section title="Browse" ref="./browse.html"></section> + </section> + <section title="Open File" ref="./openfile.html"></section> + </section> + </toc> + \endcode + + After the table of contents is defined, we will list all index keywords: + + \code + <keywords> + <keyword name="Display" ref="./index.html"/> + <keyword name="Rich text" ref="./index.html"/> + <keyword name="Plain text" ref="./index.html"/> + <keyword name="Find" ref="./findfile.html"/> + <keyword name="File menu" ref="./findfile.html"/> + <keyword name="File name" ref="./filedialog.html"/> + <keyword name="File dialog" ref="./filedialog.html"/> + <keyword name="File globbing" ref="./wildcardmatching.html"/> + <keyword name="Wildcard matching" ref="./wildcardmatching.html"/> + <keyword name="Wildcard syntax" ref="./wildcardmatching.html"/> + <keyword name="Browse" ref="./browse.html"/> + <keyword name="Directory" ref="./browse.html"/> + <keyword name="Open" ref="./openfile.html"/> + <keyword name="Select" ref="./openfile.html"/> + </keywords> + \endcode + + As the last step, we have to list all files making up the documentation. + An important point to note here is that all files have to listed, including + image files, and even stylesheets if they are used. + + \code + <files> + <file>browse.html</file> + <file>filedialog.html</file> + <file>findfile.html</file> + <file>index.html</file> + <file>intro.html</file> + <file>openfile.html</file> + <file>wildcardmatching.html</file> + <file>images/browse.png</file> + <file>images/fadedfilemenu.png</file> + <file>images/filedialog.png</file> + <file>images/handbook.png</file> + <file>images/mainwindow.png</file> + <file>images/open.png</file> + <file>images/wildcard.png</file> + </files> + </filterSection> + </QtHelpProject> + \endcode + + The help project file is now finished. If you want to see the resulting + documentation in \QA, you have to generate a Qt compressed help file + out of it and register it with the default help collection of \QA. + + \code + qhelpgenerator simpletextviewer.qhp -o simpletextviewer.qch + assistant -register simpletextviewer.qch + \endcode + + If you start \QA now, you'll see the Simple Text Viewer documentation + beside the Qt documentation. This is OK for testing purposes, but + for the final version we want to only have the Simple Text Viewer + documentation in \QA. + + \section2 Customizing \QA + + The easiest way to make \QA only display the Simple Text Viewer + documentation is to create our own help collection file. A collection + file is stored in a binary format, similar to the compressed help file, + and generated from a help collection project file (*.qhcp). With + the help of a collection file, we can customize the appearance and even + some functionality offered by \QA. + + At first, we change the window title and icon. Instead of showing "\QA" + it will show "Simple Text Viewer", so it is much clearer for the user + that the help viewer actually belongs to our application. + + \code + <?xml version="1.0" encoding="UTF-8"?> + <QHelpCollectionProject version="1.0"> + <assistant> + <title>Simple Text Viewer</title> + <applicationIcon>images/handbook.png</applicationIcon> + <cacheDirectory>Trolltech/SimpleTextViewer</cacheDirectory> + \endcode + + The \c cacheDirectory tag specifies a subdirectory of the users + data directory (see the + \l{Using Qt Assistant as a Custom Help Viewer#Qt Help Collection Files}{Qt Help Collection Files}) + where the cache file for the full text search or the settings file will + be stored. + + After this, we set the page displayed by \QA when launched for the very + first time in its new configuration. The URL consists of the namespace + and virtual folder defined in the Qt help project file, followed by the + actual page file name. + + \code + <startPage>qthelp://com.trolltech.examples.simpletextviewer/doc/index.html</startPage> + \endcode + + Next, we alter the name of the "About" menu item to "About Simple + Text Viewer". The contents of the \gui{About} dialog are also changed + by specifying a file where the about text or icon is taken from. + + \code + <aboutMenuText> + <text>About Simple Text Viewer</text> + </aboutMenuText> + <aboutDialog> + <file>about.txt</file> + <icon>images/icon.png</icon> + </aboutDialog> + \endcode + + \QA offers the possibility to add or remove documentation via its + preferences dialog. This functionality is helpful when using \QA + as the central help viewer for more applications, but in our case + we want to actually prevent the user from removing the documentation. + So, we disable the documentation manager. + + Since the address bar is not really relevant in such a small + documentation set we switch it off as well. By having just one filter + section, without any filter attributes, we can also disable the filter + functionality of \QA, which means that the filter page and the filter + toolbar will not be available. + + \code + <enableDocumentationManager>false</enableDocumentationManager> + <enableAddressBar>false</enableAddressBar> + <enableFilterFunctionality>false</enableFilterFunctionality> + </assistant> + \endcode + + For testing purposes, we already generated the compressed help file + and registered it with \QA's default help collection. With the + following lines we achieve the same result. The only and important + difference is that we register the compressed help file, not in + the default collection, but in our own collection file. + + \code + <docFiles> + <generate> + <file> + <input>simpletextviewer.qhp</input> + <output>simpletextviewer.qch</output> + </file> + </generate> + <register> + <file>simpletextviewer.qch</file> + </register> + </docFiles> + </QHelpCollectionProject> + \endcode + + As the last step, we have to generate the binary collection file + out of the help collection project file. This is done by running the + \c qcollectiongenerator tool. + + \code + qcollectiongenerator simpletextviewer.qhcp -o simpletextviewer.qhc + \endcode + + To test all our customizations made to \QA, we add the collection + file name to the command line: + + \code + assistant -collectionFile simpletextviewer.qhc + \endcode + + \section1 Controlling \QA via the Assistant Class + + We will first take a look at how to start and operate \QA from a + remote application. For that purpose, we create a class called + \c Assistant. + + This class provides a public function that is used to show pages + of the documentation, and one private helper function to make sure + that \QA is up and running. + + Launching \QA is done in the function \c startAssistant() by simply + creating and starting a QProcess. If the process is already running, + the function returns immediately. Otherwise, the process has + to be set up and started. + + \snippet examples/help/simpletextviewer/assistant.cpp 2 + + To start the process we need the executable name of \QA as well as the + command line arguments for running \QA in a customized mode. The + executable name is a little bit tricky since it depends on the + platform, but fortunately it is only different on Mac OS X. + + The displayed documentation can be altered using the \c -collectionFile + command line argument when launching \QA. When started without any options, + \QA displays a default set of documentation. When Qt is installed, + the default documentation set in \QA contains the Qt reference + documentation as well as the tools that come with Qt, such as Qt + Designer and \c qmake. + + In our example, we replace the default documentation set with our + custom documentation by passing our application-specific collection + file to the process's command line options. + + As the last argument, we add \c -enableRemoteControl, which makes \QA + listen to its \c stdin channel for commands, such as those to display + a certain page in the documentation. + Then we start the process and wait until it is actually running. If, + for some reason \QA cannot be started, \c startAssistant() will return + false. + + The implementation for \c showDocumentation() is now straightforward. + Firstly, we ensure that \QA is running, then we send the request to + display the \a page via the \c stdin channel of the process. It is very + important here that the command is terminated by the '\\0' character + followed by an end of line token to flush the channel. + + \snippet examples/help/simpletextviewer/assistant.cpp 1 + + Finally, we make sure that \QA is terminated properly in the case that + the application is shut down. The destructor of QProcess kills the + process, meaning that the application has no possibility to do things + like save user settings, which would result in corrupted settings files. + To avoid this, we ask \QA to terminate in the destructor of the + \c Assistant class. + + \snippet examples/help/simpletextviewer/assistant.cpp 0 + + \section1 MainWindow Class + + \image simpletextviewer-mainwindow.png + + The \c MainWindow class provides the main application window with + two menus: the \gui File menu lets the user open and view an + existing file, while the \gui Help menu provides information about + the application and about Qt, and lets the user open \QA to + display the application's documentation. + + To be able to access the help functionality, we initialize the + \c Assistant object in the \c MainWindow's constructor. + + \snippet examples/help/simpletextviewer/mainwindow.cpp 0 + \dots + \snippet examples/help/simpletextviewer/mainwindow.cpp 1 + + Then we create all the actions for the Simple Text Viewer application. + Of special interest is the \c assistantAct action accessible + via the \key{F1} shortcut or the \menu{Help|Help Contents} menu item. + This action is connected to the \c showDocumentation() slot of + the \c MainWindow class. + + \snippet examples/help/simpletextviewer/mainwindow.cpp 4 + \dots + \snippet examples/help/simpletextviewer/mainwindow.cpp 5 + + In the \c showDocumentation() slot, we call the \c showDocumentation() + function of the \c Assistant class with the URL of home page of the + documentation. + + \snippet examples/help/simpletextviewer/mainwindow.cpp 3 + + Finally, we must reimplement the protected QWidget::closeEvent() + event handler to ensure that the application's \QA instance is + properly closed before we terminate the application. + + \snippet examples/help/simpletextviewer/mainwindow.cpp 2 + + \section1 FindFileDialog Class + + \image simpletextviewer-findfiledialog.png + + The Simple Text Viewer application provides a find file dialog + allowing the user to search for files using wildcard matching. The + search is performed within the specified directory, and the user + is given an option to browse the existing file system to find the + relevant directory. + + In the constructor we save the references to the \c Assistant + and \c QTextEdit objects passed as arguments. The \c Assistant + object will be used in the \c FindFileDialog's \c help() slot, + as we will see shortly, while the QTextEdit will be used in the + dialog's \c openFile() slot to display the chosen file. + + \snippet examples/help/simpletextviewer/findfiledialog.cpp 0 + \dots + \snippet examples/help/simpletextviewer/findfiledialog.cpp 1 + + The most relevant member to observe in the \c FindFileDialog + class is the private \c help() slot. The slot is connected to the + dialog's \gui Help button, and brings the current \QA instance + to the foreground with the documentation for the dialog by + calling \c Assistant's \c showDocumentation() function. + + \snippet examples/help/simpletextviewer/findfiledialog.cpp 2 + + \section1 Summary + + In order to make \QA act as a customized help tool for + your application, you must provide your application with a + process that controls \QA in addition to a custom help collection + file including Qt compressed help files. + + The \l{Using Qt Assistant as a Custom Help Viewer} document contains + more information about the options and settings available to + applications that use \QA as a custom help viewer. +*/ diff --git a/doc/src/examples/simpletreemodel.qdoc b/doc/src/examples/simpletreemodel.qdoc new file mode 100644 index 0000000..5ddeb46 --- /dev/null +++ b/doc/src/examples/simpletreemodel.qdoc @@ -0,0 +1,346 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/simpletreemodel + \title Simple Tree Model Example + + The Simple Tree Model example shows how to create a basic, read-only + hierarchical model to use with Qt's standard view classes. For a + description of simple non-hierarchical list and table models, see the + \l{model-view-programming.html}{Model/View Programming} overview. + + \image simpletreemodel-example.png + + Qt's model/view architecture provides a standard way for views to manipulate + information in a data source, using an abstract model of the data to + simplify and standardize the way it is accessed. Simple models represent + data as a table of items, and allow views to access this data via an + \l{model-view-model.html}{index-based} system. More generally, models can + be used to represent data in the form of a tree structure by allowing each + item to act as a parent to a table of child items. + + Before attempting to implement a tree model, it is worth considering whether + the data is supplied by an external source, or whether it is going to be + maintained within the model itself. In this example, we will implement an + internal structure to hold data rather than discuss how to package data from + an external source. + + \section1 Design and Concepts + + The data structure that we use to represent the structure of the data takes + the form of a tree built from \c TreeItem objects. Each \c TreeItem + represents an item in a tree view, and contains several columns of data. + + \target SimpleTreeModelStructure + \table + \row \i \inlineimage treemodel-structure.png + \i \bold{Simple Tree Model Structure} + + The data is stored internally in the model using \c TreeItem objects that + are linked together in a pointer-based tree structure. Generally, each + \c TreeItem has a parent item, and can have a number of child items. + However, the root item in the tree structure has no parent item and it + is never referenced outside the model. + + Each \c TreeItem contains information about its place in the tree + structure; it can return its parent item and its row number. Having + this information readily available makes implementing the model easier. + + Since each item in a tree view usually contains several columns of data + (a title and a summary in this example), it is natural to store this + information in each item. For simplicity, we will use a list of QVariant + objects to store the data for each column in the item. + \endtable + + The use of a pointer-based tree structure means that, when passing a + model index to a view, we can record the address of the corresponding + item in the index (see QAbstractItemModel::createIndex()) and retrieve + it later with QModelIndex::internalPointer(). This makes writing the + model easier and ensures that all model indexes that refer to the same + item have the same internal data pointer. + + With the appropriate data structure in place, we can create a tree model + with a minimal amount of extra code to supply model indexes and data to + other components. + + \section1 TreeItem Class Definition + + The \c TreeItem class is defined as follows: + + \snippet examples/itemviews/simpletreemodel/treeitem.h 0 + + The class is a basic C++ class. It does not inherit from QObject or + provide signals and slots. It is used to hold a list of QVariants, + containing column data, and information about its position in the tree + structure. The functions provide the following features: + + \list + \o The \c appendChildItem() is used to add data when the model is first + constructed and is not used during normal use. + \o The \c child() and \c childCount() functions allow the model to obtain + information about any child items. + \o Information about the number of columns associated with the item is + provided by \c columnCount(), and the data in each column can be + obtained with the data() function. + \o The \c row() and \c parent() functions are used to obtain the item's + row number and parent item. + \endlist + + The parent item and column data are stored in the \c parentItem and + \c itemData private member variables. The \c childItems variable contains + a list of pointers to the item's own child items. + + \section1 TreeItem Class Implementation + + The constructor is only used to record the item's parent and the data + associated with each column. + + \snippet examples/itemviews/simpletreemodel/treeitem.cpp 0 + + A pointer to each of the child items belonging to this item will be + stored in the \c childItems private member variable. When the class's + destructor is called, it must delete each of these to ensure that + their memory is reused: + + \snippet examples/itemviews/simpletreemodel/treeitem.cpp 1 + + Since each of the child items are constructed when the model is initially + populated with data, the function to add child items is straightforward: + + \snippet examples/itemviews/simpletreemodel/treeitem.cpp 2 + + Each item is able to return any of its child items when given a suitable + row number. For example, in the \l{#SimpleTreeModelStructure}{above diagram}, + the item marked with the letter "A" corresponds to the child of the root item + with \c{row = 0}, the "B" item is a child of the "A" item with \c{row = 1}, + and the "C" item is a child of the root item with \c{row = 1}. + + The \c child() function returns the child that corresponds to + the specified row number in the item's list of child items: + + \snippet examples/itemviews/simpletreemodel/treeitem.cpp 3 + + The number of child items held can be found with \c childCount(): + + \snippet examples/itemviews/simpletreemodel/treeitem.cpp 4 + + The \c TreeModel uses this function to determine the number of rows that + exist for a given parent item. + + The \c row() function reports the item's location within its parent's + list of items: + + \snippet examples/itemviews/simpletreemodel/treeitem.cpp 8 + + Note that, although the root item (with no parent item) is automatically + assigned a row number of 0, this information is never used by the model. + + The number of columns of data in the item is trivially returned by the + \c columnCount() function. + + \snippet examples/itemviews/simpletreemodel/treeitem.cpp 5 + + Column data is returned by the \c data() function, taking advantage of + QList's ability to provide sensible default values if the column number + is out of range: + + \snippet examples/itemviews/simpletreemodel/treeitem.cpp 6 + + The item's parent is found with \c parent(): + + \snippet examples/itemviews/simpletreemodel/treeitem.cpp 7 + + Note that, since the root item in the model will not have a parent, this + function will return zero in that case. We need to ensure that the model + handles this case correctly when we implement the \c TreeModel::parent() + function. + + \section1 TreeModel Class Definition + + The \c TreeModel class is defined as follows: + + \snippet examples/itemviews/simpletreemodel/treemodel.h 0 + + This class is similar to most other subclasses of QAbstractItemModel that + provide read-only models. Only the form of the constructor and the + \c setupModelData() function are specific to this model. In addition, we + provide a destructor to clean up when the model is destroyed. + + \section1 TreeModel Class Implementation + + For simplicity, the model does not allow its data to be edited. As a + result, the constructor takes an argument containing the data that the + model will share with views and delegates: + + \snippet examples/itemviews/simpletreemodel/treemodel.cpp 0 + + It is up to the constructor to create a root item for the model. This + item only contains vertical header data for convenience. We also use it + to reference the internal data structure that contains the model data, + and it is used to represent an imaginary parent of top-level items in + the model. + + The model's internal data structure is populated with items by the + \c setupModelData() function. We will examine this function separately + at the end of this document. + + The destructor ensures that the root item and all of its descendants + are deleted when the model is destroyed: + + \snippet examples/itemviews/simpletreemodel/treemodel.cpp 1 + + Since we cannot add data to the model after it is constructed and set + up, this simplifies the way that the internal tree of items is managed. + + Models must implement an \c index() function to provide indexes for + views and delegates to use when accessing data. Indexes are created + for other components when they are referenced by their row and column + numbers, and their parent model index. If an invalid model + index is specified as the parent, it is up to the model to return an + index that corresponds to a top-level item in the model. + + When supplied with a model index, we first check whether it is valid. + If it is not, we assume that a top-level item is being referred to; + otherwise, we obtain the data pointer from the model index with its + \l{QModelIndex::internalPointer()}{internalPointer()} function and use + it to reference a \c TreeItem object. Note that all the model indexes + that we construct will contain a pointer to an existing \c TreeItem, + so we can guarantee that any valid model indexes that we receive will + contain a valid data pointer. + + \snippet examples/itemviews/simpletreemodel/treemodel.cpp 6 + + Since the row and column arguments to this function refer to a + child item of the corresponding parent item, we obtain the item using + the \c TreeItem::child() function. The + \l{QAbstractItemModel::createIndex()}{createIndex()} function is used + to create a model index to be returned. We specify the row and column + numbers, and a pointer to the item itself. The model index can be used + later to obtain the item's data. + + The way that the \c TreeItem objects are defined makes writing the + \c parent() function easy: + + \snippet examples/itemviews/simpletreemodel/treemodel.cpp 7 + + We only need to ensure that we never return a model index corresponding + to the root item. To be consistent with the way that the \c index() + function is implemented, we return an invalid model index for the + parent of any top-level items in the model. + + When creating a model index to return, we must specify the row and + column numbers of the parent item within its own parent. We can + easily discover the row number with the \c TreeItem::row() function, + but we follow a convention of specifying 0 as the column number of + the parent. The model index is created with + \l{QAbstractItemModel::createIndex()}{createIndex()} in the same way + as in the \c index() function. + + The \c rowCount() function simply returns the number of child items + for the \c TreeItem that corresponds to a given model index, or the + number of top-level items if an invalid index is specified: + + \snippet examples/itemviews/simpletreemodel/treemodel.cpp 8 + + Since each item manages its own column data, the \c columnCount() + function has to call the item's own \c columnCount() function to + determine how many columns are present for a given model index. + As with the \c rowCount() function, if an invalid model index is + specified, the number of columns returned is determined from the + root item: + + \snippet examples/itemviews/simpletreemodel/treemodel.cpp 2 + + Data is obtained from the model via \c data(). Since the item manages + its own columns, we need to use the column number to retrieve the data + with the \c TreeItem::data() function: + + \snippet examples/itemviews/simpletreemodel/treemodel.cpp 3 + + Note that we only support the \l{Qt::ItemDataRole}{DisplayRole} + in this implementation, and we also return invalid QVariant objects for + invalid model indexes. + + We use the \c flags() function to ensure that views know that the + model is read-only: + + \snippet examples/itemviews/simpletreemodel/treemodel.cpp 4 + + The \c headerData() function returns data that we conveniently stored + in the root item: + + \snippet examples/itemviews/simpletreemodel/treemodel.cpp 5 + + This information could have been supplied in a different way: either + specified in the constructor, or hard coded into the \c headerData() + function. + + \section1 Setting Up the Data in the Model + + We use the \c setupModelData() function to set up the initial data in + the model. This function parses a text file, extracting strings of + text to use in the model, and creates item objects that record both + the data and the overall model structure. + Naturally, this function works in a way that is very specific to + this model. We provide the following description of its behavior, + and refer the reader to the example code itself for more information. + + We begin with a text file in the following format: + + \snippet doc/src/snippets/code/doc_src_examples_simpletreemodel.qdoc 0 + \dots + \snippet doc/src/snippets/code/doc_src_examples_simpletreemodel.qdoc 1 + + We process the text file with the following two rules: + + \list + \o For each pair of strings on each line, create an item (or node) + in a tree structure, and place each string in a column of data + in the item. + \o When the first string on a line is indented with respect to the + first string on the previous line, make the item a child of the + previous item created. + \endlist + + To ensure that the model works correctly, it is only necessary to + create instances of \c TreeItem with the correct data and parent item. +*/ diff --git a/doc/src/examples/simplewidgetmapper.qdoc b/doc/src/examples/simplewidgetmapper.qdoc new file mode 100644 index 0000000..2fdbf25 --- /dev/null +++ b/doc/src/examples/simplewidgetmapper.qdoc @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/simplewidgetmapper + \title Simple Widget Mapper Example + + The Simple Widget Mapper example shows how to use a widget mapper to display + data from a model in a collection of widgets. + + \image simplewidgetmapper-example.png + + The QDataWidgetMapper class allows information obtained from a + \l{Model Classes}{model} to be viewed and edited in a collection of + widgets instead of in an \l{View Classes}{item view}. + Any model derived from QAbstractItemModel can be used as the source of + data and almost any input widget can be used to display it. + + The example itself is very simple: we create \c Window, a QWidget subclass + that we use to hold the widgets used to present the data, and show it. The + \c Window class will provide buttons that the user can click to show + different records from the model. + + \section1 Window Class Definition + + The class provides a constructor, a slot to keep the buttons up to date, + and a private function to set up the model: + + \snippet examples/itemviews/simplewidgetmapper/window.h Window definition + + In addition to the QDataWidgetMapper object and the controls used to make + up the user interface, we use a QStandardItemModel to hold our data. + We could use a custom model, but this standard implementation is sufficient + for our purposes. + + \section1 Window Class Implementation + + The constructor of the \c Window class can be explained in three parts. + In the first part, we set up the widgets used for the user interface: + + \snippet examples/itemviews/simplewidgetmapper/window.cpp Set up widgets + + We also set up the buddy relationships between various labels and the + corresponding input widgets. + + Next, we set up the widget mapper, relating each input widget to a column + in the model specified by the call to \l{QDataWidgetMapper::}{setModel()}: + + \snippet examples/itemviews/simplewidgetmapper/window.cpp Set up the mapper + + We also connect the mapper to the \gui{Next} and \gui{Previous} buttons + via its \l{QDataWidgetMapper::}{toNext()} and + \l{QDataWidgetMapper::}{toPrevious()} slots. The mapper's + \l{QDataWidgetMapper::}{currentIndexChanged()} signal is connected to the + \c{updateButtons()} slot in the window which we'll show later. + + In the final part of the constructor, we set up the layout, placing each + of the widgets in a grid (we could also use a QFormLayout for this): + + \snippet examples/itemviews/simplewidgetmapper/window.cpp Set up the layout + + Lastly, we set the window title and initialize the mapper by setting it to + refer to the first row in the model. + + The model is initialized in the window's \c{setupModel()} function. Here, + we create a standard model with 5 rows and 3 columns, and we insert some + sample names, addresses and ages into each row: + + \snippet examples/itemviews/simplewidgetmapper/window.cpp Set up the model + + As a result, each row can be treated like a record in a database, and the + widget mapper will read the data from each row, using the column numbers + specified earlier to access the correct data for each widget. This is + shown in the following diagram: + + \image widgetmapper-simple-mapping.png + + Since the user can navigate using the buttons in the user interface, the + example is fully-functional at this point, but to make it a bit more + user-friendly, we implement the \c{updateButtons()} slot to show when the + user is viewing the first or last records: + + \snippet examples/itemviews/simplewidgetmapper/window.cpp Slot for updating the buttons + + If the mapper is referring to the first row in the model, the \gui{Previous} + button is disabled. Similarly, the \gui{Next} button is disabled if the + mapper reaches the last row in the model. + + \section1 More Complex Mappings + + The QDataWidgetMapper class makes it easy to relate information from a + model to widgets in a user interface. However, it is sometimes necessary + to use input widgets which offer choices to the user, such as QComboBox, + in conjunction with a widget mapper. + + In these situations, although the mapping to input widgets remains simple, + more work needs to be done to expose additional data to the widget mapper. + This is covered by the \l{Combo Widget Mapper Example}{Combo Widget Mapper} + and \l{SQL Widget Mapper Example}{SQL Widget Mapper} + examples. +*/ diff --git a/doc/src/examples/sipdialog.qdoc b/doc/src/examples/sipdialog.qdoc new file mode 100644 index 0000000..817f5e2 --- /dev/null +++ b/doc/src/examples/sipdialog.qdoc @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example dialogs/sipdialog + \title SIP Dialog Example + \ingroup qtce + + The SIP Dialog example shows how to create a dialog that is aware of + the Windows Mobile SIP (Software Input Panel) and reacts to it. + + \table + \row \o \inlineimage sipdialog-closed.png + \o \inlineimage sipdialog-opened.png + \endtable + + Sometimes it is necessary for a dialog to take the SIP into account, + as the SIP may hide important input widgets. The SIP Dialog Example + shows how a \c Dialog object, \c dialog, can be resized accordingly + if the SIP is opened, by embedding the contents of \c dialog in a + QScrollArea. + + \section1 Dialog Class Definition + + The \c Dialog class is a subclass of QDialog that implements a public + slot, \c desktopResized(), and a public function, \c reactToSIP(). Also, + it holds a private instance of QRect, \c desktopGeometry. + + \snippet dialogs/sipdialog/dialog.h Dialog header + + \section1 Dialog Class Implementation + + In the constructor of \c Dialog, we start by obtaining the + available geometry of the screen with + \l{QDesktopWidget::availableGeometry()}{availableGeometry()}. The + parameter used is \c 0 to indicate that we require the primary screen. + + \snippet dialogs/sipdialog/dialog.cpp Dialog constructor part1 + + We set the window's title to "SIP Dialog Example" and declare a QScrollArea + object, \c scrollArea. Next we instantiate a QGroupBox, \c groupBox, with + \c scrollArea as its parent. The title of \c groupBox is also set to + "SIP Dialog Example". A QGridLayout object, \c gridLayout, is then used + as \c{groupBox}'s layout. + + We create a QLineEdit, a QLabel and a QPushButton and we set the + \l{QWidget::setMinimumWidth()}{minimumWidth} property to 220 pixels, + respectively. + + \snippet dialogs/sipdialog/dialog.cpp Dialog constructor part2 + + Also, all three widgets' text are set accordingly. The + \l{QGridLayout::setVerticalSpacing()}{verticalSpacing} property of + \c gridLayout is set based on the height of \c desktopGeometry. This + is to adapt to the different form factors of Windows Mobile. Then, we + add our widgets to the layout. + + \snippet dialogs/sipdialog/dialog.cpp Dialog constructor part3 + + The \c{scrollArea}'s widget is set to \c groupBox. We use a QHBoxLayout + object, \c layout, to contain \c scrollArea. The \c{Dialog}'s layout + is set to \c layout and the scroll area's horizontal scroll bar is turned + off. + + \snippet dialogs/sipdialog/dialog.cpp Dialog constructor part4 + + The following signals are connected to their respective slots: + \list + \o \c{button}'s \l{QPushButton::pressed()}{pressed()} signal to + \l{QApplication}'s \l{QApplication::closeAllWindows()} + {closeAllWindows()} slot, + \o \l{QDesktopWidget}'s \l{QDesktopWidget::workAreaResized()} + {workAreaResized()} signal to \c{dialog}'s \c desktopResized() slot. + \endlist + + \snippet dialogs/sipdialog/dialog.cpp Dialog constructor part5 + + The \c desktopResized() function accepts an integer, \a screen, + corresponding to the screen's index. We only invoke \c reactToSIP() + if \a screen is the primary screen (e.g. index = 0). + + \snippet dialogs/sipdialog/dialog.cpp desktopResized() function + + The \c reactToSIP() function resizes \c dialog accordingly if the + desktop's available geometry changed vertically, as this change signifies + that the SIP may have been opened or closed. + + \snippet dialogs/sipdialog/dialog.cpp reactToSIP() function + + If the height has decreased, we unset the maximized window state. + Otherwise, we set the maximized window state. Lastly, we update + \c desktopGeometry to the desktop's available geometry. + + \section1 The \c main() function + + The \c main() function for the SIP Dialog example instantiates \c Dialog + and invokes its \l{QDialog::exec()}{exec()} function. + + \snippet dialogs/sipdialog/main.cpp main() function + + \note Although this example uses a dialog, the techniques used here apply to + all top-level widgets respectively. +*/ diff --git a/doc/src/examples/sliders.qdoc b/doc/src/examples/sliders.qdoc new file mode 100644 index 0000000..650fdcb --- /dev/null +++ b/doc/src/examples/sliders.qdoc @@ -0,0 +1,269 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/sliders + \title Sliders Example + + Qt provides three types of slider-like widgets: QSlider, + QScrollBar and QDial. They all inherit most of their + functionality from QAbstractSlider, and can in theory replace + each other in an application since the differences only concern + their look and feel. This example shows what they look like, how + they work and how their behavior and appearance can be + manipulated through their properties. + + The example also demonstrates how signals and slots can be used to + synchronize the behavior of two or more widgets. + + \image sliders-example.png Screenshot of the Sliders example + + The Sliders example consists of two classes: + + \list + + \o \c SlidersGroup is a custom widget. It combines a QSlider, a + QScrollBar and a QDial. + + \o \c Window is the main widget combining a QGroupBox and a + QStackedWidget. In this example, the QStackedWidget provides a + stack of two \c SlidersGroup widgets. The QGroupBox contain + several widgets that control the behavior of the slider-like + widgets. + + \endlist + + First we will review the \c Window class, then we + will take a look at the \c SlidersGroup class. + + \section1 Window Class Definition + + \snippet examples/widgets/sliders/window.h 0 + + The \c Window class inherits from QWidget. It displays the slider + widgets and allows the user to set their minimum, maximum and + current values and to customize their appearance, key bindings + and orientation. We use a private \c createControls() function to + create the widgets that provide these controlling mechanisms and + to connect them to the slider widgets. + + \section1 Window Class Implementation + + \snippet examples/widgets/sliders/window.cpp 0 + + In the constructor we first create the two \c SlidersGroup + widgets that display the slider widgets horizontally and + vertically, and add them to the QStackedWidget. QStackedWidget + provides a stack of widgets where only the top widget is visible. + With \c createControls() we create a connection from a + controlling widget to the QStackedWidget, making the user able to + choose between horizontal and vertical orientation of the slider + widgets. The rest of the controlling mechanisms is implemented by + the same function call. + + \snippet examples/widgets/sliders/window.cpp 1 + \snippet examples/widgets/sliders/window.cpp 2 + + Then we connect the \c horizontalSliders, \c verticalSliders and + \c valueSpinBox to each other, so that the slider widgets and the + control widget will behave synchronized when the current value of + one of them changes. The \c valueChanged() signal is emitted with + the new value as argument. The \c setValue() slot sets the + current value of the widget to the new value, and emits \c + valueChanged() if the new value is different from the old one. + + We put the group of control widgets and the stacked widget in a + horizontal layout before we initialize the minimum, maximum and + current values. The initialization of the current value will + propagate to the slider widgets through the connection we made + between \c valueSpinBox and the \c SlidersGroup widgets. The + minimum and maximum values propagate through the connections we + created with \c createControls(). + + \snippet examples/widgets/sliders/window.cpp 3 + \snippet examples/widgets/sliders/window.cpp 4 + + In the private \c createControls() function, we let a QGroupBox + (\c controlsGroup) display the control widgets. A group box can + provide a frame, a title and a keyboard shortcut, and displays + various other widgets inside itself. The group of control widgets + is composed by two checkboxes, three spin boxes (with labels) and + one combobox. + + After creating the labels, we create the two checkboxes. + Checkboxes are typically used to represent features in an + application that can be enabled or disabled. When \c + invertedAppearance is enabled, the slider values are inverted. + The table below shows the appearance for the different + slider-like widgets: + + \table + \header \o \o{2,1} QSlider \o{2,1} QScrollBar \o{2,1} QDial + \header \o \o Normal \o Inverted \o Normal \o Inverted \o Normal \o Inverted + \row \o Qt::Horizontal \o Left to right \o Right to left \o Left to right \o Right to left \o Clockwise \o Counterclockwise + \row \o Qt::Vertical \o Bottom to top \o Top to bottom \o Top to bottom \o Bottom to top \o Clockwise \o Counterclockwise + \endtable + + It is common to invert the appearance of a vertical QSlider. A + vertical slider that controls volume, for example, will typically + go from bottom to top (the non-inverted appearance), whereas a + vertical slider that controls the position of an object on screen + might go from top to bottom, because screen coordinates go from + top to bottom. + + When the \c invertedKeyBindings option is enabled (corresponding + to the QAbstractSlider::invertedControls property), the slider's + wheel and key events are inverted. The normal key bindings mean + that scrolling the mouse wheel "up" or using keys like page up + will increase the slider's current value towards its maximum. + Inverted, the same wheel and key events will move the value + toward the slider's minimum. This can be useful if the \e + appearance of a slider is inverted: Some users might expect the + keys to still work the same way on the value, whereas others + might expect \key PageUp to mean "up" on the screen. + + Note that for horizontal and vertical scroll bars, the key + bindings are inverted by default: \key PageDown increases the + current value, and \key PageUp decreases it. + + \snippet examples/widgets/sliders/window.cpp 5 + \snippet examples/widgets/sliders/window.cpp 6 + + Then we create the spin boxes. QSpinBox allows the user to choose + a value by clicking the up and down buttons or pressing the \key + Up and \key Down keys on the keyboard to modify the value + currently displayed. The user can also type in the value + manually. The spin boxes control the minimum, maximum and current + values for the QSlider, QScrollBar, and QDial widgets. + + We create a QComboBox that allows the user to choose the + orientation of the slider widgets. The QComboBox widget is a + combined button and popup list. It provides a means of presenting + a list of options to the user in a way that takes up the minimum + amount of screen space. + + \snippet examples/widgets/sliders/window.cpp 7 + \snippet examples/widgets/sliders/window.cpp 8 + + We synchronize the behavior of the control widgets and the slider + widgets through their signals and slots. We connect each control + widget to both the horizontal and vertical group of slider + widgets. We also connect \c orientationCombo to the + QStackedWidget, so that the correct "page" is shown. Finally, we + lay out the control widgets in a QGridLayout within the \c + controlsGroup group box. + + \section1 SlidersGroup Class Definition + + \snippet examples/widgets/sliders/slidersgroup.h 0 + + The \c SlidersGroup class inherits from QGroupBox. It provides a + frame and a title, and contains a QSlider, a QScrollBar and a + QDial. + + We provide a \c valueChanged() signal and a public \c setValue() + slot with equivalent functionality to the ones in QAbstractSlider + and QSpinBox. In addition, we implement several other public + slots to set the minimum and maximum value, and invert the slider + widgets' appearance as well as key bindings. + + \section1 SlidersGroup Class Implementation + + \snippet examples/widgets/sliders/slidersgroup.cpp 0 + + First we create the slider-like widgets with the appropiate + properties. In particular we set the focus policy for each + widget. Qt::FocusPolicy is an enum type that defines the various + policies a widget can have with respect to acquiring keyboard + focus. The Qt::StrongFocus policy means that the widget accepts + focus by both tabbing and clicking. + + Then we connect the widgets with each other, so that they will + stay synchronized when the current value of one of them changes. + + \snippet examples/widgets/sliders/slidersgroup.cpp 1 + \snippet examples/widgets/sliders/slidersgroup.cpp 2 + + We connect \c {dial}'s \c valueChanged() signal to the + \c{SlidersGroup}'s \c valueChanged() signal, to notify the other + widgets in the application (i.e., the control widgets) of the + changed value. + + \snippet examples/widgets/sliders/slidersgroup.cpp 3 + \codeline + \snippet examples/widgets/sliders/slidersgroup.cpp 4 + + Finally, depending on the \l {Qt::Orientation}{orientation} given + at the time of construction, we choose and create the layout for + the slider widgets within the group box. + + \snippet examples/widgets/sliders/slidersgroup.cpp 5 + \snippet examples/widgets/sliders/slidersgroup.cpp 6 + + The \c setValue() slot sets the value of the QSlider. We don't + need to explicitly call + \l{QAbstractSlider::setValue()}{setValue()} on the QScrollBar and + QDial widgets, since QSlider will emit the + \l{QAbstractSlider::valueChanged()}{valueChanged()} signal when + its value changes, triggering a domino effect. + + \snippet examples/widgets/sliders/slidersgroup.cpp 7 + \snippet examples/widgets/sliders/slidersgroup.cpp 8 + \codeline + \snippet examples/widgets/sliders/slidersgroup.cpp 9 + \snippet examples/widgets/sliders/slidersgroup.cpp 10 + + The \c setMinimum() and \c setMaximum() slots are used by the \c + Window class to set the range of the QSlider, QScrollBar, and + QDial widgets. + + \snippet examples/widgets/sliders/slidersgroup.cpp 11 + \snippet examples/widgets/sliders/slidersgroup.cpp 12 + \codeline + \snippet examples/widgets/sliders/slidersgroup.cpp 13 + \snippet examples/widgets/sliders/slidersgroup.cpp 14 + + The \c invertAppearance() and \c invertKeyBindings() slots + control the child widgets' + \l{QAbstractSlider::invertedAppearance}{invertedAppearance} and + \l{QAbstractSlider::invertedControls}{invertedControls} + properties. +*/ diff --git a/doc/src/examples/spinboxdelegate.qdoc b/doc/src/examples/spinboxdelegate.qdoc new file mode 100644 index 0000000..542eebd --- /dev/null +++ b/doc/src/examples/spinboxdelegate.qdoc @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/spinboxdelegate + \title Spin Box Delegate Example + + The Spin Box Delegate example shows how to create an editor for a custom delegate in + the model/view framework by reusing a standard Qt editor widget. + + The model/view framework provides a standard delegate that is used by default + with the standard view classes. For most purposes, the selection of editor + widgets available through this delegate is sufficient for editing text, boolean + values, and other simple data types. However, for specific data types, it is + sometimes necessary to use a custom delegate to either display the data in a + specific way, or allow the user to edit it with a custom control. + + \image spinboxdelegate-example.png + + This concepts behind this example are covered in the + \l{model-view-delegate.html}{Delegate Classes} chapter of the + \l{model-view-programming.html}{Model/View Programming} overview. + + \section1 SpinBoxDelegate Class Definition + + The definition of the delegate is as follows: + + \snippet examples/itemviews/spinboxdelegate/delegate.h 0 + + The delegate class declares only those functions that are needed to + create an editor widget, display it at the correct location in a view, + and communicate with a model. Custom delegates can also provide their + own painting code by reimplementing the \c paintEvent() function. + + \section1 SpinBoxDelegate Class Implementation + + Since the delegate is stateless, the constructor only needs to + call the base class's constructor with the parent QObject as its + argument: + + \snippet examples/itemviews/spinboxdelegate/delegate.cpp 0 + + Since the delegate is a subclass of QItemDelegate, the data it retrieves + from the model is displayed in a default style, and we do not need to + provide a custom \c paintEvent(). + + The \c createEditor() function returns an editor widget, in this case a + spin box that restricts values from the model to integers from 0 to 100 + inclusive. + + \snippet examples/itemviews/spinboxdelegate/delegate.cpp 1 + + We install an event filter on the spin box to ensure that it behaves in + a way that is consistent with other delegates. The implementation for + the event filter is provided by the base class. + + The \c setEditorData() function reads data from the model, converts it + to an integer value, and writes it to the editor widget. + + \snippet examples/itemviews/spinboxdelegate/delegate.cpp 2 + + Since the view treats delegates as ordinary QWidget instances, we have + to use a static cast before we can set the value in the spin box. + + The \c setModelData() function reads the contents of the spin box, and + writes it to the model. + + \snippet examples/itemviews/spinboxdelegate/delegate.cpp 3 + + We call \l{QSpinBox::interpretText()}{interpretText()} to make sure that + we obtain the most up-to-date value in the spin box. + + The \c updateEditorGeometry() function updates the editor widget's + geometry using the information supplied in the style option. This is the + minimum that the delegate must do in this case. + + \snippet examples/itemviews/spinboxdelegate/delegate.cpp 4 + + More complex editor widgets may divide the rectangle available in + \c{option.rect} between different child widgets if required. + + \section1 The Main Function + + This example is written in a slightly different way to many of the + other examples supplied with Qt. To demonstrate the use of a custom + editor widget in a standard view, it is necessary to set up a model + containing some arbitrary data and a view to display it. + + We set up the application in the normal way, construct a standard item + model to hold some data, set up a table view to use the data in the + model, and construct a custom delegate to use for editing: + + \snippet examples/itemviews/spinboxdelegate/main.cpp 0 + + The table view is informed about the delegate, and will use it to + display each of the items. Since the delegate is a subclass of + QItemDelegate, each cell in the table will be rendered using standard + painting operations. + + We insert some arbitrary data into the model for demonstration purposes: + + \snippet examples/itemviews/spinboxdelegate/main.cpp 1 + \snippet examples/itemviews/spinboxdelegate/main.cpp 2 + + Finally, the table view is displayed with a window title, and we start + the application's event loop: + + \snippet examples/itemviews/spinboxdelegate/main.cpp 3 + + Each of the cells in the table can now be edited in the usual way, but + the spin box ensures that the data returned to the model is always + constrained by the values allowed by the spin box delegate. +*/ diff --git a/doc/src/examples/spinboxes.qdoc b/doc/src/examples/spinboxes.qdoc new file mode 100644 index 0000000..d8b0daa --- /dev/null +++ b/doc/src/examples/spinboxes.qdoc @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/spinboxes + \title Spin Boxes Example + + The Spin Boxes example shows how to use the many different types of spin boxes + available in Qt, from a simple QSpinBox widget to more complex editors like + the QDateTimeEdit widget. + + \image spinboxes-example.png + + The example consists of a single \c Window class that is used to display the + different spin box-based widgets available with Qt. + + \section1 Window Class Definition + + The \c Window class inherits QWidget and contains two slots that are used + to provide interactive features: + + \snippet examples/widgets/spinboxes/window.h 0 + + The private functions are used to set up each type of spin box in the window. + We use member variables to keep track of various widgets so that they can + be reconfigured when required. + + \section1 Window Class Implementation + + The constructor simply calls private functions to set up the different types + of spin box used in the example, and places each group in a layout: + + \snippet examples/widgets/spinboxes/window.cpp 0 + + We use the layout to manage the arrangement of the window's child widgets, + and change the window title. + + The \c createSpinBoxes() function constructs a QGroupBox and places three + QSpinBox widgets inside it with descriptive labels to indicate the types of + input they expect. + + \snippet examples/widgets/spinboxes/window.cpp 1 + + The first spin box shows the simplest way to use QSpinBox. It accepts values + from -20 to 20, the current value can be increased or decreased by 1 with + either the arrow buttons or \key{Up} and \key{Down} keys, and the default + value is 0. + + The second spin box uses a larger step size and displays a suffix to + provide more information about the type of data the number represents: + + \snippet examples/widgets/spinboxes/window.cpp 2 + + This spin box also displays a + \l{QAbstractSpinBox::specialValueText}{special value} instead of the minimum + value defined for it. This means that it will never show \gui{0%}, but will + display \gui{Automatic} when the minimum value is selected. + + The third spin box shows how a prefix can be used: + + \snippet examples/widgets/spinboxes/window.cpp 4 + + For simplicity, we show a spin box with a prefix and no suffix. It is also + possible to use both at the same time. + + \snippet examples/widgets/spinboxes/window.cpp 5 + + The rest of the function sets up a layout for the group box and places each + of the widgets inside it. + + The \c createDateTimeEdits() function constructs another group box with a + selection of spin boxes used for editing dates and times. + + \snippet examples/widgets/spinboxes/window.cpp 6 + + The first spin box is a QDateEdit widget that is able to accept dates + within a given range specified using QDate values. The arrow buttons and + \key{Up} and \key{Down} keys can be used to increase and decrease the + values for year, month, and day when the cursor is in the relevant section. + + The second spin box is a QTimeEdit widget: + + \snippet examples/widgets/spinboxes/window.cpp 7 + + Acceptable values for the time are defined using QTime values. + + The third spin box is a QDateTimeEdit widget that can display both date and + time values, and we place a label above it to indicate the range of allowed + times for a meeting. These widgets will be updated when the user changes a + format string. + + \snippet examples/widgets/spinboxes/window.cpp 8 + + The format string used for the date time editor, which is also shown in the + string displayed by the label, is chosen from a set of strings in a combobox: + + \snippet examples/widgets/spinboxes/window.cpp 9 + \codeline + \snippet examples/widgets/spinboxes/window.cpp 10 + + A signal from this combobox is connected to a slot in the \c Window class + (shown later). + + \snippet examples/widgets/spinboxes/window.cpp 11 + + Each child widget of the group box in placed in a layout. + + The \c setFormatString() slot is called whenever the user selects a new + format string in the combobox. The display format for the QDateTimeEdit + widget is set using the raw string passed by the signal: + + \snippet examples/widgets/spinboxes/window.cpp 12 + + Depending on the visible sections in the widget, we set a new date or time + range, and update the associated label to provide relevant information for + the user: + + \snippet examples/widgets/spinboxes/window.cpp 13 + + When the format string is changed, there will be an appropriate label and + entry widget for dates, times, or both types of input. + + The \c createDoubleSpinBoxes() function constructs three spin boxes that are + used to input double-precision floating point numbers: + + \snippet examples/widgets/spinboxes/window.cpp 14 + + Before the QDoubleSpinBox widgets are constructed, we create a spin box to + control how many decimal places they show. By default, only two decimal places + are shown in the following spin boxes, each of which is the equivalent of a + spin box in the group created by the \c createSpinBoxes() function. + + The first double spin box shows a basic double-precision spin box with the + same range, step size, and default value as the first spin box in the + \c createSpinBoxes() function: + + \snippet examples/widgets/spinboxes/window.cpp 15 + + However, this spin box also allows non-integer values to be entered. + + The second spin box displays a suffix and shows a special value instead + of the minimum value: + + \snippet examples/widgets/spinboxes/window.cpp 16 + + The third spin box displays a prefix instead of a suffix: + + \snippet examples/widgets/spinboxes/window.cpp 17 + + We connect the QSpinBox widget that specifies the precision to a slot in + the \c Window class. + + \snippet examples/widgets/spinboxes/window.cpp 18 + + The rest of the function places each of the widgets into a layout for the + group box. + + The \c changePrecision() slot is called when the user changes the value in + the precision spin box: + + \snippet examples/widgets/spinboxes/window.cpp 19 + + This function simply uses the integer supplied by the signal to specify the + number of decimal places in each of the QDoubleSpinBox widgets. Each one + of these will be updated automatically when their + \l{QDoubleSpinBox::decimals}{decimals} property is changed. +*/ diff --git a/doc/src/examples/sqlwidgetmapper.qdoc b/doc/src/examples/sqlwidgetmapper.qdoc new file mode 100644 index 0000000..173aea4 --- /dev/null +++ b/doc/src/examples/sqlwidgetmapper.qdoc @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example sql/sqlwidgetmapper + \title SQL Widget Mapper Example + + The SQL Widget Mapper example shows how to use a map information from a + database to widgets on a form. + + \image sql-widget-mapper.png + + In the \l{Combo Widget Mapper Example}, we showed how to use a named + mapping between a widget mapper and a QComboBox widget with a special + purpose model to relate values in the model to a list of choices. + + Again, we create a \c Window class with an almost identical user interface, + providing a combo box to allow their addresses to be classified as "Home", + "Work" or "Other". However, instead of using a separate model to hold these + address types, we use one database table to hold the example data and + another to hold the address types. In this way, we store all the + information in the same place. + + \section1 Window Class Definition + + The class provides a constructor, a slot to keep the buttons up to date, + and a private function to set up the model: + + \snippet examples/sql/sqlwidgetmapper/window.h Window definition + + In addition to the QDataWidgetMapper object and the controls used to make + up the user interface, we use a QStandardItemModel to hold our data and + a QStringListModel to hold information about the types of address that + can be applied to each person's data. + + \section1 Window Class Implementation + + The first act performed by the \c Window class constructor is to set up + the model used to hold the example data. Since this is a key part of the + example, we will look at this first. + + The model is initialized in the window's \c{setupModel()} function. Here, + we create a SQLite database containing a "person" table with primary key, + name, address and type fields. + + \snippet examples/sql/sqlwidgetmapper/window.cpp Set up the main table + + On each row of the table, we insert default values for these fields, + including values for the address types that correspond to the address + types are stored in a separate table. + + \image widgetmapper-sql-mapping-table.png + + We create an "addresstype" table containing the identifiers used in the + "person" table and the corresponding strings: + + \snippet examples/sql/sqlwidgetmapper/window.cpp Set up the address type table + + The "typeid" field in the "person" table is related to the contents of + the "addresstype" table via a relation in a QSqlRelationalTableModel. + This kind of model performs all the necessary work to store the data in + a database and also allows any relations to be used as models in their + own right. + + In this case, we have defined a relation for the "typeid" field in the + "person" table that relates it to the "id" field in the "addresstype" + table and which causes the contents of the "description" field to be + used wherever the "typeid" is presented to the user. (See the + QSqlRelationalTableModel::setRelation() documentation for details.) + + \image widgetmapper-sql-mapping.png + + The constructor of the \c Window class can be explained in three parts. + In the first part, we set up the model used to hold the data, then we set + up the widgets used for the user interface: + + \snippet examples/sql/sqlwidgetmapper/window.cpp Set up widgets + + We obtain a model for the combo box from the main model, based on the + relation we set up for the "typeid" field. The call to the combo box's + \l{QComboBox::}{setModelColumn()} selects the field in the field in the + model to display. + + Note that this approach is similar to the one used in the + \l{Combo Widget Mapper Example} in that we set up a model for the + combo box. However, in this case, we obtain a model based on a relation + in the QSqlRelationalTableModel rather than create a separate one. + + Next, we set up the widget mapper, relating each input widget to a field + in the model: + + \snippet examples/sql/sqlwidgetmapper/window.cpp Set up the mapper + + For the combo box, we already know the index of the field in the model + from the \c{setupModel()} function. We use a QSqlRelationalDelegate as + a proxy between the mapper and the input widgets to match up the "typeid" + values in the model with those in the combo box's model and populate the + combo box with descriptions rather than integer values. + + As a result, the user is able to select an item from the combo box, + and the associated value is written back to the model. + + The rest of the constructor is very similar to that of the + \l{Simple Widget Mapper Example}: + + \snippet examples/sql/sqlwidgetmapper/window.cpp Set up connections and layouts + + We show the implementation of the \c{updateButtons()} slot for + completeness: + + \snippet examples/sql/sqlwidgetmapper/window.cpp Slot for updating the buttons + + \omit + \section1 Delegate Class Definition and Implementation + + The delegate we use to mediate interaction between the widget mapper and + the input widgets is a small QItemDelegate subclass: + + \snippet examples/sql/sqlwidgetmapper/delegate.h Delegate class definition + + This provides implementations of the two standard functions used to pass + data between editor widgets and the model (see the \l{Delegate Classes} + documentation for a more general description of these functions). + + Since we only provide an empty implementation of the constructor, we + concentrate on the other two functions. + + The \l{QItemDelegate::}{setEditorData()} implementation takes the data + referred to by the model index supplied and processes it according to + the presence of a \c currentIndex property in the editor widget: + + \snippet examples/sql/sqlwidgetmapper/delegate.cpp setEditorData implementation + + If, like QComboBox, the editor widget has this property, it is set using + the value from the model. Since we are passing around QVariant values, + the strings stored in the model are automatically converted to the integer + values needed for the \c currentIndex property. + + As a result, instead of showing "0", "1" or "2" in the combo box, one of + its predefined set of items is shown. We call QItemDelegate::setEditorData() + for widgets without the \c currentIndex property. + + The \l{QItemDelegate::}{setModelData()} implementation performs the reverse + process, taking the value stored in the widget's \c currentIndex property + and storing it back in the model: + + \snippet examples/sql/sqlwidgetmapper/delegate.cpp setModelData implementation + \endomit + + \section1 Summary and Further Reading + + The use of a separate model for the combo box and a special delegate for the + widget mapper allows us to present a menu of choices to the user. Although + the choices are stored in the same database as the user's data, they are held + in a separate table. Using this approach, we can reconstructed complete records + at a later time while using database features appropriately. + + If SQL models are not being used, it is still possible to use more than + one model to present choices to the user. This is covered by the + \l{Combo Widget Mapper Example}. +*/ diff --git a/doc/src/examples/standarddialogs.qdoc b/doc/src/examples/standarddialogs.qdoc new file mode 100644 index 0000000..db533ed --- /dev/null +++ b/doc/src/examples/standarddialogs.qdoc @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example dialogs/standarddialogs + \title Standard Dialogs Example + + The Standard Dialogs example shows the standard dialogs that are provided by Qt. + + \image standarddialogs-example.png +*/ diff --git a/doc/src/examples/stardelegate.qdoc b/doc/src/examples/stardelegate.qdoc new file mode 100644 index 0000000..fde3316 --- /dev/null +++ b/doc/src/examples/stardelegate.qdoc @@ -0,0 +1,310 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example itemviews/stardelegate + \title Star Delegate Example + + The Star Delegate example shows how to create a delegate that + can paint itself and that supports editing. + + \image stardelegate.png The Star Delegate Example + + When displaying data in a QListView, QTableView, or QTreeView, + the individual items are drawn by a + \l{Delegate Classes}{delegate}. Also, when the user starts + editing an item (e.g., by double-clicking the item), the delegate + provides an editor widget that is placed on top of the item while + editing takes place. + + Delegates are subclasses of QAbstractItemDelegate. Qt provides + QItemDelegate, which inherits QAbstractItemDelegate and handles + the most common data types (notably \c int and QString). If we + need to support custom data types, or want to customize the + rendering or the editing for existing data types, we can subclass + QAbstractItemDelegate or QItemDelegate. See \l{Delegate Classes} + for more information about delegates, and \l{Model/View + Programming} if you need a high-level introduction to Qt's + model/view architecture (including delegates). + + In this example, we will see how to implement a custom delegate + to render and edit a "star rating" data type, which can store + values such as "1 out of 5 stars". + + The example consists of the following classes: + + \list + \o \c StarRating is the custom data type. It stores a rating + expressed as stars, such as "2 out of 5 stars" or "5 out of + 6 stars". + + \o \c StarDelegate inherits QItemDelegate and provides support + for \c StarRating (in addition to the data types already + handled by QItemDelegate). + + \o \c StarEditor inherits QWidget and is used by \c StarDelegate + to let the user edit a star rating using the mouse. + \endlist + + To show the \c StarDelegate in action, we will fill a + QTableWidget with some data and install the delegate on it. + + \section1 StarDelegate Class Definition + + Here's the definition of the \c StarDelegate class: + + \snippet examples/itemviews/stardelegate/stardelegate.h 0 + + All public functions are reimplemented virtual functions from + QItemDelegate to provide custom rendering and editing. + + \section1 StarDelegate Class Implementation + + The \l{QAbstractItemDelegate::}{paint()} function is + reimplemented from QItemDelegate and is called whenever the view + needs to repaint an item: + + \snippet examples/itemviews/stardelegate/stardelegate.cpp 0 + + The function is invoked once for each item, represented by a + QModelIndex object from the model. If the data stored in the item + is a \c StarRating, we paint it ourselves; otherwise, we let + QItemDelegate paint it for us. This ensures that the \c + StarDelegate can handle the most common data types. + + In the case where the item is a \c StarRating, we draw the + background if the item is selected, and we draw the item using \c + StarRating::paint(), which we will review later. + + \c{StartRating}s can be stored in a QVariant thanks to the + Q_DECLARE_METATYPE() macro appearing in \c starrating.h. More on + this later. + + The \l{QAbstractItemDelegate::}{createEditor()} function is + called when the user starts editing an item: + + \snippet examples/itemviews/stardelegate/stardelegate.cpp 2 + + If the item is a \c StarRating, we create a \c StarEditor and + connect its \c editingFinished() signal to our \c + commitAndCloseEditor() slot, so we can update the model when the + editor closes. + + Here's the implementation of \c commitAndCloseEditor(): + + \snippet examples/itemviews/stardelegate/stardelegate.cpp 5 + + When the user is done editing, we emit + \l{QAbstractItemDelegate::}{commitData()} and + \l{QAbstractItemDelegate::}{closeEditor()} (both declared in + QAbstractItemDelegate), to tell the model that there is edited + data and to inform the view that the editor is no longer needed. + + The \l{QAbstractItemDelegate::}{setEditorData()} function is + called when an editor is created to initialize it with data + from the model: + + \snippet examples/itemviews/stardelegate/stardelegate.cpp 3 + + We simply call \c setStarRating() on the editor. + + The \l{QAbstractItemDelegate::}{setModelData()} function is + called when editing is finished, to commit data from the editor + to the model: + + \snippet examples/itemviews/stardelegate/stardelegate.cpp 4 + + The \c sizeHint() function returns an item's preferred size: + + \snippet examples/itemviews/stardelegate/stardelegate.cpp 1 + + We simply forward the call to \c StarRating. + + \section1 StarEditor Class Definition + + The \c StarEditor class was used when implementing \c + StarDelegate. Here's the class definition: + + \snippet examples/itemviews/stardelegate/stareditor.h 0 + + The class lets the user edit a \c StarRating by moving the mouse + over the editor. It emits the \c editingFinished() signal when + the user clicks on the editor. + + The protected functions are reimplemented from QWidget to handle + mouse and paint events. The private function \c starAtPosition() + is a helper function that returns the number of the star under + the mouse pointer. + + \section1 StarEditor Class Implementation + + Let's start with the constructor: + + \snippet examples/itemviews/stardelegate/stareditor.cpp 0 + + We enable \l{QWidget::setMouseTracking()}{mouse tracking} on the + widget so we can follow the cursor even when the user doesn't + hold down any mouse button. We also turn on QWidget's + \l{QWidget::autoFillBackground}{auto-fill background} feature to + obtain an opaque background. (Without the call, the view's + background would shine through the editor.) + + The \l{QWidget::}{paintEvent()} function is reimplemented from + QWidget: + + \snippet examples/itemviews/stardelegate/stareditor.cpp 1 + + We simply call \c StarRating::paint() to draw the stars, just + like we did when implementing \c StarDelegate. + + \snippet examples/itemviews/stardelegate/stareditor.cpp 2 + + In the mouse event handler, we call \c setStarCount() on the + private data member \c myStarRating to reflect the current cursor + position, and we call QWidget::update() to force a repaint. + + \snippet examples/itemviews/stardelegate/stareditor.cpp 3 + + When the user releases a mouse button, we simply emit the \c + editingFinished() signal. + + \snippet examples/itemviews/stardelegate/stareditor.cpp 4 + + The \c starAtPosition() function uses basic linear algebra to + find out which star is under the cursor. + + \section1 StarRating Class Definition + + \snippet examples/itemviews/stardelegate/starrating.h 0 + \codeline + \snippet examples/itemviews/stardelegate/starrating.h 1 + + The \c StarRating class represents a rating as a number of stars. + In addition to holding the data, it is also capable of painting + the stars on a QPaintDevice, which in this example is either a + view or an editor. The \c myStarCount member variable stores the + current rating, and \c myMaxStarCount stores the highest possible + rating (typically 5). + + The Q_DECLARE_METATYPE() macro makes the type \c StarRating known + to QVariant, making it possible to store \c StarRating values in + QVariant. + + \section1 StarRating Class Implementation + + The constructor initializes \c myStarCount and \c myMaxStarCount, + and sets up the polygons used to draw stars and diamonds: + + \snippet examples/itemviews/stardelegate/starrating.cpp 0 + + The \c paint() function paints the stars in this \c StarRating + object on a paint device: + + \snippet examples/itemviews/stardelegate/starrating.cpp 2 + + We first set the pen and brush we will use for painting. The \c + mode parameter can be either \c Editable or \c ReadOnly. If \c + mode is editable, we use the \l{QPalette::}{Highlight} color + instead of the \l{QPalette::}{Foreground} color to draw the + stars. + + Then we draw the stars. If we are in \c Edit mode, we paint + diamonds in place of stars if the rating is less than the highest + rating. + + The \c sizeHint() function returns the preferred size for an area + to paint the stars on: + + \snippet examples/itemviews/stardelegate/starrating.cpp 1 + + The preferred size is just enough to paint the maximum number of + stars. The function is called by both \c StarDelegate::sizeHint() + and \c StarEditor::sizeHint(). + + \section1 The \c main() Function + + Here's the program's \c main() function: + + \snippet examples/itemviews/stardelegate/main.cpp 5 + + The \c main() function creates a QTableWidget and sets a \c + StarDelegate on it. \l{QAbstractItemView::}{DoubleClicked} and + \l{QAbstractItemView::}{SelectedClicked} are set as + \l{QAbstractItemView::editTriggers()}{edit triggers}, so that the + editor is opened with a single click when the star rating item is + selected. + + The \c populateTableWidget() function fills the QTableWidget with + data: + + \snippet examples/itemviews/stardelegate/main.cpp 0 + \snippet examples/itemviews/stardelegate/main.cpp 1 + \dots + \snippet examples/itemviews/stardelegate/main.cpp 2 + \snippet examples/itemviews/stardelegate/main.cpp 3 + \codeline + \snippet examples/itemviews/stardelegate/main.cpp 4 + + Notice the call to qVariantFromValue to convert a \c + StarRating to a QVariant. + + \section1 Possible Extensions and Suggestions + + There are many ways to customize Qt's \l{Model/View + Programming}{model/view framework}. The approach used in this + example is appropriate for most custom delegates and editors. + Examples of possibilities not used by the star delegate and star + editor are: + + \list + \o It is possible to open editors programmatically by calling + QAbstractItemView::edit(), instead of relying on edit + triggers. This could be use to support other edit triggers + than those offered by the QAbstractItemView::EditTrigger enum. + For example, in the Star Delegate example, hovering over an + item with the mouse might make sense as a way to pop up an + editor. + + \o By reimplementing QAbstractItemDelegate::editorEvent(), it is + possible to implement the editor directly in the delegate, + instead of creating a separate QWidget subclass. + \endlist +*/ diff --git a/doc/src/examples/styleplugin.qdoc b/doc/src/examples/styleplugin.qdoc new file mode 100644 index 0000000..0dea7bf --- /dev/null +++ b/doc/src/examples/styleplugin.qdoc @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/styleplugin + \title Style Plugin Example + + This example shows how to create a plugin that extends Qt with a new + GUI look and feel. + + \image stylepluginexample.png + + On some platforms, the native style will prevent the button + from having a red background. In this case, try to run the example + in another style (e.g., plastique). + + A plugin in Qt is a class stored in a shared library that can be + loaded by a QPluginLoader at run-time. When you create plugins in + Qt, they either extend a Qt application or Qt itself. Writing a + plugin that extends Qt itself is achieved by inheriting one of the + plugin \l{Plugin Classes}{base classes}, reimplementing functions + from that class, and adding a macro. In this example we extend Qt + by adding a new GUI look and feel (i.e., making a new QStyle + available). A high-level introduction to plugins is given in the + plugin \l{How to Create Qt Plugins}{overview document}. + + Plugins that provide new styles inherit the QStylePlugin base + class. Style plugins are loaded by Qt and made available through + QStyleFactory; we will look at this later. We have implemented \c + SimpleStylePlugin, which provides \c SimpleStyle. The new style + inherits QWindowsStyle and contributes to widget styling by + drawing button backgrounds in red - not a major contribution, but + it still makes a new style. We test the plugin with \c + StyleWindow, in which we display a QPushButton. + + The \c SimpleStyle and \c StyleWindow classes do not contain any + plugin specific functionality and their implementations are + trivial; we will therefore leap past them and head on to the \c + SimpleStylePlugin and the \c main() function. After we have looked + at that, we examine the plugin's profile. + + + \section1 SimpleStylePlugin Class Definition + + \c SimpleStylePlugin inherits QStylePlugin and is the plugin + class. + + \snippet examples/tools/styleplugin/plugin/simplestyleplugin.h 0 + + \c keys() returns a list of style names that this plugin can + create, while \c create() takes such a string and returns the + QStyle corresponding to the key. Both functions are pure virtual + functions reimplemented from QStylePlugin. When an application + requests an instance of the \c SimpleStyle style, which this + plugin creates, Qt will create it with this plugin. + + + \section1 SimpleStylePlugin Class Implementation + + Here is the implementation of \c keys(): + + \snippet examples/tools/styleplugin/plugin/simplestyleplugin.cpp 0 + + Since this plugin only supports one style, we return a QStringList + with the class name of that style. + + Here is the \c create() function: + + \snippet examples/tools/styleplugin/plugin/simplestyleplugin.cpp 1 + + Note that the key for style plugins are case insensitive. + The case sensitivity varies from plugin to plugin, so you need to + check this when implementing new plugins. + + \section1 The \c main() function + + \snippet examples/tools/styleplugin/stylewindow/main.cpp 0 + + Qt loads the available style plugins when the QApplication object + is initialized. The QStyleFactory class knows about all styles and + produces them with \l{QStyleFactory::}{create()} (it is a + wrapper around all the style plugins). + + \section1 The Simple Style Plugin Profile + + The \c SimpleStylePlugin lives in its own directory and have + its own profile: + + \snippet examples/tools/styleplugin/plugin/plugin.pro 0 + + In the plugin profile we need to set the lib template as we are + building a shared library instead of an executable. We must also + set the config to plugin. We set the library to be stored in the + styles folder under stylewindow because this is a path in which Qt + will search for style plugins. + + \section1 Related articles and examples + + In addition to the plugin \l{How to Create Qt Plugins}{overview + document}, we have other examples and articles that concern + plugins. + + In the \l{Echo Plugin Example}{echo plugin example} we show how to + implement plugins that extends Qt applications rather than Qt + itself, which is the case with the style plugin of this example. + The \l{Plug & Paint Example}{plug & paint} example shows how to + implement a static plugin as well as being a more involved example + on plugins that extend applications. +*/ diff --git a/doc/src/examples/styles.qdoc b/doc/src/examples/styles.qdoc new file mode 100644 index 0000000..b68a310 --- /dev/null +++ b/doc/src/examples/styles.qdoc @@ -0,0 +1,486 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/styles + \title Styles Example + + The Styles example illustrates how to create custom widget + drawing styles using Qt, and demonstrates Qt's predefined styles. + + \image styles-enabledwood.png Screenshot of the Styles example + + A style in Qt is a subclass of QStyle or of one of its + subclasses. Styles perform drawing on behalf of widgets. Qt + provides a whole range of predefined styles, either built into + the \l QtGui library or found in plugins. Custom styles are + usually created by subclassing one of Qt's existing style and + reimplementing a few virtual functions. + + In this example, the custom style is called \c NorwegianWoodStyle + and derives from QMotifStyle. Its main features are the wooden + textures used for filling most of the widgets and its round + buttons and comboboxes. + + To implement the style, we use some advanced features provided by + QPainter, such as \l{QPainter::Antialiasing}{antialiasing} (to + obtain smoother button edges), \l{QColor::alpha()}{alpha blending} + (to make the buttons appeared raised or sunken), and + \l{QPainterPath}{painter paths} (to fill the buttons and draw the + outline). We also use many features of QBrush and QPalette. + + The example consists of the following classes: + + \list + \o \c NorwegianWoodStyle inherits from QMotifStyle and implements + the Norwegian Wood style. + \o \c WidgetGallery is a \c QDialog subclass that shows the most + common widgets and allows the user to switch style + dynamically. + \endlist + + \section1 NorwegianWoodStyle Class Definition + + Here's the definition of the \c NorwegianWoodStyle class: + + \snippet examples/widgets/styles/norwegianwoodstyle.h 0 + + The public functions are all declared in QStyle (QMotifStyle's + grandparent class) and reimplemented here to override the Motif + look and feel. The private functions are helper functions. + + \section1 NorwegianWoodStyle Class Implementation + + We will now review the implementation of the \c + NorwegianWoodStyle class. + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 0 + + The \c polish() function is reimplemented from QStyle. It takes a + QPalette as a reference and adapts the palette to fit the style. + Most styles don't need to reimplement that function. The + Norwegian Wood style reimplements it to set a "wooden" palette. + + We start by defining a few \l{QColor}s that we'll need. Then we + load two PNG images. The \c : prefix in the file path indicates + that the PNG files are \l{The Qt Resource System}{embedded + resources}. + + \table + \row \o \inlineimage widgets/styles/images/woodbackground.png + + \o \bold{woodbackground.png} + + This texture is used as the background of most widgets. + The wood pattern is horizontal. + + \row \o \inlineimage widgets/styles/images/woodbutton.png + + \o \bold{woodbutton.png} + + This texture is used for filling push buttons and + comboboxes. The wood pattern is vertical and more reddish + than the texture used for the background. + \endtable + + The \c midImage variable is initialized to be the same as \c + buttonImage, but then we use a QPainter and fill it with a 25% + opaque black color (a black with an \l{QColor::alpha()}{alpha + channel} of 63). The result is a somewhat darker image than \c + buttonImage. This image will be used for filling buttons that the + user is holding down. + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 1 + + We initialize the palette. Palettes have various + \l{QPalette::ColorRole}{color roles}, such as QPalette::Base + (used for filling text editors, item views, etc.), QPalette::Text + (used for foreground text), and QPalette::Background (used for + the background of most widgets). Each role has its own QBrush, + which usually is a plain color but can also be a brush pattern or + even a texture (a QPixmap). + + In addition to the roles, palettes have several + \l{QPalette::ColorGroup}{color groups}: active, disabled, and + inactive. The active color group is used for painting widgets in + the active window. The disabled group is used for disabled + widgets. The inactive group is used for all other widgets. Most + palettes have identical active and inactive groups, while the + disabled group uses darker shades. + + We initialize the QPalette object with a brown color. Qt + automatically derivates all color roles for all color groups from + that single color. We then override some of the default values. For + example, we use Qt::darkGreen instead of the default + (Qt::darkBlue) for the QPalette::Highlight role. The + QPalette::setBrush() overload that we use here sets the same + color or brush for all three color groups. + + The \c setTexture() function is a private function that sets the + texture for a certain color role, while preserving the existing + color in the QBrush. A QBrush can hold both a solid color and a + texture at the same time. The solid color is used for drawing + text and other graphical elements where textures don't look good. + + At the end, we set the brush for the disabled color group of the + palette. We use \c woodbackground.png as the texture for all + disabled widgets, including buttons, and use a darker color to + accompany the texture. + + \image styles-disabledwood.png The Norwegian Wood style with disabled widgets + + Let's move on to the other functions reimplemented from + QMotifStyle: + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 3 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 4 + + This QStyle::polish() overload is called once on every widget + drawn using the style. We reimplement it to set the Qt::WA_Hover + attribute on \l{QPushButton}s and \l{QComboBox}es. When this + attribute is set, Qt generates paint events when the mouse + pointer enters or leaves the widget. This makes it possible to + render push buttons and comboboxes differently when the mouse + pointer is over them. + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 5 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 6 + + This QStyle::unpolish() overload is called to undo any + modification done to the widget in \c polish(). For simplicity, + we assume that the flag wasn't set before \c polish() was called. + In an ideal world, we would remember the original state for each + widgets (e.g., using a QMap<QWidget *, bool>) and restore it in + \c unpolish(). + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 7 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 8 + + The \l{QStyle::pixelMetric()}{pixelMetric()} function returns the + size in pixels for a certain user interface element. By + reimplementing this function, we can affect the way certain + widgets are drawn and their size hint. Here, we return 8 as the + width around a shown in a QComboBox, ensuring that there is + enough place around the text and the arrow for the Norwegian Wood + round corners. The default value for this setting in the Motif + style is 2. + + We also change the extent of \l{QScrollBar}s, i.e., the height + for a horizontal scroll bar and the width for a vertical scroll + bar, to be 4 pixels more than in the Motif style. This makes the + style a bit more distinctive. + + For all other QStyle::PixelMetric elements, we use the Motif + settings. + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 9 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 10 + + The \l{QStyle::styleHint()}{styleHint()} function returns some + hints to widgets or to the base style (in our case QMotifStyle) + about how to draw the widgets. The Motif style returns \c true + for the QStyle::SH_DitherDisabledText hint, resulting in a most + unpleasing visual effect. We override this behavior and return \c + false instead. We also return \c true for the + QStyle::SH_EtchDisabledText hint, meaning that disabled text is + rendered with an embossed look (as QWindowsStyle does). + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 11 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 12 + + The \l{QStyle::drawPrimitive()}{drawPrimitive()} function is + called by Qt widgets to draw various fundamental graphical + elements. Here we reimplement it to draw QPushButton and + QComboBox with round corners. The button part of these widgets is + drawn using the QStyle::PE_PanelButtonCommand primitive element. + + The \c option parameter, of type QStyleOption, contains + everything we need to know about the widget we want to draw on. + In particular, \c option->rect gives the rectangle within which + to draw the primitive element. The \c painter parameter is a + QPainter object that we can use to draw on the widget. + + The \c widget parameter is the widget itself. Normally, all the + information we need is available in \c option and \c painter, so + we don't need \c widget. We can use it to perform special + effects; for example, QMacStyle uses it to animate default + buttons. If you use it, be aware that the caller is allowed to + pass a null pointer. + + We start by defining three \l{QColor}s that we'll need later on. + We also put the x, y, width, and height components of the + widget's rectangle in local variables. The value used for the \c + semiTransparentWhite and for the \c semiTransparentBlack color's + alpha channel depends on whether the mouse cursor is over the + widget or not. Since we set the Qt::WA_Hover attribute on + \l{QPushButton}s and \l{QComboBox}es, we can rely on the + QStyle::State_MouseOver flag to be set when the mouse is over the + widget. + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 13 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 14 + + The \c roundRect variable is a QPainterPath. A QPainterPath is is + a vectorial specification of a shape. Any shape (rectangle, + ellipse, spline, etc.) or combination of shapes can be expressed + as a path. We will use \c roundRect both for filling the button + background with a wooden texture and for drawing the outline. The + \c roundRectPath() function is a private function; we will come + back to it later. + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 15 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 16 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 17 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 18 + + We define two variables, \c brush and \c darker, and initialize + them based on the state of the button: + + \list + \o If the button is a \l{QPushButton::flat}{flat button}, we use + the \l{QPalette::Background}{Background} brush. We set \c + darker to \c true if the button is + \l{QAbstractButton::down}{down} or + \l{QAbstractButton::checked}{checked}. + \o If the button is currently held down by the user or in the + \l{QAbstractButton::checked}{checked} state, we use the + \l{QPalette::Mid}{Mid} component of the palette. We set + \c darker to \c true if the button is + \l{QAbstractButton::checked}{checked}. + \o Otherwise, we use the \l{QPalette::Button}{Button} component + of the palette. + \endlist + + The screenshot below illustrates how \l{QPushButton}s are + rendered based on their state: + + \image styles-woodbuttons.png Norwegian Wood buttons in different states + + To discover whether the button is flat or not, we need to cast + the \c option parameter to QStyleOptionButton and check if the + \l{QStyleOptionButton::features}{features} member specifies the + QStyleOptionButton::Flat flag. The qstyleoption_cast() function + performs a dynamic cast; if \c option is not a + QStyleOptionButton, qstyleoption_cast() returns a null pointer. + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 19 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 20 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 21 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 22 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 23 + + We turn on antialiasing on QPainter. Antialiasing is a technique + that reduces the visual distortion that occurs when the edges of + a shape are converted into pixels. For the Norwegian Wood style, + we use it to obtain smoother edges for the round buttons. + + \image styles-aliasing.png Norwegian wood buttons with and without antialiasing + + The first call to QPainter::fillPath() draws the background of + the button with a wooden texture. The second call to + \l{QPainter::fillPath()}{fillPath()} paints the same area with a + semi-transparent black color (a black color with an alpha channel + of 63) to make the area darker if \c darker is true. + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 24 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 25 + + Next, we draw the outline. The top-left half of the outline and + the bottom-right half of the outline are drawn using different + \l{QPen}s to produce a 3D effect. Normally, the top-left half of + the outline is drawn lighter whereas the bottom-right half is + drawn darker, but if the button is + \l{QAbstractButton::down}{down} or + \l{QAbstractButton::checked}{checked}, we invert the two + \l{QPen}s to give a sunken look to the button. + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 26 + + We draw the top-left part of the outline by calling + QPainter::drawPath() with an appropriate + \l{QPainter::setClipRegion()}{clip region}. If the + \l{QStyleOption::direction}{layout direction} is right-to-left + instead of left-to-right, we swap the \c x1, \c x2, \c x3, and \c + x4 variables to obtain correct results. On right-to-left desktop, + the "light" comes from the top-right corner of the screen instead + of the top-left corner; raised and sunken widgets must be drawn + accordingly. + + The diagram below illustrates how 3D effects are drawn according + to the layout direction. The area in red on the diagram + corresponds to the \c topHalf polygon: + + \image styles-3d.png + + An easy way to test how a style looks in right-to-left mode is to + pass the \c -reverse command-line option to the application. This + option is recognized by the QApplication constructor. + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 32 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 33 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 34 + + The bottom-right part of the outline is drawn in a similar + fashion. Then we draw a one-pixel wide outline around the entire + button, using the \l{QPalette::Foreground}{Foreground} component + of the QPalette. + + This completes the QStyle::PE_PanelButtonCommand case of the \c + switch statement. Other primitive elements are handled by the + base style. Let's now turn to the other \c NorwegianWoodStyle + member functions: + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 35 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 36 + + We reimplement QStyle::drawControl() to draw the text on a + QPushButton in a bright color when the button is + \l{QAbstractButton::down}{down} or + \l{QAbstractButton::checked}{checked}. + + If the \c option parameter points to a QStyleOptionButton object + (it normally should), we take a copy of the object and modify its + \l{QStyleOption::palette}{palette} member to make the + QPalette::ButtonText be the same as the QPalette::BrightText + component (unless the widget is disabled). + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 37 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 38 + + The \c setTexture() function is a private function that sets the + \l{QBrush::texture()}{texture} component of the \l{QBrush}es for + a certain \l{QPalette::ColorRole}{color role}, for all three + \l{QPalette::ColorGroup}{color groups} (active, disabled, + inactive). We used it to initialize the Norwegian Wood palette in + \c polish(QPalette &). + + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 39 + \snippet examples/widgets/styles/norwegianwoodstyle.cpp 40 + + The \c roundRectPath() function is a private function that + constructs a QPainterPath object for round buttons. The path + consists of eight segments: four arc segments for the corners and + four lines for the sides. + + With around 250 lines of code, we have a fully functional custom + style based on one of the predefined styles. Custom styles can be + used to provide a distinct look to an application or family of + applications. + + \section1 WidgetGallery Class + + For completeness, we will quickly review the \c WidgetGallery + class, which contains the most common Qt widgets and allows the + user to change style dynamically. Here's the class definition: + + \snippet examples/widgets/styles/widgetgallery.h 0 + \dots + \snippet examples/widgets/styles/widgetgallery.h 1 + + Here's the \c WidgetGallery constructor: + + \snippet examples/widgets/styles/widgetgallery.cpp 0 + + We start by creating child widgets. The \gui Style combobox is + initialized with all the styles known to QStyleFactory, in + addition to \c NorwegianWood. The \c create...() functions are + private functions that set up the various parts of the \c + WidgetGallery. + + \snippet examples/widgets/styles/widgetgallery.cpp 1 + \snippet examples/widgets/styles/widgetgallery.cpp 2 + + We connect the \gui Style combobox to the \c changeStyle() + private slot, the \gui{Use style's standard palette} check box to + the \c changePalette() slot, and the \gui{Disable widgets} check + box to the child widgets' + \l{QWidget::setDisabled()}{setDisabled()} slot. + + \snippet examples/widgets/styles/widgetgallery.cpp 3 + \snippet examples/widgets/styles/widgetgallery.cpp 4 + + Finally, we put the child widgets in layouts. + + \snippet examples/widgets/styles/widgetgallery.cpp 5 + \snippet examples/widgets/styles/widgetgallery.cpp 6 + + When the user changes the style in the combobox, we call + QApplication::setStyle() to dynamically change the style of the + application. + + \snippet examples/widgets/styles/widgetgallery.cpp 7 + \snippet examples/widgets/styles/widgetgallery.cpp 8 + + If the user turns the \gui{Use style's standard palette} on, the + current style's \l{QStyle::standardPalette()}{standard palette} + is used; otherwise, the system's default palette is honored. + + For the Norwegian Wood style, this makes no difference because we + always override the palette with our own palette in \c + NorwegianWoodStyle::polish(). + + \snippet examples/widgets/styles/widgetgallery.cpp 9 + \snippet examples/widgets/styles/widgetgallery.cpp 10 + + The \c advanceProgressBar() slot is called at regular intervals + to advance the progress bar. Since we don't know how long the + user will keep the Styles application running, we use a + logarithmic formula: The closer the progress bar gets to 100%, + the slower it advances. + + We will review \c createProgressBar() in a moment. + + \snippet examples/widgets/styles/widgetgallery.cpp 11 + \snippet examples/widgets/styles/widgetgallery.cpp 12 + + The \c createTopLeftGroupBox() function creates the QGroupBox + that occupies the top-left corner of the \c WidgetGallery. We + skip the \c createTopRightGroupBox(), \c + createBottomLeftTabWidget(), and \c createBottomRightGroupBox() + functions, which are very similar. + + \snippet examples/widgets/styles/widgetgallery.cpp 13 + + In \c createProgressBar(), we create a QProgressBar at the bottom + of the \c WidgetGallery and connect its + \l{QTimer::timeout()}{timeout()} signal to the \c + advanceProgressBar() slot. +*/ diff --git a/doc/src/examples/stylesheet.qdoc b/doc/src/examples/stylesheet.qdoc new file mode 100644 index 0000000..811d65c --- /dev/null +++ b/doc/src/examples/stylesheet.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/stylesheet + \title Style Sheet Example + + The Style Sheet Example shows how to use style sheets. + + \image stylesheet-pagefold.png Screen Shot of the Pagefold style sheet +*/ + diff --git a/doc/src/examples/svgalib.qdoc b/doc/src/examples/svgalib.qdoc new file mode 100644 index 0000000..c94d408 --- /dev/null +++ b/doc/src/examples/svgalib.qdoc @@ -0,0 +1,360 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example qws/svgalib + \title Accelerated Graphics Driver Example + + The Accelerated Graphics Driver example shows how you can write + your own accelerated graphics driver and \l {add your graphics + driver to Qt for Embedded Linux}. In \l{Qt for Embedded Linux}, + painting is a pure software implementation and is normally performed + in two steps: + The clients render each window onto a corresponding surface + (stored in memory) using a paint engine, and then the server uses + the graphics driver to compose the surface images and copy them to + the screen. (See the \l{Qt for Embedded Linux Architecture} documentation + for details.) + + The rendering can be accelerated in two ways: Either by + accelerating the copying of pixels to the screen, or by + accelerating the explicit painting operations. The first is done + in the graphics driver implementation, the latter is performed by + the paint engine implementation. Typically, both the pixel copying + and the painting operations are accelerated using the following + approach: + + \list 1 + \o \l {Step 1: Creating a Custom Graphics Driver} + {Creating a Custom Graphics Driver} + + \o \l {Step 2: Implementing a Custom Raster Paint Engine} + {Implementing a Custom Paint Engine} + + \o \l {Step 3: Making the Widgets Aware of the Custom Paint + Engine}{Making the Widgets Aware of the Custom Paint Engine} + + \endlist + + After compiling the example code, install the graphics driver + plugin with the command \c {make install}. To start an application + using the graphics driver, you can either set the environment + variable \l QWS_DISPLAY and then run the application, or you can + just run the application using the \c -display switch: + + \snippet doc/src/snippets/code/doc_src_examples_svgalib.qdoc 0 + + \table + \header \o SVGAlib + \row \o + + Instead of interfacing the graphics hardware directly, this + example relies on \l {http://www.svgalib.org}{SVGAlib} being + installed on your system. \l {http://www.svgalib.org}{SVGAlib} is + a small graphics library which provides acceleration for many + common graphics cards used on desktop computers. It should work on + most workstations and has a small and simple API. + + \endtable + + \section1 Step 1: Creating a Custom Graphics Driver + + The custom graphics driver is created by deriving from the QScreen + class. QScreen is the base class for implementing screen/graphics + drivers in Qt for Embedded Linux. + + \snippet examples/qws/svgalib/svgalibscreen.h 0 + \codeline + \snippet examples/qws/svgalib/svgalibscreen.h 1 + + The \l {QScreen::}{connect()}, \l {QScreen::}{disconnect()}, \l + {QScreen::}{initDevice()} and \l {QScreen::}{shutdownDevice()} + functions are declared as pure virtual functions in QScreen and + must be implemented. They are used to configure the hardware, or + query its configuration: \l {QScreen::}{connect()} and \l + {QScreen::}{disconnect()} are called by both the server and client + processes, while the \l {QScreen::}{initDevice()} and \l + {QScreen::}{shutdownDevice()} functions are only called by the + server process. + + QScreen's \l {QScreen::}{setMode()} and \l {QScreen::}{blank()} + functions are also pure virtual, but our driver's implementations + are trivial. The last two functions (\l {QScreen::}{blit()} and \l + {QScreen::}{solidFill()}) are the ones involved in putting pixels + on the screen, i.e., we reimplement these functions to perform the + pixel copying acceleration. + + Finally, the \c context variable is a pointer to a \l + {http://www.svgalib.org}{SVGAlib} specific type. Note that the + details of using the \l {http://www.svgalib.org}{SVGAlib} library + is beyond the scope of this example. + + \section2 SvgalibScreen Class Implementation + + The \l {QScreen::}{connect()} function is the first function that + is called after the constructor returns. It queries \l + {http://www.svgalib.org}{SVGAlib} about the graphics mode and + initializes the variables. + + \snippet examples/qws/svgalib/svgalibscreen.cpp 0 + + It is important that the \l {QScreen::}{connect()} function + initializes the \c data, \c lstep, \c w, \c h, \c dw, \c dh, \c d, + \c physWidth and \c physHeight variables (inherited from QScreen) + to ensure that the driver is in a state consistent with the driver + configuration. + + In this particular example we do not have any information of the + real physical size of the screen, so we set these values with the + assumption of a screen with 72 DPI. + + \snippet examples/qws/svgalib/svgalibscreen.cpp 1 + + When the \l {QScreen::}{connect()} function returns, the server + process calls the \l {QScreen::}{initDevice()} function which is + expected to do the necessary hardware initialization, leaving the + hardware in a state consistent with the driver configuration. + + Note that we have chosen to use the software cursor. If you want + to use a hardware cursor, you should create a subclass of + QScreenCursor, create an instance of it, and make the global + variable \c qt_screencursor point to this instance. + + \snippet examples/qws/svgalib/svgalibscreen.cpp 2 + \codeline + \snippet examples/qws/svgalib/svgalibscreen.cpp 3 + + Before exiting, the server process will call the \l + {QScreen::}{shutdownDevice()} function to do the necessary + hardware cleanup. Again, it is important that the function leaves + the hardware in a state consistent with the driver + configuration. When \l {QScreen::}{shutdownDevice()} returns, the + \l {QScreen::}{disconnect()} function is called. Our + implementation of the latter function is trivial. + + Note that, provided that the \c QScreen::data variable points to a + valid linear framebuffer, the graphics driver is fully functional + as a simple screen driver at this point. The rest of this example + will show where to take advantage of the accelerated capabilities + available on the hardware. + + Whenever an area on the screen needs to be updated, the server will + call the \l {QScreen::}{exposeRegion()} function that paints the + given region on screen. The default implementation will do the + necessary composing of the top-level windows and call \l + {QScreen::}{solidFill()} and \l {QScreen::}{blit()} whenever it is + required. We do not want to change this behavior in the driver so + we do not reimplement \l {QScreen::}{exposeRegion()}. + + To control how the pixels are put onto the screen we need to + reimplement the \l {QScreen::}{solidFill()} and \l + {QScreen::}{blit()} functions. + + \snippet examples/qws/svgalib/svgalibscreen.cpp 4 + \codeline + \snippet examples/qws/svgalib/svgalibscreen.cpp 5 + + \section1 Step 2: Implementing a Custom Raster Paint Engine + + \l{Qt for Embedded Linux} uses QRasterPaintEngine (a raster-based + implementation of QPaintEngine) to implement the painting + operations. + + Acceleration of the painting operations is done by deriving from + QRasterPaintEngine class. This is a powerful mechanism for + accelerating graphic primitives while getting software fallbacks + for all the primitives you do not accelerate. + + \snippet examples/qws/svgalib/svgalibpaintengine.h 0 + + In this example, we will only accelerate one of the \l + {QRasterPaintEngine::}{drawRects()} functions, i.e., only + non-rotated, aliased and opaque rectangles will be rendered using + accelerated painting. All other primitives are rendered using the + base class's unaccelerated implementation. + + The paint engine's state is stored in the private member + variables, and we reimplement the \l + {QPaintEngine::}{updateState()} function to ensure that our + custom paint engine's state is updated properly whenever it is + required. The private \c setClip() and \c updateClip() functions + are only helper function used to simplify the \l + {QPaintEngine::}{updateState()} implementation. + + We also reimplement QRasterPaintEngine's \l + {QRasterPaintEngine::}{begin()} and \l + {QRasterPaintEngine::}{end()} functions to initialize the paint + engine and to do the cleanup when we are done rendering, + respectively. + + \table + \header \o Private Header Files + \row + \o + + Note the \c include statement used by this class. The files + prefixed with \c private/ are private headers file within + \l{Qt for Embedded Linux}. Private header files are not part of + the standard installation and are only present while + compiling Qt. To be able to compile using + private header files you need to use a \c qmake binary within a + compiled \l{Qt for Embedded Linux} package. + + \warning Private header files may change without notice between + releases. + + \endtable + + The \l {QRasterPaintEngine::}{begin()} function initializes the + internal state of the paint engine. Note that it also calls the + base class implementation to initialize the parts inherited from + QRasterPaintEngine: + + \snippet examples/qws/svgalib/svgalibpaintengine.cpp 0 + \codeline + \snippet examples/qws/svgalib/svgalibpaintengine.cpp 1 + + The implementation of the \l {QRasterPaintEngine::}{end()} + function removes the clipping constraints that might have been set + in \l {http://www.svgalib.org}{SVGAlib}, before calling the + corresponding base class implementation. + + \snippet examples/qws/svgalib/svgalibpaintengine.cpp 2 + + The \l {QPaintEngine::}{updateState()} function updates our + custom paint engine's state. The QPaintEngineState class provides + information about the active paint engine's current state. + + Note that we only accept and save the current matrix if it doesn't + do any shearing. The pen is accepted if it is opaque and only one + pixel wide. The rest of the engine's properties are updated + following the same pattern. Again it is important that the + QPaintEngine::updateState() function is called to update the + parts inherited from the base class. + + \snippet examples/qws/svgalib/svgalibpaintengine.cpp 3 + \codeline + \snippet examples/qws/svgalib/svgalibpaintengine.cpp 4 + + The \c setClip() helper function is called from our custom + implementation of \l {QPaintEngine::}{updateState()}, and + enables clipping to the given region. An empty region means that + clipping is disabled. + + Our custom update function also makes use of the \c updateClip() + helper function that checks if the clip is "simple", i.e., that it + can be represented by only one rectangle, and updates the clip + region in \l {http://www.svgalib.org}{SVGAlib}. + + \snippet examples/qws/svgalib/svgalibpaintengine.cpp 5 + + Finally, we accelerated that drawing of non-rotated, aliased and + opaque rectangles in our reimplementation of the \l + {QRasterPaintEngine::}{drawRects()} function. The + QRasterPaintEngine fallback is used whenever the rectangle is not + simple enough. + + \section1 Step 3: Making the Widgets Aware of the Custom Paint Engine + + To activate the custom paint engine, we also need to implement a + corresponding paint device and window surface and make some minor + adjustments of the graphics driver. + + \list + \o \l {Implementing a Custom Paint Device} + \o \l {Implementing a Custom Window Surface} + \o \l {Adjusting the Graphics Driver} + \endlist + + \section2 Implementing a Custom Paint Device + + The custom paint device can be derived from the + QCustomRasterPaintDevice class. Reimplement its \l + {QCustomRasterPaintDevice::}{paintEngine()} and \l + {QCustomRasterPaintDevice::}{memory()} functions to activate the + accelerated paint engine: + + \snippet examples/qws/svgalib/svgalibpaintdevice.h 0 + + The \l {QCustomRasterPaintDevice::}{paintEngine()} function should + return an instance of the \c SvgalibPaintEngine class. The \l + {QCustomRasterPaintDevice::}{memory()} function should return a + pointer to the buffer which should be used when drawing the + widget. + + Our example driver is rendering directly to the screen without any + buffering, i.e., our custom pain device's \l + {QCustomRasterPaintDevice::}{memory()} function returns a pointer + to the framebuffer. For this reason, we must also reimplement the + \l {QPaintDevice::}{metric()} function to reflect the metrics of + framebuffer. + + \section2 Implementing a Custom Window Surface + + The custom window surface can be derived from the QWSWindowSurface + class. QWSWindowSurface manages the memory used when drawing a + window. + + \snippet examples/qws/svgalib/svgalibsurface.h 0 + + We can implement most of the pure virtual functions inherited from + QWSWindowSurface as trivial inline functions, except the + \l {QWindowSurface::}{scroll()} function that actually makes use + of some hardware acceleration: + + \snippet examples/qws/svgalib/svgalibsurface.cpp 0 + + \section2 Adjusting the Graphics Driver + + Finally, we enable the graphics driver to recognize an instance of + our custom window surface: + + \snippet examples/qws/svgalib/svgalibscreen.cpp 7 + \codeline + \snippet examples/qws/svgalib/svgalibscreen.cpp 8 + + The \l {QScreen::}{createSurface()} functions are factory + functions that determines what kind of surface a top-level window + is using. In our example we only use the custom surface if the + given window has the Qt::WA_PaintOnScreen attribute or the + QT_ONSCREEN_PAINT environment variable is set. +*/ + diff --git a/doc/src/examples/svgviewer.qdoc b/doc/src/examples/svgviewer.qdoc new file mode 100644 index 0000000..affc85f --- /dev/null +++ b/doc/src/examples/svgviewer.qdoc @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example painting/svgviewer + \title SVG Viewer Example + + The SVG Viewer example shows how to add SVG viewing support to applications. + + \image svgviewer-example.png + + Scalable Vector Graphics (SVG) is an XML-based language for describing two-dimensional + vector graphics. Qt provides classes for rendering and displaying SVG drawings in + widgets and on other paint devices. This example allows the user to load SVG files + and view them in a QGraphicsView using a QGraphicsSvgItem. Based on the selected + renderer the QGraphicsView uses either a QWidget or QGLWidget as its viewport. A + third render mode is also provided, where the QGraphicsView draws indirectly though + a QImage. This allows testing of drawing accuracy and performance for both the + native, raster, and OpenGL paint engines. + + See the QtSvg module documentation for more information about SVG and Qt's SVG classes. +*/ diff --git a/doc/src/examples/syntaxhighlighter.qdoc b/doc/src/examples/syntaxhighlighter.qdoc new file mode 100644 index 0000000..7cc9e61 --- /dev/null +++ b/doc/src/examples/syntaxhighlighter.qdoc @@ -0,0 +1,256 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example richtext/syntaxhighlighter + \title Syntax Highlighter Example + + The Syntax Highlighter example shows how to perform simple syntax + highlighting by subclassing the QSyntaxHighlighter class. + + \image syntaxhighlighter-example.png + + The Syntax Highlighter application displays C++ files with custom + syntax highlighting. + + The example consists of two classes: + + \list + \o The \c Highlighter class defines and applies the + highlighting rules. + \o The \c MainWindow widget is the application's main window. + \endlist + + We will first review the \c Highlighter class to see how you can + customize the QSyntaxHighlighter class to fit your preferences, + then we will take a look at the relevant parts of the \c + MainWindow class to see how you can use your custom highlighter + class in an application. + + \section1 Highlighter Class Definition + + \snippet examples/richtext/syntaxhighlighter/highlighter.h 0 + + To provide your own syntax highlighting, you must subclass + QSyntaxHighlighter, reimplement the \l + {QSyntaxHighlighter::highlightBlock()}{highlightBlock()} function, + and define your own highlighting rules. + + We have chosen to store our highlighting rules using a private + struct: A rule consists of a QRegExp pattern and a QTextCharFormat + instance. The various rules are then stored using a QVector. + + The QTextCharFormat class provides formatting information for + characters in a QTextDocument specifying the visual properties of + the text, as well as information about its role in a hypertext + document. In this example, we will only define the font weight and + color using the QTextCharFormat::setFontWeight() and + QTextCharFormat::setForeground() functions. + + \section1 Highlighter Class Implementation + + When subclassing the QSyntaxHighlighter class you must pass the + parent parameter to the base class constructor. The parent is the + text document upon which the syntax highligning will be + applied. In this example, we have also chosen to define our + highlighting rules in the constructor: + + \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 0 + \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 1 + + First we define a keyword rule which recognizes the most common + C++ keywords. We give the \c keywordFormat a bold, dark blue + font. For each keyword, we assign the keyword and the specified + format to a HighlightingRule object and append the object to our + list of rules. + + \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 2 + \codeline + \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 4 + \codeline + \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 5 + + Then we create a format that we will apply to Qt class names. The + class names will be rendered with a dark magenta color and a bold + style. We specify a string pattern that is actually a regular + expression capturing all Qt class names. Then we assign the + regular expression and the specified format to a HighlightingRule + object and append the object to our list of rules. + + We also define highlighting rules for quotations and functions + using the same approach: The patterns have the form of regular + expressions and are stored in HighlightingRule objects with the + associated format. + + \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 3 + \codeline + \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 6 + + The C++ language has two variations of comments: The single line + comment (\c //) and the multiline comment (\c{/*...}\starslash). The single + line comment can easily be defined through a highlighting rule + similar to the previous ones. But the multiline comment needs + special care due to the design of the QSyntaxHighlighter class. + + After a QSyntaxHighlighter object is created, its \l + {QSyntaxHighlighter::highlightBlock()}{highlightBlock()} function + will be called automatically whenever it is necessary by the rich + text engine, highlighting the given text block. The problem + appears when a comment spans several text blocks. We will take a + closer look at how this problem can be solved when reviewing the + implementation of the \c Highlighter::highlightBlock() + function. At this point we only specify the multiline comment's + color. + + \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 7 + + The highlightBlock() function is called automatically whenever it + is necessary by the rich text engine, i.e. when there are text + blocks that have changed. + + First we apply the syntax highlighting rules that we stored in the + \c highlightingRules vector. For each rule (i.e. for each + HighlightingRule object) we search for the pattern in the given + textblock using the QString::indexOf() function. When the first + occurrence of the pattern is found, we use the + QRegExp::matchedLength() function to determine the string that + will be formatted. QRegExp::matchedLength() returns the length of + the last matched string, or -1 if there was no match. + + To perform the actual formatting the QSyntaxHighlighter class + provides the \l {QSyntaxHighlighter::setFormat()}{setFormat()} + function. This function operates on the text block that is passed + as argument to the \c highlightBlock() function. The specified + format is applied to the text from the given start position for + the given length. The formatting properties set in the given + format are merged at display time with the formatting information + stored directly in the document. Note that the document itself + remains unmodified by the format set through this function. + + This process is repeated until the last occurrence of the pattern + in the current text block is found. + + \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 8 + + To deal with constructs that can span several text blocks (like + the C++ multiline comment), it is necessary to know the end state + of the previous text block (e.g. "in comment"). Inside your \c + highlightBlock() implementation you can query the end state of the + previous text block using the + QSyntaxHighlighter::previousBlockState() function. After parsing + the block you can save the last state using + QSyntaxHighlighter::setCurrentBlockState(). + + The \l + {QSyntaxHighlighter::previousBlockState()}{previousBlockState()} + function return an int value. If no state is set, the returned + value is -1. You can designate any other value to identify any + given state using the \l + {QSyntaxHighlighter::setCurrentBlockState()}{setCurrentBlockState()} + function. Once the state is set, the QTextBlock keeps that value + until it is set again or until the corresponding paragraph of text + is deleted. + + In this example we have chosen to use 0 to represent the "not in + comment" state, and 1 for the "in comment" state. When the stored + syntax highlighting rules are applied we initialize the current + block state to 0. + + \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 9 + + If the previous block state was "in comment" (\c + {previousBlockState() == 1}), we start the search for an end + expression at the beginning of the text block. If the + previousBlockState() returns 0, we start the search at the + location of the first occurrence of a start expression. + + \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 10 + \snippet examples/richtext/syntaxhighlighter/highlighter.cpp 11 + + When an end expression is found, we calculate the length of the + comment and apply the multiline comment format. Then we search for + the next occurrence of the start expression and repeat the + process. If no end expression can be found in the current text + block we set the current block state to 1, i.e. "in comment". + + This completes the \c Highlighter class implementation; it is now + ready for use. + + \section1 MainWindow Class Definition + + Using a QSyntaxHighlighter subclass is simple; just provide your + application with an instance of the class and pass it the document + upon which you want the highlighting to be applied. + + \snippet examples/richtext/syntaxhighlighter/mainwindow.h 0 + + In this example we declare a pointer to a \c Highlighter instance + which we later will initialize in the private \c setupEditor() + function. + + \section1 MainWindow Class Implementation + + The constructor of the main window is straight forward. We first + set up the menus, then we initialize the editor and make it the + central widget of the application. Finally we set the main + window's title. + + \snippet examples/richtext/syntaxhighlighter/mainwindow.cpp 0 + + We initialize and install the \c Highlighter object in the private + setupEditor() convenience function: + + \snippet examples/richtext/syntaxhighlighter/mainwindow.cpp 1 + + First we create the font we want to use in the editor, then we + create the editor itself which is an instance of the QTextEdit + class. Before we initialize the editor with the \c MainWindow + class definition file, we create a \c Highlighter instance passing + the editor's document as argument. This is the document that the + highlighting will be applied to. Then we are done. + + A QSyntaxHighlighter object can only be installed on one document + at the time, but you can easily reinstall the highlighter on + another document using the QSyntaxHighlighter::setDocument() + function. The QSyntaxHighlighter class also provides the \l + {QSyntaxHighlighter::document()}{document()} function which + returns the currently set document. +*/ diff --git a/doc/src/examples/systray.qdoc b/doc/src/examples/systray.qdoc new file mode 100644 index 0000000..62bc05c --- /dev/null +++ b/doc/src/examples/systray.qdoc @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example desktop/systray + \title System Tray Icon Example + + + The System Tray Icon example shows how to add an icon with a menu + and popup messages to a desktop environment's system tray. + + \image systemtray-example.png Screenshot of the System Tray Icon. + + Modern operating systems usually provide a special area on the + desktop, called the system tray or notification area, where + long-running applications can display icons and short messages. + + This example consists of one single class, \c Window, providing + the main application window (i.e., an editor for the system tray + icon) and the associated icon. + + \image systemtray-editor.png + + The editor allows the user to choose the preferred icon as well as + set the balloon message's type and duration. The user can also + edit the message's title and body. Finally, the editor provide a + checkbox controlling whether the icon is actually shown in the + system tray, or not. + + \section1 Window Class Definition + + The \c Window class inherits QWidget: + + \snippet examples/desktop/systray/window.h 0 + + We implement several private slots to respond to user + interaction. The other private functions are only convenience + functions provided to simplify the constructor. + + The tray icon is an instance of the QSystemTrayIcon class. To + check whether a system tray is present on the user's desktop, call + the static QSystemTrayIcon::isSystemTrayAvailable() + function. Associated with the icon, we provide a menu containing + the typical \gui minimize, \gui maximize, \gui restore and \gui + quit actions. We reimplement the QWidget::setVisible() function to + update the tray icon's menu whenever the editor's appearance + changes, e.g., when maximizing or minimizing the main application + window. + + Finally, we reimplement QWidget's \l {QWidget::}{closeEvent()} + function to be able to inform the user (when closing the editor + window) that the program will keep running in the system tray + until the user chooses the \gui Quit entry in the icon's context + menu. + + \section1 Window Class Implementation + + When constructing the editor widget, we first create the various + editor elements before we create the actual system tray icon: + + \snippet examples/desktop/systray/window.cpp 0 + + We ensure that the application responds to user input by + connecting most of the editor's input widgets (including the + system tray icon) to the application's private slots. But note the + visibility checkbox; its \l {QCheckBox::}{toggled()} signal is + connected to the \e {icon}'s \l {QSystemTrayIcon::}{setVisible()} + function instead. + + \snippet examples/desktop/systray/window.cpp 3 + + The \c setIcon() slot is triggered whenever the current index in + the icon combobox changes, i.e., whenever the user chooses another + icon in the editor. Note that it is also called when the user + activates the tray icon with the left mouse button, triggering the + icon's \l {QSystemTrayIcon::}{activated()} signal. We will come + back to this signal shortly. + + The QSystemTrayIcon::setIcon() function sets the \l + {QSystemTrayIcon::}{icon} property that holds the actual system + tray icon. On Windows, the system tray icon size is 16x16; on X11, + the preferred size is 22x22. The icon will be scaled to the + appropriate size as necessary. + + Note that on X11, due to a limitation in the system tray + specification, mouse clicks on transparent areas in the icon are + propagated to the system tray. If this behavior is unacceptable, + we suggest using an icon with no transparency. + + \snippet examples/desktop/systray/window.cpp 4 + + Whenever the user activates the system tray icon, it emits its \l + {QSystemTrayIcon::}{activated()} signal passing the triggering + reason as parameter. QSystemTrayIcon provides the \l + {QSystemTrayIcon::}{ActivationReason} enum to describe how the + icon was activated. + + In the constructor, we connected our icon's \l + {QSystemTrayIcon::}{activated()} signal to our custom \c + iconActivated() slot: If the user has clicked the icon using the + left mouse button, this function changes the icon image by + incrementing the icon combobox's current index, triggering the \c + setIcon() slot as mentioned above. If the user activates the icon + using the middle mouse button, it calls the custom \c + showMessage() slot: + + \snippet examples/desktop/systray/window.cpp 5 + + When the \e showMessage() slot is triggered, we first retrieve the + message icon depending on the currently chosen message type. The + QSystemTrayIcon::MessageIcon enum describes the icon that is shown + when a balloon message is displayed. Then we call + QSystemTrayIcon's \l {QSystemTrayIcon::}{showMessage()} function + to show the message with the title, body, and icon for the time + specified in milliseconds. + + Mac OS X users note: The Growl notification system must be + installed for QSystemTrayIcon::showMessage() to display messages. + + QSystemTrayIcon also has the corresponding, \l {QSystemTrayIcon::} + {messageClicked()} signal, which is emitted when the user clicks a + message displayed by \l {QSystemTrayIcon::}{showMessage()}. + + \snippet examples/desktop/systray/window.cpp 6 + + In the constructor, we connected the \l + {QSystemTrayIcon::}{messageClicked()} signal to our custom \c + messageClicked() slot that simply displays a message using the + QMessageBox class. + + QMessageBox provides a modal dialog with a short message, an icon, + and buttons laid out depending on the current style. It supports + four severity levels: "Question", "Information", "Warning" and + "Critical". The easiest way to pop up a message box in Qt is to + call one of the associated static functions, e.g., + QMessageBox::information(). + + As we mentioned earlier, we reimplement a couple of QWidget's + virtual functions: + + \snippet examples/desktop/systray/window.cpp 1 + + Our reimplementation of the QWidget::setVisible() function updates + the tray icon's menu whenever the editor's appearance changes, + e.g., when maximizing or minimizing the main application window, + before calling the base class implementation. + + \snippet examples/desktop/systray/window.cpp 2 + + We have reimplemented the QWidget::closeEvent() event handler to + receive widget close events, showing the above message to the + users when they are closing the editor window. + + In addition to the functions and slots discussed above, we have + also implemented several convenience functions to simplify the + constructor: \c createIconGroupBox(), \c createMessageGroupBox(), + \c createActions() and \c createTrayIcon(). See the \l + {desktop/systray/window.cpp}{window.cpp} file for details. +*/ diff --git a/doc/src/examples/tabdialog.qdoc b/doc/src/examples/tabdialog.qdoc new file mode 100644 index 0000000..c9500af --- /dev/null +++ b/doc/src/examples/tabdialog.qdoc @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example dialogs/tabdialog + \title Tab Dialog Example + + The Tab Dialog example shows how to construct a tab dialog using the + QTabWidget class. + + Dialogs provide an efficient way for the application to communicate + with the user, but complex dialogs suffer from the problem that they + often take up too much screen area. By using a number of tabs in a + dialog, information can be split into different categories, while + remaining accessible. + + \image tabdialog-example.png + + The Tab Dialog example consists of a single \c TabDialog class that + provides three tabs, each containing information about a particular + file, and two standard push buttons that are used to accept or reject + the contents of the dialog. + + \section1 TabDialog Class Definition + + The \c TabDialog class is a subclass of QDialog that displays a + QTabWidget and two standard dialog buttons. The class definition + only contain the class constructor and a private data member for + the QTabWidget: + + \snippet examples/dialogs/tabdialog/tabdialog.h 3 + + In the example, the widget will be used as a top-level window, but + we define the constructor so that it can take a parent widget. This + allows the dialog to be centered on top of an application's main + window. + + \section1 TabDialog Class Implementation + + The constructor calls the QDialog constructor and creates a QFileInfo + object for the specified filename. + + \snippet examples/dialogs/tabdialog/tabdialog.cpp 0 + + The tab widget is populated with three custom widgets that each + contain information about the file. We construct each of these + without a parent widget because the tab widget will reparent + them as they are added to it. + + We create two standard push buttons, and connect each of them to + the appropriate slots in the dialog: + + \snippet examples/dialogs/tabdialog/tabdialog.cpp 1 + \snippet examples/dialogs/tabdialog/tabdialog.cpp 3 + + We arrange the the tab widget above the buttons in the dialog: + + \snippet examples/dialogs/tabdialog/tabdialog.cpp 4 + + Finally, we set the dialog's title: + + \snippet examples/dialogs/tabdialog/tabdialog.cpp 5 + + Each of the tabs are subclassed from QWidget, and only provide + constructors. + + \section1 GeneralTab Class Definition + + The GeneralTab widget definition is simple because we are only interested + in displaying the contents of a widget within a tab: + + \snippet examples/dialogs/tabdialog/tabdialog.h 0 + + \section1 GeneralTab Class Implementation + + The GeneralTab widget simply displays some information about the file + passed by the TabDialog. Various widgets for this purpose, and these + are arranged within a vertical layout: + + \snippet examples/dialogs/tabdialog/tabdialog.cpp 6 + + \section1 PermissionsTab Class Definition + + Like the GeneralTab, the PermissionsTab is just used as a placeholder + widget for its children: + + \snippet examples/dialogs/tabdialog/tabdialog.h 1 + + \section1 PermissionsTab Class Implementation + + The PermissionsTab shows information about the file's access information, + displaying details of the file permissions and owner in widgets that are + arranged in nested layouts: + + \snippet examples/dialogs/tabdialog/tabdialog.cpp 7 + + \section1 ApplicationsTab Class Definition + + The ApplicationsTab is another placeholder widget that is mostly + cosmetic: + + \snippet examples/dialogs/tabdialog/tabdialog.h 2 + + \section1 ApplicationsTab Class Implementation + + The ApplicationsTab does not show any useful information, but could be + used as a template for a more complicated example: + + \snippet examples/dialogs/tabdialog/tabdialog.cpp 8 +*/ diff --git a/doc/src/examples/tablemodel.qdoc b/doc/src/examples/tablemodel.qdoc new file mode 100644 index 0000000..e3d4a22 --- /dev/null +++ b/doc/src/examples/tablemodel.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example sql/tablemodel + \title Table Model Example + + The Table Model example shows how to use a specialized SQL table model with table + views to edit information in a database. + + \image tablemodel-example.png +*/ diff --git a/doc/src/examples/tablet.qdoc b/doc/src/examples/tablet.qdoc new file mode 100644 index 0000000..476bba1 --- /dev/null +++ b/doc/src/examples/tablet.qdoc @@ -0,0 +1,380 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/tablet + \title Tablet Example + + This example shows how to use a Wacom tablet in Qt applications. + + \image tabletexample.png + + When you use a tablet with Qt applications, \l{QTabletEvent}s are + genarated. You need to reimplement the + \l{QWidget::}{tabletEvent()} event handler if you want to handle + tablet events. Events are generated when the device used for + drawing enters and leaves the proximity of the tablet (i.e., when + it is close but not pressed down on it), when a device is pushed + down and released from it, and when a device is moved on the + tablet. + + The information available in QTabletEvent depends on the device + used. The tablet in this example has two different devices for + drawing: a stylus and an airbrush. For both devices the event + contains the position of the device, pressure on the tablet, + vertical tilt, and horizontal tilt (i.e, the angle between the + device and the perpendicular of the tablet). The airbrush has a + finger wheel; the position of this is also available in the tablet + event. + + In this example we implement a drawing program. You can use the + stylus to draw on the tablet as you use a pencil on paper. When + you draw with the airbrush you get a spray of paint; the finger + wheel is used to change the density of the spray. The pressure and + tilt can change the alpha and saturation values of the QColor and the + width of the QPen used for drawing. + + The example consists of the following: + + \list + \o The \c MainWindow class inherits QMainWindow and creates + the examples menus and connect their slots and signals. + \o The \c TabletCanvas class inherits QWidget and + receives tablet events. It uses the events to paint on a + QImage, which it draws onto itself. + \o The \c TabletApplication class inherits QApplication. This + class handles tablet events that are not sent to \c tabletEvent(). + We will look at this later. + \o The \c main() function creates a \c MainWindow and shows it + as a top level window. + \endlist + + + \section1 MainWindow Class Definition + + The \c MainWindow creates a \c TabletCanvas and sets it as its + center widget. + + \snippet examples/widgets/tablet/mainwindow.h 0 + + The QActions let the user select if the tablets pressure and + tilt should change the pen width, color alpha component and color + saturation. \c createActions() creates all actions, and \c + createMenus() sets up the menus with the actions. We have one + QActionGroup for the actions that alter the alpha channel, color + saturation and line width respectively. The action groups are + connected to the \c alphaActionTriggered(), \c + colorSaturationActiontriggered(), and \c + lineWidthActionTriggered() slots, which calls functions in \c + myCanvas. + + + \section1 MainWindow Class Implementation + + We start width a look at the constructor \c MainWindow(): + + \snippet examples/widgets/tablet/mainwindow.cpp 0 + + In the constructor we create the canvas, actions, and menus. + We set the canvas as the center widget. We also initialize the + canvas to match the state of our menus and start drawing with a + red color. + + Here is the implementation of \c brushColorAct(): + + \snippet examples/widgets/tablet/mainwindow.cpp 1 + + We let the user pick a color with a QColorDialog. If it is valid, + we set a new drawing color with \c setColor(). + + Here is the implementation of \c alphaActionTriggered(): + + \snippet examples/widgets/tablet/mainwindow.cpp 2 + + The \c TabletCanvas class supports two ways by which the alpha + channel of the drawing color can be changed: tablet pressure and + tilt. We have one action for each and an action if the alpha + channel should not be changed. + + Here is the implementation of \c lineWidthActionTriggered(): + + \snippet examples/widgets/tablet/mainwindow.cpp 3 + + We check which action is selected in \c lineWidthGroup, and set + how the canvas should change the drawing line width. + + Here is the implementation of \c saturationActionTriggered(): + + \snippet examples/widgets/tablet/mainwindow.cpp 4 + + We check which action is selected in \c colorSaturationGroup, and + set how the canvas should change the color saturation of the + drawing color. + + Here is the implementation of \c saveAct(): + + \snippet examples/widgets/tablet/mainwindow.cpp 5 + + We use the QFileDialog to let the user select a file to save the + drawing in. It is the \c TabletCanvas that save the drawing, so we + call its \c saveImage() function. + + Here is the implementation of \c loadAct(): + + \snippet examples/widgets/tablet/mainwindow.cpp 6 + + We let the user select the image file to be opened with + a QFileDialog; we then ask the canvas to load the image with \c + loadImage(). + + Here is the implementation of \c aboutAct(): + + \snippet examples/widgets/tablet/mainwindow.cpp 7 + + We show a message box with a short description of the example. + + \c createActions() creates all actions and action groups of + the example. We look at the creation of one action group and its + actions. See the \l{Application Example}{application example} if + you want a high-level introduction to QActions. + + Here is the implementation of \c createActions: + + \snippet examples/widgets/tablet/mainwindow.cpp 8 + \dots + \snippet examples/widgets/tablet/mainwindow.cpp 9 + + We want the user to be able to choose if the drawing color's + alpha component should be changed by the tablet pressure or tilt. + We have one action for each choice and an action if the alpha + channel is not to be changed, i.e, the color is opaque. We make + the actions checkable; the \c alphaChannelGroup will then ensure + that only one of the actions are checked at any time. The \c + triggered() signal is emitted when an action is checked. + + \dots + \snippet examples/widgets/tablet/mainwindow.cpp 10 + + Here is the implementation of \c createMenus(): + + \snippet examples/widgets/tablet/mainwindow.cpp 11 + + We create the menus of the example and add the actions to them. + + + \section1 TabletCanvas Class Definition + + The \c TabletCanvas class provides a surface on which the + user can draw with a tablet. + + \snippet examples/widgets/tablet/tabletcanvas.h 0 + + The canvas can change the alpha channel, color saturation, + and line width of the drawing. We have one enum for each of + these; their values decide if it is the tablet pressure or tilt + that will alter them. We keep a private variable for each, the \c + alphaChannelType, \c colorSturationType, and \c penWidthType, + which we provide access functions for. + + We draw on a QImage with \c myPen and \c myBrush using \c + myColor. The \c saveImage() and \c loadImage() saves and loads + the QImage to disk. The image is drawn on the widget in \c + paintEvent(). The \c pointerType and \c deviceType keeps the type + of pointer, which is either a pen or an eraser, and device + currently used on the tablet, which is either a stylus or an + airbrush. + + The interpretation of events from the tablet is done in \c + tabletEvent(); \c paintImage(), \c updateBrush(), and \c + brushPattern() are helper functions used by \c tabletEvent(). + + + \section1 TabletCanvas Class Implementation + + We start with a look at the constructor: + + \snippet examples/widgets/tablet/tabletcanvas.cpp 0 + + In the constructor we initialize our class variables. We need + to draw the background of our image, as the default is gray. + + Here is the implementation of \c saveImage(): + + \snippet examples/widgets/tablet/tabletcanvas.cpp 1 + + QImage implements functionality to save itself to disk, so we + simply call \l{QImage::}{save()}. + + Here is the implementation of \c loadImage(): + + \snippet examples/widgets/tablet/tabletcanvas.cpp 2 + + We simply call \l{QImage::}{load()}, which loads the image in \a + file. + + Here is the implementation of \c tabletEvent(): + + \snippet examples/widgets/tablet/tabletcanvas.cpp 3 + + We get three kind of events to this function: TabletPress, + TabletRelease, and TabletMove, which is generated when a device + is pressed down on, leaves, or moves on the tablet. We set the \c + deviceDown to true when a device is pressed down on the tablet; + we then know when we should draw when we receive move events. We + have implemented the \c updateBrush() and \c paintImage() helper + functions to update \c myBrush and \c myPen after the state of \c + alphaChannelType, \c colorSaturationType, and \c lineWidthType. + + Here is the implementation of \c paintEvent(): + + \snippet examples/widgets/tablet/tabletcanvas.cpp 4 + + We simply draw the image to the top left of the widget. + + Here is the implementation of \c paintImage(): + + \snippet examples/widgets/tablet/tabletcanvas.cpp 5 + + In this function we draw on the image based on the movement of the + device. If the device used on the tablet is a stylus we want to draw a + line between the positions of the stylus recorded in \c polyLine. + If it is an airbrush we want to draw a circle of points with a + point density based on the tangential pressure, which is the position + of the finger wheel on the airbrush. We use the Qt::BrushStyle to + draw the points as it has styles that draw points with different + density; we select the style based on the tangential pressure in + \c brushPattern(). + + \snippet examples/widgets/tablet/tabletcanvas.cpp 6 + + We return a brush style with a point density that increases with + the tangential pressure. + + In \c updateBrush() we set the pen and brush used for drawing + to match \c alphaChannelType, \c lineWidthType, \c + colorSaturationType, and \c myColor. We will examine the code to + set up \c myBrush and \c myPen for each of these variables: + + \snippet examples/widgets/tablet/tabletcanvas.cpp 7 + + We fetch the current drawingcolor's hue, saturation, value, + and alpha values. \c hValue and \c vValue are set to the + horizontal and vertical tilt as a number from 0 to 255. The + original values are in degrees from -60 to 60, i.e., 0 equals + -60, 127 equals 0, and 255 equals 60 degrees. The angle measured + is between the device and the perpendicular of the tablet (see + QTabletEvent for an illustration). + + \snippet examples/widgets/tablet/tabletcanvas.cpp 8 + + The alpha channel of QColor is given as a number between 0 + and 255 where 0 is transparent and 255 is opaque. + \l{QTabletEvent::}{pressure()} returns the pressure as a qreal + between 0.0 and 1.0. By subtracting 127 from the tilt values and + taking the absolute value we get the smallest alpha values (i.e., + the color is most transparent) when the pen is perpendicular to + the tablet. We select the largest of the vertical and horizontal + tilt value. + + \snippet examples/widgets/tablet/tabletcanvas.cpp 9 + + The colorsaturation is given as a number between 0 and 255. It is + set with \l{QColor::}{setHsv()}. We can set the tilt values + directly, but must multiply the pressure to a number between 0 and + 255. + + \snippet examples/widgets/tablet/tabletcanvas.cpp 10 + + The width of the pen increases with the pressure. When the pen + width is controlled with the tilt we let the width increse with + the angle between the device and the perpendicular of the tablet. + + \snippet examples/widgets/tablet/tabletcanvas.cpp 11 + + We finally check wether the pointer is the stylus or the eraser. + If it is the eraser, we set the color to the background color of + the image an let the pressure decide the pen width, else we set + the colors we have set up previously in the function. + + + \section1 TabletApplication Class Definition + + We inherit QApplication in this class because we want to + reimplement the \l{QApplication::}{event()} function. + + \snippet examples/widgets/tablet/tabletapplication.h 0 + + We keep a \c TabletCanvas we send the device type of the events we + handle in the \c event() function to. The TabletEnterProximity + and TabletLeaveProximity events are not sendt to the QApplication + object, while other tablet events are sendt to the QWidget's + \c event(), which sends them on to \l{QWidget::}{tabletEvent()}. + Since we want to handle these events we have implemented \c + TabletApplication. + + + \section1 TabletApplication Class Implementation + + Here is the implementation of \c event(): + + \snippet examples/widgets/tablet/tabletapplication.cpp 0 + + We use this function to handle the TabletEnterProximity and + TabletLeaveProximity events, which is generated when a device + enters and leaves the proximity of the tablet. The intended use of these + events is to do work that is dependent on what kind of device is + used on the tablet. This way, you don't have to do this work + when other events are generated, which is more frequently than the + leave and enter proximity events. We call \c setTabletDevice() in + \c TabletCanvas. + + \section1 The \c main() function + + Here is the examples \c main() function: + + \snippet examples/widgets/tablet/main.cpp 0 + + In the \c main() function we create a \c MainWinow and display it + as a top level window. We use the \c TabletApplication class. We + need to set the canvas after the application is created. We cannot + use classes that implement event handling before an QApplication + object is instantiated. +*/ diff --git a/doc/src/examples/taskmenuextension.qdoc b/doc/src/examples/taskmenuextension.qdoc new file mode 100644 index 0000000..b02da6c --- /dev/null +++ b/doc/src/examples/taskmenuextension.qdoc @@ -0,0 +1,457 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example designer/taskmenuextension + \title Task Menu Extension Example + + The Task Menu Extension example shows how to create a custom + widget plugin for \l {Qt Designer Manual}{\QD}, and how to to use + the QDesignerTaskMenuExtension class to provide custom task menu + entries associated with the plugin. + + \image taskmenuextension-example-faded.png + + To provide a custom widget that can be used with \QD, we need to + supply a self-contained implementation. In this example we use a + custom widget designed to show the task menu extension feature: + The TicTacToe widget. + + An extension is an object which modifies the behavior of \QD. The + QDesignerTaskMenuExtension can provide custom task menu entries + when a widget with this extension is selected. + + There are four available types of extensions in \QD: + + \list + \o QDesignerContainerExtension provides an extension that allows + you to add (and delete) pages to a multi-page container plugin + in \QD. + \o QDesignerMemberSheetExtension provides an extension that allows + you to manipulate a widget's member functions which is displayed + when configuring connections using Qt Designer's mode for editing + signals and slots. + \o QDesignerPropertySheetExtension provides an extension that + allows you to manipulate a widget's properties which is displayed + in Qt Designer's property editor. + \o QDesignerTaskMenuExtension provides an extension that allows + you to add custom menu entries to \QD's task menu. + \endlist + + You can use all the extensions following the same pattern as in + this example, only replacing the respective extension base + class. For more information, see the \l {QtDesigner Module}. + + The Task Menu Extension example consists of five classes: + + \list + \o \c TicTacToe is a custom widget that lets the user play + the Tic-Tac-Toe game. + \o \c TicTacToePlugin exposes the \c TicTacToe class to \QD. + \o \c TicTacToeTaskMenuFactory creates a \c TicTacToeTaskMenu object. + \o \c TicTacToeTaskMenu provides the task menu extension, i.e the + plugin's associated task menu entries. + \o \c TicTacToeDialog lets the user modify the state of a + Tic-Tac-Toe plugin loaded into \QD. + \endlist + + The project file for custom widget plugins needs some additional + information to ensure that they will work within \QD. For example, + custom widget plugins rely on components supplied with \QD, and + this must be specified in the project file that we use. We will + first take a look at the plugin's project file. + + Then we will continue by reviewing the \c TicTacToePlugin class, + and take a look at the \c TicTacToeTaskMenuFactory and \c + TicTacToeTaskMenu classes. Finally, we will review the \c + TicTacToeDialog class before we take a quick look at the \c + TicTacToe widget's class definition. + + \section1 The Project File: taskmenuextension.pro + + The project file must contain some additional information to + ensure that the plugin will work as expected: + + \snippet examples/designer/taskmenuextension/taskmenuextension.pro 0 + \snippet examples/designer/taskmenuextension/taskmenuextension.pro 1 + + The \c TEMPLATE variable's value makes \c qmake create the custom + widget as a library. Later, we will ensure that the widget will be + recognized as a plugin by Qt by using the Q_EXPORT_PLUGIN2() macro to + export the relevant widget information. + + The \c CONFIG variable contains two values, \c designer and \c + plugin: + + \list + \o \c designer: Since custom widgets plugins rely on components + supplied with \QD, this value ensures that our plugin links against + \QD's library (\c libQtDesigner.so). + + \o \c plugin: We also need to ensure that \c qmake considers the + custom widget a \e plugin library. + \endlist + + When Qt is configured to build in both debug and release modes, + \QD will be built in release mode. When this occurs, it is + necessary to ensure that plugins are also built in release + mode. For that reason we add the \c debug_and_release value to + the \c CONFIG variable. Otherwise, if a plugin is built in a mode + that is incompatible with \QD, it won't be loaded and + installed. + + The header and source files for the widget are declared in the + usual way: + + \snippet examples/designer/taskmenuextension/taskmenuextension.pro 2 + + We provide an implementation of the plugin interface so that \QD + can use the custom widget. In this particular example we also + provide implementations of the task menu extension and the + extension factory as well as a dialog implementation. + + It is important to ensure that the plugin is installed in a + location that is searched by \QD. We do this by specifying a + target path for the project and adding it to the list of items to + install: + + \snippet doc/src/snippets/code/doc_src_examples_taskmenuextension.qdoc 0 + + The task menu extension is created as a library, and will be + installed alongside the other \QD plugins when the project is + installed (using \c{make install} or an equivalent installation + procedure). + + Note that if you want the plugins to appear in a Visual Studio + integration, the plugins must be built in release mode and their + libraries must be copied into the plugin directory in the install + path of the integration (for an example, see \c {C:/program + files/trolltech as/visual studio integration/plugins}). + + For more information about plugins, see the \l {How to Create Qt + Plugins} documentation. + + \section1 TicTacToePlugin Class Definition + + The \c TicTacToePlugin class exposes \c the TicTacToe class to + \QD. Its definition is equivalent to the \l + {designer/customwidgetplugin}{Custom Widget Plugin} example's + plugin class which is explained in detail. The only part of the + class definition that is specific to this particular custom widget + is the class name: + + \snippet examples/designer/taskmenuextension/tictactoeplugin.h 0 + + The plugin class provides \QD with basic information about our + plugin, such as its class name and its include file. Furthermore + it knows how to create instances of the \c TicTacToe widget. + TicTacToePlugin also defines the \l + {QDesignerCustomWidgetInterface::initialize()}{initialize()} + function which is called after the plugin is loaded into \QD. The + function's QDesignerFormEditorInterface parameter provides the + plugin with a gateway to all of \QD's API's. + + The \c TicTacToePlugin class inherits from both QObject and + QDesignerCustomWidgetInterface. It is important to remember, when + using multiple inheritance, to ensure that all the interfaces + (i.e. the classes that doesn't inherit Q_OBJECT) are made known to + the meta object system using the Q_INTERFACES() macro. This + enables \QD to use \l qobject_cast() to query for supported + interfaces using nothing but a QObject pointer. + + \section1 TicTacToePlugin Class Implementation + + The TicTacToePlugin class implementation is in most parts + equivalent to the \l {designer/customwidgetplugin}{Custom Widget + Plugin} example's plugin class: + + \snippet examples/designer/taskmenuextension/tictactoeplugin.cpp 0 + + The only function that differs significantly is the initialize() + function: + + \snippet examples/designer/taskmenuextension/tictactoeplugin.cpp 1 + + The \c initialize() function takes a QDesignerFormEditorInterface + object as argument. The QDesignerFormEditorInterface class + provides access to Qt Designer's components. + + In \QD you can create two kinds of plugins: custom widget plugins + and tool plugins. QDesignerFormEditorInterface provides access to + all the \QD components that you normally need to create a tool + plugin: the extension manager, the object inspector, the property + editor and the widget box. Custom widget plugins have access to + the same components. + + \snippet examples/designer/taskmenuextension/tictactoeplugin.cpp 2 + + When creating extensions associated with custom widget plugins, we + need to access \QD's current extension manager which we retrieve + from the QDesignerFormEditorInterface parameter. + + \QD's QDesignerFormEditorInterface holds information about all Qt + Designer's components: The action editor, the object inspector, + the property editor, the widget box, and the extension and form + window managers. + + The QExtensionManager class provides extension management + facilities for \QD. Using \QD's current extension manager you can + retrieve the extension for a given object. You can also register + and unregister an extension for a given object. Remember that an + extension is an object which modifies the behavior of \QD. + + When registrering an extension, it is actually the associated + extension factory that is registered. In \QD, extension factories + are used to look up and create named extensions as they are + required. So, in this example, the task menu extension itself is + not created until a task menu is requested by the user. + + \snippet examples/designer/taskmenuextension/tictactoeplugin.cpp 3 + + We create a \c TicTacToeTaskMenuFactory object that we register + using \QD's current \l {QExtensionManager}{extension manager} + retrieved from the QDesignerFormEditorInterface parameter. The + first argument is the newly created factory and the second + argument is an extension identifier which is a string. The \c + Q_TYPEID() macro simply converts the string into a QLatin1String. + + The \c TicTacToeTaskMenuFactory class is a subclass of + QExtensionFactory. When the user request a task menu by clicking + the right mouse button over a widget with the specified task menu + extension, \QD's extension manager will run through all its + registered factories invoking the first one that is able to create + a task menu extension for the selected widget. This factory will + in turn create a \c TicTacToeTaskMenu object (the extension). + + We omit to reimplement the + QDesignerCustomWidgetInterface::domXml() function (which include + default settings for the widget in the standard XML format used by + Qt Designer), since no default values are necessary. + + \snippet examples/designer/taskmenuextension/tictactoeplugin.cpp 4 + + Finally, we use the Q_EXPORT_PLUGIN2() macro to export the + TicTacToePlugin class for use with Qt's plugin handling classes: + This macro ensures that \QD can access and construct the custom + widget. Without this macro, there is no way for \QD to use the + widget. + + \section1 TicTacToeTaskMenuFactory Class Definition + + The \c TicTacToeTaskMenuFactory class inherits QExtensionFactory + which provides a standard extension factory for \QD. + + \snippet examples/designer/taskmenuextension/tictactoetaskmenu.h 1 + + The subclass's purpose is to reimplement the + QExtensionFactory::createExtension() function, making it able to + create a \c TicTacToe task menu extension. + + \section1 TicTacToeTaskMenuFactory Class Implementation + + The class constructor simply calls the QExtensionFactory base + class constructor: + + \snippet examples/designer/taskmenuextension/tictactoetaskmenu.cpp 4 + + As described above, the factory is invoked when the user request a + task menu by clicking the right mouse button over a widget with + the specified task menu extension in \QD. + + \QD's behavior is the same whether the requested extension is + associated with a container, a member sheet, a property sheet or a + task menu: Its extension manager runs through all its registered + extension factories calling \c createExtension() for each until + one responds by creating the requested extension. + + \snippet examples/designer/taskmenuextension/tictactoetaskmenu.cpp 5 + + So the first thing we do in \c + TicTacToeTaskMenuFactory::createExtension() is to check if the + requested extension is a task menu extension. If it is, and the + widget requesting it is a \c TicTacToe widget, we create and + return a \c TicTacToeTaskMenu object. Otherwise, we simply return + a null pointer, allowing \QD's extension manager to continue its + search through the registered factories. + + + \section1 TicTacToeTaskMenu Class Definition + + \image taskmenuextension-menu.png + + The \c TicTacToeTaskMenu class inherits QDesignerTaskMenuExtension + which allows you to add custom entries (in the form of QActions) + to the task menu in \QD. + + \snippet examples/designer/taskmenuextension/tictactoetaskmenu.h 0 + + We reimplement the \c preferredEditAction() and \c taskActions() + functions. Note that we implement a constructor that takes \e two + arguments: the parent widget, and the \c TicTacToe widget for + which the task menu is requested. + + In addition we declare the private \c editState() slot, our custom + \c editStateAction and a private pointer to the \c TicTacToe + widget which state we want to modify. + + \section1 TicTacToeTaskMenu Class Implementation + + \snippet examples/designer/taskmenuextension/tictactoetaskmenu.cpp 0 + + In the constructor we first save the reference to the \c TicTacToe + widget sent as parameter, i.e the widget which state we want to + modify. We will need this later when our custom action is + invoked. We also create our custom \c editStateAction and connect + it to the \c editState() slot. + + \snippet examples/designer/taskmenuextension/tictactoetaskmenu.cpp 1 + + The \c editState() slot is called whenever the user chooses the + \gui {Edit State...} option in a \c TicTacToe widget's task menu. The + slot creates a \c TicTacToeDialog presenting the current state of + the widget, and allowing the user to edit its state by playing the + game. + + \snippet examples/designer/taskmenuextension/tictactoetaskmenu.cpp 2 + + We reimplement the \c preferredEditAction() function to return our + custom \c editStateAction as the action that should be invoked + when selecting a \c TicTacToe widget and pressing \key F2 . + + \snippet examples/designer/taskmenuextension/tictactoetaskmenu.cpp 3 + + We reimplement the \c taskActions() function to return a list of + our custom actions making these appear on top of the default menu + entries in a \c TicTacToe widget's task menu. + + \section1 TicTacToeDialog Class Definition + + \image taskmenuextension-dialog.png + + The \c TicTacToeDialog class inherits QDialog. The dialog lets the + user modify the state of the currently selected Tic-Tac-Toe + plugin. + + \snippet examples/designer/taskmenuextension/tictactoedialog.h 0 + + We reimplement the \c sizeHint() function. We also declare two + private slots: \c resetState() and \c saveState(). In addition to + the dialog's buttons and layouts we declare two \c TicTacToe + pointers, one to the widget the user can interact with and the + other to the original custom widget plugin which state the user + wants to edit. + + \section1 TicTacToeDialog Class Implementation + + \snippet examples/designer/taskmenuextension/tictactoedialog.cpp 0 + + In the constructor we first save the reference to the TicTacToe + widget sent as parameter, i.e the widget which state the user want + to modify. Then we create a new \c TicTacToe widget, and set its + state to be equivalent to the parameter widget's state. + + Finally, we create the dialog's buttons and layout. + + \snippet examples/designer/taskmenuextension/tictactoedialog.cpp 1 + + We reimplement the \c sizeHint() function to ensure that the + dialog is given a reasonable size. + + \snippet examples/designer/taskmenuextension/tictactoedialog.cpp 2 + + The \c resetState() slot is called whenever the user press the + \gui Reset button. The only thing we do is to call the \c + clearBoard() function for the editor widget, i.e. the \c TicTacToe + widget we created in the dialog's constructor. + + \snippet examples/designer/taskmenuextension/tictactoedialog.cpp 3 + + The \c saveState() slot is called whenever the user press the \gui + OK button, and transfers the state of the editor widget to the + widget which state we want to modify. In order to make the change + of state visible to \QD we need to set the latter widget's state + property using the QDesignerFormWindowInterface class. + + QDesignerFormWindowInterface provides you with information about + the associated form window as well as allowing you to alter its + properties. The interface is not intended to be instantiated + directly, but to provide access to Qt Designer's current form + windows controlled by Qt Designer's form window manager. + + If you are looking for the form window containing a specific + widget, you can use the static + QDesignerFormWindowInterface::findFormWindow() function: + + \snippet examples/designer/taskmenuextension/tictactoedialog.cpp 4 + + After retrieving the form window of the widget (which state we + want to modify), we use the QDesignerFormWindowInterface::cursor() + function to retrieve the form window's cursor. + + The QDesignerFormWindowCursorInterface class provides an interface + to the form window's text cursor. Once we have cursor, we can + finally set the state property using the + QDesignerFormWindowCursorInterface::setProperty() function. + + \snippet examples/designer/taskmenuextension/tictactoedialog.cpp 5 + + In the end we call the QEvent::accept() function which sets the + accept flag of the event object. Setting the \c accept parameter + indicates that the event receiver wants the event. Unwanted events + might be propagated to the parent widget. + + \section1 TicTacToe Class Definition + + The \c TicTacToe class is a custom widget that lets the user play + the Tic-Tac-Toe game. + + \snippet examples/designer/taskmenuextension/tictactoe.h 0 + + The main details to observe in the \c TicTacToe class defintion is + the declaration of the \c state property and its \c state() and \c + setState() functions. + + We need to declare the \c TicTacToe widget's state as a property + to make it visible to \QD; allowing \QD to manage it in the same + way it manages the properties the \c TicTacToe widget inherits + from QWidget and QObject, for example featuring the property + editor. +*/ diff --git a/doc/src/examples/tetrix.qdoc b/doc/src/examples/tetrix.qdoc new file mode 100644 index 0000000..b9adb98 --- /dev/null +++ b/doc/src/examples/tetrix.qdoc @@ -0,0 +1,445 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/tetrix + \title Tetrix Example + + The Tetrix example is a Qt version of the classic Tetrix game. + + \image tetrix-example.png + + The object of the game is to stack pieces dropped from the top of the + playing area so that they fill entire rows at the bottom of the playing area. + + When a row is filled, all the blocks on that row are removed, the player earns + a number of points, and the pieces above are moved down to occupy that row. + If more than one row is filled, the blocks on each row are removed, and the + player earns extra points. + + The \gui{Left} cursor key moves the current piece one space to the left, the + \gui{Right} cursor key moves it one space to the right, the \gui{Up} cursor + key rotates the piece counter-clockwise by 90 degrees, and the \gui{Down} + cursor key rotates the piece clockwise by 90 degrees. + + To avoid waiting for a piece to fall to the bottom of the board, press \gui{D} + to immediately move the piece down by one row, or press the \gui{Space} key to + drop it as close to the bottom of the board as possible. + + This example shows how a simple game can be created using only three classes: + + \list + \o The \c TetrixWindow class is used to display the player's score, number of + lives, and information about the next piece to appear. + \o The \c TetrixBoard class contains the game logic, handles keyboard input, and + displays the pieces on the playing area. + \o The \c TetrixPiece class contains information about each piece. + \endlist + + In this approach, the \c TetrixBoard class is the most complex class, since it + handles the game logic and rendering. One benefit of this is that the + \c TetrixWindow and \c TetrixPiece classes are very simple and contain only a + minimum of code. + + \section1 TetrixWindow Class Definition + + The \c TetrixWindow class is used to display the game information and contains + the playing area: + + \snippet examples/widgets/tetrix/tetrixwindow.h 0 + + We use private member variables for the board, various display widgets, and + buttons to allow the user to start a new game, pause the current game, and quit. + + Although the window inherits QWidget, the constructor does not provide an + argument to allow a parent widget to be specified. This is because the window + will always be used as a top-level widget. + + \section1 TetrixWindow Class Implementation + + The constructor sets up the user interface elements for the game: + + \snippet examples/widgets/tetrix/tetrixwindow.cpp 0 + + We begin by constructing a \c TetrixBoard instance for the playing area and a + label that shows the next piece to be dropped into the playing area; the label + is initially empty. + + Three QLCDNumber objects are used to display the score, number of lives, and + lines removed. These initially show default values, and will be filled in + when a game begins: + + \snippet examples/widgets/tetrix/tetrixwindow.cpp 1 + + Three buttons with shortcuts are constructed so that the user can start a + new game, pause the current game, and quit the application: + + \snippet examples/widgets/tetrix/tetrixwindow.cpp 2 + \snippet examples/widgets/tetrix/tetrixwindow.cpp 3 + + These buttons are configured so that they never receive the keyboard focus; + we want the keyboard focus to remain with the \c TetrixBoard instance so that + it receives all the keyboard events. Nonetheless, the buttons will still respond + to \key{Alt} key shortcuts. + + We connect \l{QAbstractButton::}{clicked()} signals from the \gui{Start} + and \gui{Pause} buttons to the board, and from the \gui{Quit} button to the + application's \l{QApplication::}{quit()} slot. + + \snippet examples/widgets/tetrix/tetrixwindow.cpp 4 + \snippet examples/widgets/tetrix/tetrixwindow.cpp 5 + + Signals from the board are also connected to the LCD widgets for the purpose of + updating the score, number of lives, and lines removed from the playing area. + + We place the label, LCD widgets, and the board into a QGridLayout + along with some labels that we create with the \c createLabel() convenience + function: + + \snippet examples/widgets/tetrix/tetrixwindow.cpp 6 + + Finally, we set the grid layout on the widget, give the window a title, and + resize it to an appropriate size. + + The \c createLabel() convenience function simply creates a new label on the + heap, gives it an appropriate alignment, and returns it to the caller: + + \snippet examples/widgets/tetrix/tetrixwindow.cpp 7 + + Since each label will be used in the widget's layout, it will become a child + of the \c TetrixWindow widget and, as a result, it will be deleted when the + window is deleted. + + \section1 TetrixPiece Class Definition + + The \c TetrixPiece class holds information about a piece in the game's + playing area, including its shape, position, and the range of positions it can + occupy on the board: + + \snippet examples/widgets/tetrix/tetrixpiece.h 0 + + Each shape contains four blocks, and these are defined by the \c coords private + member variable. Additionally, each piece has a high-level description that is + stored internally in the \c pieceShape variable. + + The constructor is written inline in the definition, and simply ensures that + each piece is initially created with no shape. The \c shape() function simply + returns the contents of the \c pieceShape variable, and the \c x() and \c y() + functions return the x and y-coordinates of any given block in the shape. + + \section1 TetrixPiece Class Implementation + + The \c setRandomShape() function is used to select a random shape for a piece: + + \snippet examples/widgets/tetrix/tetrixpiece.cpp 0 + + For convenience, it simply chooses a random shape from the \c TetrixShape enum + and calls the \c setShape() function to perform the task of positioning the + blocks. + + The \c setShape() function uses a look-up table of pieces to associate each + shape with an array of block positions: + + \snippet examples/widgets/tetrix/tetrixpiece.cpp 1 + \snippet examples/widgets/tetrix/tetrixpiece.cpp 2 + + These positions are read from the table into the piece's own array of positions, + and the piece's internal shape information is updated to use the new shape. + + The \c x() and \c y() functions are implemented inline in the class definition, + returning positions defined on a grid that extends horizontally and vertically + with coordinates from -2 to 2. Although the predefined coordinates for each + piece only vary horizontally from -1 to 1 and vertically from -1 to 2, each + piece can be rotated by 90, 180, and 270 degrees. + + The \c minX() and \c maxX() functions return the minimum and maximum horizontal + coordinates occupied by the blocks that make up the piece: + + \snippet examples/widgets/tetrix/tetrixpiece.cpp 3 + \snippet examples/widgets/tetrix/tetrixpiece.cpp 4 + + Similarly, the \c minY() and \c maxY() functions return the minimum and maximum + vertical coordinates occupied by the blocks: + + \snippet examples/widgets/tetrix/tetrixpiece.cpp 5 + \snippet examples/widgets/tetrix/tetrixpiece.cpp 6 + + The \c rotatedLeft() function returns a new piece with the same shape as an + existing piece, but rotated counter-clockwise by 90 degrees: + + \snippet examples/widgets/tetrix/tetrixpiece.cpp 7 + + Similarly, the \c rotatedRight() function returns a new piece with the same + shape as an existing piece, but rotated clockwise by 90 degrees: + + \snippet examples/widgets/tetrix/tetrixpiece.cpp 9 + + These last two functions enable each piece to create rotated copies of itself. + + \section1 TetrixBoard Class Definition + + The \c TetrixBoard class inherits from QFrame and contains the game logic and display features: + + \snippet examples/widgets/tetrix/tetrixboard.h 0 + + Apart from the \c setNextPieceLabel() function and the \c start() and \c pause() + public slots, we only provide public functions to reimplement QWidget::sizeHint() + and QWidget::minimumSizeHint(). The signals are used to communicate changes to + the player's information to the \c TetrixWindow instance. + + The rest of the functionality is provided by reimplementations of protected event + handlers and private functions: + + \snippet examples/widgets/tetrix/tetrixboard.h 1 + + The board is composed of a fixed-size array whose elements correspond to + spaces for individual blocks. Each element in the array contains a \c TetrixShape + value corresponding to the type of shape that occupies that element. + + Each shape on the board will occupy four elements in the array, and these will + all contain the enum value that corresponds to the type of the shape. + + We use a QBasicTimer to control the rate at which pieces fall toward the bottom + of the playing area. This allows us to provide an implementation of + \l{QObject::}{timerEvent()} that we can use to update the widget. + + \section1 TetrixBoard Class Implementation + + In the constructor, we customize the frame style of the widget, ensure that + keyboard input will be received by the widget by using Qt::StrongFocus for the + focus policy, and initialize the game state: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 0 + + The first (next) piece is also set up with a random shape. + + The \c setNextPieceLabel() function is used to pass in an externally-constructed + label to the board, so that it can be shown alongside the playing area: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 1 + + We provide a reasonable size hint and minimum size hint for the board, based on + the size of the space for each block in the playing area: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 2 + \snippet examples/widgets/tetrix/tetrixboard.cpp 3 + + By using a minimum size hint, we indicate to the layout in the parent widget + that the board should not shrink below a minimum size. + + A new game is started when the \c start() slot is called. This resets the + game's state, the player's score and level, and the contents of the board: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 4 + + We also emit signals to inform other components of these changes before creating + a new piece that is ready to be dropped into the playing area. We start the + timer that determines how often the piece drops down one row on the board. + + The \c pause() slot is used to temporarily stop the current game by stopping the + internal timer: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 5 + \snippet examples/widgets/tetrix/tetrixboard.cpp 6 + + We perform checks to ensure that the game can only be paused if it is already + running and not already paused. + + The \c paintEvent() function is straightforward to implement. We begin by + calling the base class's implementation of \l{QWidget::}{paintEvent()} before + constructing a QPainter for use on the board: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 7 + + Since the board is a subclass of QFrame, we obtain a QRect that covers the area + \e inside the frame decoration before drawing our own content. + + If the game is paused, we want to hide the existing state of the board and + show some text. We achieve this by painting text onto the widget and returning + early from the function. The rest of the painting is performed after this point. + + The position of the top of the board is found by subtracting the total height + of each space on the board from the bottom of the frame's internal rectangle. + For each space on the board that is occupied by a piece, we call the + \c drawSquare() function to draw a block at that position. + + \snippet examples/widgets/tetrix/tetrixboard.cpp 8 + \snippet examples/widgets/tetrix/tetrixboard.cpp 9 + + Spaces that are not occupied by blocks are left blank. + + Unlike the existing pieces on the board, the current piece is drawn + block-by-block at its current position: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 10 + \snippet examples/widgets/tetrix/tetrixboard.cpp 11 + \snippet examples/widgets/tetrix/tetrixboard.cpp 12 + + The \c keyPressEvent() handler is called whenever the player presses a key while + the \c TetrixBoard widget has the keyboard focus. + + \snippet examples/widgets/tetrix/tetrixboard.cpp 13 + + If there is no current game, the game is running but paused, or if there is no + current shape to control, we simply pass on the event to the base class. + + We check whether the event is about any of the keys that the player uses to + control the current piece and, if so, we call the relevant function to handle + the input: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 14 + + In the case where the player presses a key that we are not interested in, we + again pass on the event to the base class's implementation of + \l{QWidget::}{keyPressEvent()}. + + The \c timerEvent() handler is called every time the class's QBasicTimer + instance times out. We need to check that the event we receive corresponds to + our timer. If it does, we can update the board: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 15 + \snippet examples/widgets/tetrix/tetrixboard.cpp 16 + \snippet examples/widgets/tetrix/tetrixboard.cpp 17 + + If a row (or line) has just been filled, we create a new piece and reset the + timer; otherwise we move the current piece down by one row. We let the base + class handle other timer events that we receive. + + The \c clearBoard() function simply fills the board with the + \c TetrixShape::NoShape value: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 18 + + The \c dropDown() function moves the current piece down as far as possible on + the board, either until it is touching the bottom of the playing area or it is + stacked on top of another piece: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 19 + \snippet examples/widgets/tetrix/tetrixboard.cpp 20 + + The number of rows the piece has dropped is recorded and passed to the + \c pieceDropped() function so that the player's score can be updated. + + The \c oneLineDown() function is used to move the current piece down by one row + (line), either when the user presses the \gui{D} key or when the piece is + scheduled to move: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 21 + + If the piece cannot drop down by one line, we call the \c pieceDropped() function + with zero as the argument to indicate that it cannot fall any further, and that + the player should receive no extra points for the fall. + + The \c pieceDropped() function itself is responsible for awarding points to the + player for positioning the current piece, checking for full rows on the board + and, if no lines have been removed, creating a new piece to replace the current + one: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 22 + \snippet examples/widgets/tetrix/tetrixboard.cpp 23 + + We call \c removeFullLines() each time a piece has been dropped. This scans + the board from bottom to top, looking for blank spaces on each row. + + \snippet examples/widgets/tetrix/tetrixboard.cpp 24 + \snippet examples/widgets/tetrix/tetrixboard.cpp 25 + \snippet examples/widgets/tetrix/tetrixboard.cpp 26 + \snippet examples/widgets/tetrix/tetrixboard.cpp 27 + + If a row contains no blank spaces, the rows above it are copied down by one row + to compress the stack of pieces, the top row on the board is cleared, and the + number of full lines found is incremented. + + \snippet examples/widgets/tetrix/tetrixboard.cpp 28 + \snippet examples/widgets/tetrix/tetrixboard.cpp 29 + + If some lines have been removed, the player's score and the total number of lines + removed are updated. The \c linesRemoved() and \c scoreChanged() signals are + emitted to send these new values to other widgets in the window. + + Additionally, we set the timer to elapse after half a second, set the + \c isWaitingAfterLine flag to indicate that lines have been removed, unset + the piece's shape to ensure that it is not drawn, and update the widget. + The next time that the \c timerEvent() handler is called, a new piece will be + created and the game will continue. + + The \c newPiece() function places the next available piece at the top of the + board, and creates a new piece with a random shape: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 30 + \snippet examples/widgets/tetrix/tetrixboard.cpp 31 + + We place a new piece in the middle of the board at the top. The game is over if + the piece can't move, so we unset its shape to prevent it from being drawn, stop + the timer, and unset the \c isStarted flag. + + The \c showNextPiece() function updates the label that shows the next piece to + be dropped: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 32 + \snippet examples/widgets/tetrix/tetrixboard.cpp 33 + + We draw the piece's component blocks onto a pixmap that is then set on the label. + + The \c tryMove() function is used to determine whether a piece can be positioned + at the specified coordinates: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 34 + + We examine the spaces on the board that the piece needs to occupy and, if they + are already occupied by other pieces, we return \c false to indicate that the + move has failed. + + \snippet examples/widgets/tetrix/tetrixboard.cpp 35 + + If the piece could be placed on the board at the desired location, we update the + current piece and its position, update the widget, and return \c true to indicate + success. + + The \c drawSquare() function draws the blocks (normally squares) that make up + each piece using different colors for pieces with different shapes: + + \snippet examples/widgets/tetrix/tetrixboard.cpp 36 + + We obtain the color to use from a look-up table that relates each shape to an + RGB value, and use the painter provided to draw the block at the specified + coordinates. +*/ diff --git a/doc/src/examples/textfinder.qdoc b/doc/src/examples/textfinder.qdoc new file mode 100644 index 0000000..2eea15d --- /dev/null +++ b/doc/src/examples/textfinder.qdoc @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example uitools/textfinder + \title Text Finder Example + + The Text Finder example demonstrates how to dynamically process forms + using the QtUiTools module. Dynamic form processing enables a form to + be processed at run-time only by changing the .ui file for the project. + The program allows the user to look up a particular word within the + contents of a text file. This text file is included in the project's + resource and is loaded into the display at startup. + + \table + \row \o \inlineimage textfinder-example-find.png + \o \inlineimage textfinder-example-find2.png + \endtable + + \section1 Setting Up The Resource File + + The resources required for Text Finder are: + \list + \o \e{textfinder.ui} - the user interface file created in QtDesigner + \o \e{input.txt} - a text file containing some text to be displayed + in the QTextEdit + \endlist + + \e{textfinder.ui} contains all the necessary QWidget objects for the + Text Finder. A QLineEdit is used for the user input, a QTextEdit is + used to display the contents of \e{input.txt}, a QLabel is used to + display the text "Keyword", and a QPushButton is used for the "Find" + button. The screenshot below shows the preview obtained in QtDesigner. + + \image textfinder-example-userinterface.png + + A \e{textfinder.qrc} file is used to store both the \e{textfinder.ui} + and \e{input.txt} in the application's executable. The file contains + the following code: + + \quotefile examples/uitools/textfinder/textfinder.qrc + + For more information on resource files, see \l{The Qt Resource System}. + + To generate a form at run-time, the example is linked against the + QtUiTools module library. This is done in the \c{textfinder.pro} file + that contains the following lines: + + \snippet doc/src/snippets/code/doc_src_examples_textfinder.qdoc 0 + + \section1 TextFinder Class Definition + + The \c TextFinder class is a subclass of QWidget and it hosts the + \l{QWidget}s we need to access in the user interface. The QLabel in the + user interface is not declared here as we do not need to access it. + + \snippet examples/uitools/textfinder/textfinder.h 0 + + The slot \c{on_find_Button_clicked()} is a slot named according to the + \l{Using a Designer .ui File in Your Application#Automatic Connections} + {Automatic Connection} naming convention required + by \c uic. + + \section1 TextFinder Class Implementation + + The \c TextFinder class's constructor calls the \c loadUiFile() function + and then uses \c qFindChild() to access the user interface's + \l{QWidget}s. + + \snippet examples/uitools/textfinder/textfinder.cpp 0 + + We then use QMetaObject's system to enable signal and slot connections. + + \snippet examples/uitools/textfinder/textfinder.cpp 2 + + The loadTextFile() function is called to load \c{input.txt} into + QTextEdit to displays its contents. + + \snippet examples/uitools/textfinder/textfinder.cpp 3a + + The \c{TextFinder}'s layout is set with \l{QWidget::}{setLayout()}. + + \snippet examples/uitools/textfinder/textfinder.cpp 3b + + Finally, the window title is set to \e {Text Finder} and \c isFirstTime is + set to true. + + \c isFirstTime is used as a flag to indicate whether the search operation + has been performed more than once. This is further explained with the + \c{on_findButton_clicked()} function. + + The \c{loadUiFile()} function is used to load the user interface file + previously created in QtDesigner. The QUiLoader class is instantiated + and its \c load() function is used to load the form into \c{formWidget} + that acts as a place holder for the user interface. The function then + returns \c{formWidget} to its caller. + + \snippet examples/uitools/textfinder/textfinder.cpp 4 + + As mentioned earlier, the loadTextFile() function loads \e{input.txt} + into QTextEdit to display its contents. Data is read using QTextStream + into a QString object, \c line with the QTextStream::readAll() function. + The contents of \c line are then appended to \c{ui_textEdit}. + + \snippet examples/uitools/textfinder/textfinder.cpp 5 + + The \c{on_findButton_clicked()} function is a slot that is connected to + \c{ui_findButton}'s \c clicked() signal. The \c searchString is extracted + from the \c ui_lineEdit and the \c document is extracted from \c textEdit. + In event there is an empty \c searchString, a QMessageBox is used, + requesting the user to enter a word. Otherwise, we traverse through the + words in \c ui_textEdit, and highlight all ocurrences of the + \c searchString . Two QTextCursor objects are used: One to traverse through + the words in \c line and another to keep track of the edit blocks. + + \snippet examples/uitools/textfinder/textfinder.cpp 7 + + The \c isFirstTime flag is set to false the moment \c findButton is + clicked. This is necessary to undo the previous text highlight before + highlighting the user's next search string. Also, the \c found flag + is used to indicate if the \c searchString was found within the contents + of \c ui_textEdit. If it was not found, a QMessageBox is used + to inform the user. + + \snippet examples/uitools/textfinder/textfinder.cpp 9 + + \section1 \c main() Function + + \snippet examples/uitools/textfinder/main.cpp 0 + + The \c main() function initialises the \e{textfinder.qrc} resource file + and instantiates as well as displays \c TextFinder. + + \sa{Calculator Builder Example}, {World Time Clock Builder Example} + */ diff --git a/doc/src/examples/textobject.qdoc b/doc/src/examples/textobject.qdoc new file mode 100644 index 0000000..cc5a6b6 --- /dev/null +++ b/doc/src/examples/textobject.qdoc @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example richtext/textobject + \title Text Object Example + + The Text Object example shows how to insert an SVG file into a + QTextDocument. + + \image textobject-example.png + + A QTextDocument consists of a hierarchy of elements, such as text blocks and + frames. A text object describes the structure or format of one or more of these + elements. For instance, images imported from HTML are implemented using text + objects. Text objects are used by the document's + \l{QAbstractTextDocumentLayout}{layout} to lay out and render (paint) the + document. Each object knows how to paint the elements they govern, and + calculates their size. + + To be able to insert an SVG image into a text document, we create + a text object, and implement painting for that object. This object + can then be \l{QTextCharFormat::setObjectType()}{set} on a + QTextCharFormat. We also register the text object with the layout + of the document, enabling it to draw \l{QTextCharFormat}s governed + by our text object. We can summarize the procedure with the + following steps: + + \list + \o Implement the text object. + \o Register the text object with the layout of the text + document. + \o Set the text object on a QTextCharFormat. + \o Insert a QChar::ObjectReplacementCharacter with that + text char format into the document. + \endlist + + The example consists of the following classes: + + \list + \o \c{SvgTextObject} implements the text object. + \o \c{Window} shows a QTextEdit into which SVG images can be + inserted. + \endlist + + \section1 SvgTextObject Class Definition + + Let's take a look at the header file of \c {SvgTextObject}: + + \snippet examples/richtext/textobject/svgtextobject.h 0 + + A text object is a QObject that implements QTextObjectInterface. + Note that the first class inherited must be QObject, and that + you must use Q_INTERFACES to let Qt know that your class + implements QTextObjectInterface. + + The document layout keeps a collection of text objects stored as + \l{QObject}s, each of which has an associated object type. The + layout casts the QObject for the associated object type into the + QTextObjectInterface. + + The \l{QTextObjectInterface::}{intrinsicSize()} and + \l{QTextObjectInterface::}{drawObject()} functions are then used + to calculate the size of the text object and draw it. + + \section1 SvgTextObject Class Implementation + + We start of by taking a look at the + \l{QTextObjectInterface::}{intrinsicSize()} function: + + \snippet examples/richtext/textobject/svgtextobject.cpp 0 + + \c intrinsicSize() is called by the layout to calculate the size + of the text object. Notice that we have drawn the SVG image on a + QImage. This is because SVG rendering is quite expensive. The + example would lag seriously for large images if we drew them + with a QSvgRenderer each time. + + \snippet examples/richtext/textobject/svgtextobject.cpp 1 + + In \c drawObject(), we paint the SVG image using the QPainter + provided by the layout. + + \section1 Window Class Definition + + The \c Window class is a self-contained window that has a + QTextEdit in which SVG images can be inserted. + + \snippet examples/richtext/textobject/window.h 0 + + The \c insertTextObject() slot inserts an SVG image at the current + cursor position, while \c setupTextObject() creates and registers + the SvgTextObject with the layout of the text edit's document. + + The constructor simply calls \c setupTextObject() and \c + setupGui(), which creates and lays out the widgets of the \c + Window. + + \section1 Window Class Implementation + + We will now take a closer look at the functions that are relevant + to our text object, starting with the \c setupTextObject() + function. + + \snippet examples/richtext/textobject/window.cpp 3 + + \c {SvgTextFormat}'s value is the number of our object type. It is + used to identify object types by the document layout. + + Note that we only create one SvgTextObject instance; it will be + used for all QTextCharFormat's with the \c SvgTextFormat object + type. + + Let's move on to the \c insertTextObject() function: + + \snippet examples/richtext/textobject/window.cpp 1 + + First, the \c .svg file is opened and its contents are read + into the \c svgData array. + + \snippet examples/richtext/textobject/window.cpp 2 + + To speed things up, we buffer the SVG image in a QImage. We use + \l{QTextFormat::}{setProperty()} to store the QImage in the in the + QTextCharFormat. We can retrieve it later with + \l{QTextCharFormat::}{property()}. + + We insert the char format in the standard way - using a + QTextCursor. Notice that we use the special QChar + \l{QChar::}{ObjectReplacementCharacter}. +*/ + diff --git a/doc/src/examples/textures.qdoc b/doc/src/examples/textures.qdoc new file mode 100644 index 0000000..2f0389c3 --- /dev/null +++ b/doc/src/examples/textures.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example opengl/textures + \title Textures Example + + The Textures example demonstrates the use of Qt's image classes as textures in + applications that use both OpenGL and Qt to display graphics. + + \image textures-example.png +*/ diff --git a/doc/src/examples/threadedfortuneserver.qdoc b/doc/src/examples/threadedfortuneserver.qdoc new file mode 100644 index 0000000..d5f2571 --- /dev/null +++ b/doc/src/examples/threadedfortuneserver.qdoc @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example network/threadedfortuneserver + \title Threaded Fortune Server Example + + The Threaded Fortune Server example shows how to create a server for a + simple network service that uses threads to handle requests from different + clients. It is intended to be run alongside the Fortune Client example. + + \image threadedfortuneserver-example.png + + The implementation of this example is similar to that of the + \l{network/fortuneserver}{Fortune Server} example, but here we will + implement a subclass of QTcpServer that starts each connection in a + different thread. + + For this we need two classes: FortuneServer, a QTcpServer subclass, and + FortuneThread, which inherits QThread. + + \snippet examples/network/threadedfortuneserver/fortuneserver.h 0 + + FortuneServer inherits QTcpServer and reimplements + QTcpServer::incomingConnection(). We also use it for storing the list of + random fortunes. + + \snippet examples/network/threadedfortuneserver/fortuneserver.cpp 0 + + We use FortuneServer's constructor to simply generate the list of + fortunes. + + \snippet examples/network/threadedfortuneserver/fortuneserver.cpp 1 + + Our implementation of QTcpServer::incomingConnection() creates a + FortuneThread object, passing the incoming socket descriptor and a random + fortune to FortuneThread's constructor. By connecting FortuneThread's + finished() signal to QObject::deleteLater(), we ensure that the thread + gets deleted once it has finished. We can then call QThread::start(), + which starts the thread. + + \snippet examples/network/threadedfortuneserver/fortunethread.h 0 + + Moving on to the FortuneThread class, this is a QThread subclass whose job + is to write the fortune to the connected socket. The class reimplements + QThread::run(), and it has a signal for reporting errors. + + \snippet examples/network/threadedfortuneserver/fortunethread.cpp 0 + + FortuneThread's constructor simply stores the socket descriptor and + fortune text, so that they are available for run() later on. + + \snippet examples/network/threadedfortuneserver/fortunethread.cpp 1 + + The first thing our run() function does is to create a QTcpSocket object + on the stack. What's worth noticing is that we are creating this object + inside the thread, which automatically associates the socket to the + thread's event loop. This ensures that Qt will not try to deliver events + to our socket from the main thread while we are accessing it from + FortuneThread::run(). + + \snippet examples/network/threadedfortuneserver/fortunethread.cpp 2 + + The socket is initialized by calling QTcpSocket::setSocketDescriptor(), + passing our socket descriptor as an argument. We expect this to succeed, + but just to be sure, (although unlikely, the system may run out of + resources,) we catch the return value and report any error. + + \snippet examples/network/threadedfortuneserver/fortunethread.cpp 3 + + As with the \l{network/fortuneserver}{Fortune Server} example, we encode + the fortune into a QByteArray using QDataStream. + + \snippet examples/network/threadedfortuneserver/fortunethread.cpp 4 + + But unlike the previous example, we finish off by calling + QTcpSocket::waitForDisconnected(), which blocks the calling thread until + the socket has disconnected. Because we are running in a separate thread, + the GUI will remain responsive. + + \sa {Fortune Server Example}, {Fortune Client Example}, {Blocking Fortune + Client Example} +*/ diff --git a/doc/src/examples/tooltips.qdoc b/doc/src/examples/tooltips.qdoc new file mode 100644 index 0000000..5daa2b2 --- /dev/null +++ b/doc/src/examples/tooltips.qdoc @@ -0,0 +1,408 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/tooltips + \title Tool Tips Example + + The Tool Tips example shows how to provide static and dynamic tool + tips for an application's widgets. + + The simplest and most common way to set a widget's tool tip is by + calling its QWidget::setToolTip() function (static tool + tips). Then the tool tip is shown whenever the cursor points at + the widget. We show how to do this with our application's tool + buttons. But it is also possible to show different tool tips + depending on the cursor's position (dynamic tooltips). This + approach uses mouse tracking and event handling to determine what + widgets are located under the cursor at any point in time, and + displays their tool tips. The tool tips for the shape items in our + application are implemented using the latter approach. + + \image tooltips-example.png + + With the \c Tooltips application the user can create new shape + items with the provided tool buttons, and move the items around + using the mouse. Tooltips are provided whenever the cursor is + pointing to a shape item or one of the buttons. + + The Tooltips example consists of two classes: + + \list + \o \c ShapeItem is a custom widget representing one single shape item. + \o \c SortingBox inherits from QWidget and is the application's main + widget. + \endlist + + First we will review the \c SortingBox class, then we will take a + look at the \c ShapeItem class. + + \section1 SortingBox Class Definition + + \snippet examples/widgets/tooltips/sortingbox.h 0 + + The \c SortingBox class inherits QWidget, and it is the Tooltips + application's main widget. We reimplement several of the event + handlers. + + The \c event() function provides tooltips, the \c resize() + function makes sure the application appears consistently when the + user resizes the main widget, and the \c paintEvent() function + displays the shape items within the \c SortingBox widget. The + mouse event handlers are reimplemented to make the user able to + move the items around. + + In addition we need three private slots to make the user able to + create new shape items. + + \snippet examples/widgets/tooltips/sortingbox.h 1 + + We also create several private functions: We use the \c + initialItemPosition(), \c initialItemColor() and \c + createToolButton() functions when we are constructing the widget, + and we use the \c updateButtonGeometry() function whenever the + user is resizing the application's main widget. + + The \c itemAt() function determines if there is a shape item at a + particular position, and the \c moveItemTo() function moves an + item to a new position. We use the \c createShapeItem(), \c + randomItemPosition() and \c randomItemColor() functions to create + new shape items. + + \snippet examples/widgets/tooltips/sortingbox.h 2 + + We keep all the shape items in a QList, and we keep three + QPainterPath objects holding the shapes of a circle, a square and + a triangle. We also need to have a pointer to an item when it is + moving, and we need to know its previous position. + + \section1 SortingBox Class Implementation + + \snippet examples/widgets/tooltips/sortingbox.cpp 0 + + In the constructor, we first set the Qt::WA_StaticContents + attribute on the widget. This attribute indicates that the widget + contents are north-west aligned and static. On resize, such a + widget will receive paint events only for the newly visible part + of itself. + + \snippet examples/widgets/tooltips/sortingbox.cpp 1 + + To be able to show the appropiate tooltips while the user is + moving the cursor around, we need to enable mouse tracking for the + widget. + + If mouse tracking is disabled (the default), the widget only + receives mouse move events when at least one mouse button is + pressed while the mouse is being moved. If mouse tracking is + enabled, the widget receives mouse move events even if no buttons + are pressed. + + \snippet examples/widgets/tooltips/sortingbox.cpp 2 + + A widget's background role defines the brush from the widget's + palette that is used to render the background, and QPalette::Base + is typically white. + + \snippet examples/widgets/tooltips/sortingbox.cpp 3 + + After creating the application's tool buttons using the private \c + createToolButton() function, we construct the shapes of a circle, + a square and a triangle using QPainterPath. + + The QPainterPath class provides a container for painting + operations, enabling graphical shapes to be constructed and + reused. The main advantage of painter paths over normal drawing + operations is that complex shapes only need to be created once, + but they can be drawn many times using only calls to + QPainter::drawPath(). + + \snippet examples/widgets/tooltips/sortingbox.cpp 4 + + Then we set the window title, resize the widget to a suitable + size, and finally create three initial shape items using the + private \c createShapeItem(), \c initialItemPosition() and \c + initialItemColor() functions. + + \snippet examples/widgets/tooltips/sortingbox.cpp 5 + + QWidget::event() is the main event handler and receives all the + widget's events. Normally, we recommend reimplementing one of the + specialized event handlers instead of this function. But here we + want to catch the QEvent::ToolTip events, and since these are + rather rare, there exists no specific event handler. For that + reason we reimplement the main event handler, and the first thing + we need to do is to determine the event's type: + + \snippet examples/widgets/tooltips/sortingbox.cpp 6 + + If the type is QEvent::ToolTip, we cast the event to a QHelpEvent, + otherwise we propagate the event using the QWidget::event() + function. + + The QHelpEvent class provides an event that is used to request + helpful information about a particular point in a widget. + + For example, the QHelpEvent::pos() function returns the event's + position relative to the widget to which the event is dispatched. + Here we use this information to determine if the position of the + event is contained within the area of any of the shape items. If + it is, we display the shape item's tooltip at the position of the + event. If not, we hide the tooltip and explicitly ignore the event. + This makes sure that the calling code does not start any tooltip + specific modes as a result of the event. Note that the + QToolTip::showText() function needs the event's position in global + coordinates provided by QHelpEvent::globalPos(). + + \snippet examples/widgets/tooltips/sortingbox.cpp 7 + + The \c resizeEvent() function is reimplemented to receive the + resize events dispatched to the widget. It makes sure that the + tool buttons keep their position relative to the main widget when + the widget is resized. We want the buttons to always be vertically + aligned in the application's bottom right corner, so each time the + main widget is resized we update the buttons geometry. + + \snippet examples/widgets/tooltips/sortingbox.cpp 8 + + The \c paintEvent() function is reimplemented to receive paint + events for the widget. We create a QPainter for the \c SortingBox + widget, and run through the list of created shape items, drawing + each item at its defined position. + + \snippet examples/widgets/tooltips/sortingbox.cpp 9 + + The painter will by default draw all the shape items at position + (0,0) in the \c SortingBox widget. The QPainter::translate() + function translates the coordinate system by the given offset, + making each shape item appear at its defined position. But + remember to translate the coordinate system back when the item is + drawn, otherwise the next shape item will appear at a position + relative to the item we drawed last. + + \snippet examples/widgets/tooltips/sortingbox.cpp 10 + + The QPainter::setBrush() function sets the current brush used by + the painter. When the provided argument is a QColor, the function + calls the appropiate QBrush constructor which creates a brush with + the specified color and Qt::SolidPattern style. The + QPainter::drawPath() function draws the given path using the + current pen for outline and the current brush for filling. + + \snippet examples/widgets/tooltips/sortingbox.cpp 11 + + The \c mousePressEvent() function is reimplemented to receive the + mouse press events dispatched to the widget. It determines if an + event's position is contained within the area of any of the shape + items, using the private \c itemAt() function. + + If an item covers the position, we store a pointer to that item + and the event's position. If several of the shape items cover the + position, we store the pointer to the uppermost item. Finally, we + move the shape item to the end of the list, and make a call to the + QWidget::update() function to make the item appear on top. + + The QWidget::update() function does not cause an immediate + repaint; instead it schedules a paint event for processing when Qt + returns to the main event loop. + + \snippet examples/widgets/tooltips/sortingbox.cpp 12 + + The \c mouseMoveEvent() function is reimplemented to receive mouse + move events for the widget. If the left mouse button is pressed + and there exists a shape item in motion, we use the private \c + moveItemTo() function to move the item with an offset + corresponding to the offset between the positions of the current + mouse event and the previous one. + + \snippet examples/widgets/tooltips/sortingbox.cpp 13 + + The \c mouseReleaseEvent() function is reimplemented to receive + the mouse release events dispatched to the widget. If the left + mouse button is pressed and there exists a shape item in motion, + we use the private \c moveItemTo() function to move the item like + we did in \c mouseMoveEvent(). But then we remove the pointer to + the item in motion, making the shape item's position final for + now. To move the item further, the user will need to press the + left mouse button again. + + \snippet examples/widgets/tooltips/sortingbox.cpp 14 + \codeline + \snippet examples/widgets/tooltips/sortingbox.cpp 15 + \codeline + \snippet examples/widgets/tooltips/sortingbox.cpp 16 + + The \c createNewCircle(), \c createNewSquare() and \c + createNewTriangle() slots simply create new shape items, using the + private \c createShapeItem(), \c randomItemPosition() and \c + randomItemColor() functions. + + \snippet examples/widgets/tooltips/sortingbox.cpp 17 + + In the \c itemAt() function, we run through the list of created + shape items to check if the given position is contained within the + area of any of the shape items. + + For each shape item we use the QPainterPath::contains() function + to find out if the item's painter path contains the position. If + it does we return the index of the item, otherwise we return + -1. We run through the list backwards to get the index of the + uppermost shape item in case several items cover the position. + + \snippet examples/widgets/tooltips/sortingbox.cpp 18 + + The \c moveItemTo() function moves the shape item in motion, and + the parameter \c pos is the position of a mouse event. First we + calculate the offset between the parameter \c pos and the previous + mouse event position. Then we add the offset to the current + position of the item in motion. + + It is tempting to simply set the position of the item to be the + parameter \c pos. But an item's position defines the top left + corner of the item's bounding rectangle, and the parameter \c pos + can be any point; The suggested shortcut would cause the item to + jump to a position where the cursor is pointing to the bounding + rectangle's top left corner, regardless of the item's previous + position. + + \snippet examples/widgets/tooltips/sortingbox.cpp 19 + + Finally, we update the previous mouse event position, and make a + call to the QWidget::update() function to make the item appear at + its new position. + + \snippet examples/widgets/tooltips/sortingbox.cpp 20 + + In the \c updateButtonGeometry() function we set the geometry for + the given button. The parameter coordinates define the bottom + right corner of the button. We use these coordinates and the + button's size hint to determine the position of the upper left + corner. This position, and the button's width and height, are the + arguments required by the QWidget::setGeometry() function. + + In the end, we calculate and return the y-coordinate of the bottom + right corner of the next button. We use the QWidget::style() + function to retrieve the widget's GUI style, and then + QStyle::pixelMetric() to determine the widget's preferred default + spacing between its child widgets. + + \snippet examples/widgets/tooltips/sortingbox.cpp 21 + + The \c createShapeItem() function creates a single shape item. It + sets the path, tooltip, position and color, using the item's own + functions. In the end, the function appends the new item to the + list of shape items, and calls the QWidget::update() function to + make it appear with the other items within the \c SortingBox + widget. + + \snippet examples/widgets/tooltips/sortingbox.cpp 22 + + The \c createToolButton() function is called from the \c + SortingBox constructor. We create a tool button with the given + tooltip and icon. The button's parent is the \c SortingBox widget, + and its size is 32 x 32 pixels. Before we return the button, we + connect it to the given slot. + + \snippet examples/widgets/tooltips/sortingbox.cpp 23 + + The \c initialItemPosition() function is also called from the + constructor. We want the three first items to initially be + centered in the middle of the \c SortingBox widget, and we use + this function to calculate their positions. + + \snippet examples/widgets/tooltips/sortingbox.cpp 24 + + Whenever the user creates a new shape item, we want the new item + to appear at a random position, and we use the \c + randomItemPosition() function to calculate such a position. We + make sure that the item appears within the the visible area of the + \c SortingBox widget, using the widget's current width and heigth + when calculating the random coordinates. + + \snippet examples/widgets/tooltips/sortingbox.cpp 25 + + As with \c initialItemPosition(), the \c initialItemColor() + function is called from the constructor. The purposes of both + functions are purely cosmetic: We want to control the inital + position and color of the three first items. + + \snippet examples/widgets/tooltips/sortingbox.cpp 26 + + Finally the \c randomItemColor() function is implemented to give + the shape items the user creates, a random color. + + \section1 ShapeItem Class Definition + + \snippet examples/widgets/tooltips/shapeitem.h 0 + + The \c ShapeItem class is a custom widget representing one single + shape item. The widget has a path, a position, a color and a + tooltip. We need functions to set or modify these objects, as well + as functions that return them. We make the latter functions \c + const to prohibit any modifications of the objects, + i.e. prohibiting unauthorized manipulation of the shape items + appearance. + + \section1 ShapeItem Class Implementation + + \snippet examples/widgets/tooltips/shapeitem.cpp 0 + \codeline + \snippet examples/widgets/tooltips/shapeitem.cpp 1 + \codeline + \snippet examples/widgets/tooltips/shapeitem.cpp 2 + \codeline + \snippet examples/widgets/tooltips/shapeitem.cpp 3 + + This first group of functions simply return the objects that are + requested. The objects are returned as constants, i.e. they cannot + be modified. + + \snippet examples/widgets/tooltips/shapeitem.cpp 4 + \codeline + \snippet examples/widgets/tooltips/shapeitem.cpp 5 + \codeline + \snippet examples/widgets/tooltips/shapeitem.cpp 6 + \codeline + \snippet examples/widgets/tooltips/shapeitem.cpp 7 + + The last group of functions set or modify the shape item's path, + position, color and tooltip, respectively. +*/ diff --git a/doc/src/examples/torrent.qdoc b/doc/src/examples/torrent.qdoc new file mode 100644 index 0000000..8805dad --- /dev/null +++ b/doc/src/examples/torrent.qdoc @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example network/torrent + \title Torrent Example + + The Torrent example is a functional BitTorrent client that + illustrates how to write a complex TCP/IP application using Qt. + + \image torrent-example.png + + \section1 License Information + + The implementation of the US Secure Hash Algorithm 1 (SHA1) in this example is + derived from the original description in \l{RFC 3174}. + + \legalese + Copyright (C) The Internet Society (2001). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + \endlegalese +*/ diff --git a/doc/src/examples/trafficinfo.qdoc b/doc/src/examples/trafficinfo.qdoc new file mode 100644 index 0000000..c9b6890 --- /dev/null +++ b/doc/src/examples/trafficinfo.qdoc @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/trafficinfo + \title TrafficInfo Example + + Shows how XQuery can be used extract information from WML documents provided by a WAP service. + + \section1 Overview + + The WAP service used in this example is \l{Trafikanten}{wap.trafikanten.no} + that is run by the Norwegian governmental agency for public transport in + Oslo. The service provides real time information about the departure of + busses, trams and undergrounds for every station in the city area. + + This example application displays the departure information for a specific + station and provides the feature to filter for a special bus or tram line. + + \image trafficinfo-example.png + + \section1 Retrieving the Data + + Without the knowledge of XQuery, one would use QNetworkAccessManager to + query the WML document from the WAP service and then using the QDom + classes or QXmlStreamReader classes to iterate over the document and + extract the needed information. + However this approach results in a lot of glue code and consumes valuable + developer time, so we are looking for something that can access XML + documents locally or over the network and extract data according to given + filter rules. That's the point where XQuery enters the stage! + + If we want to know when the underground number 6 in direction + \Aring\c{}sjordet is passing the underground station in Nydalen on November + 14th 2008 after 1pm, we use the following URL: + + \c{http://wap.trafikanten.no/F.asp?f=03012130&t=13&m=00&d=14.11.2008&start=1} + + The parameters have the following meanings: + \list + \o \e{f} The unique station ID of Nydalen. + \o \e{t} The hour in 0-23 format. + \o \e{m} The minute in 0-59 format. + \o \e{d} The date in dd.mm.yyyy format. + \o \e{start} Not interesting for our use but should be passed. + \endlist + + As a result we get the following document: + + \quotefile examples/xmlpatterns/trafficinfo/time_example.wml + + So for every departure we have a \c <a> tag that contains the time as a + text element, and the following text element contains the line number + and direction. + + To encapsulate the XQuery code in the example application, we create a + custom \c TimeQuery class. This provides the \c queryInternal() function + that takes a station ID and date/time as input and returns the list of + times and directions: + + \snippet examples/xmlpatterns/trafficinfo/timequery.cpp 1 + + The first lines of this function synthesize the XQuery strings that fetch + the document and extract the data. + For better readability, two separated queries are used here: the first one + fetches the times and the second fetches the line numbers and directions. + + The \c doc() XQuery method opens a local or remote XML document and returns + it, so the \c{/wml/card/p/small/} statement behind it selects all XML nodes + that can be reached by the path, \c wml \rarrow \c card \rarrow \c p \rarrow + \c small. + Now we are on the node that contains all the XML nodes we are interested in. + + In the first query we select all \c a nodes that have a \c href attribute + starting with the string "Rute" and return the text of these nodes. + + In the second query we select all text nodes that are children of the + \c small node which start with a number. + These two queries are passed to the QXmlQuery instance and are evaluated + to string lists. After some sanity checking, we have collected all the + information we need. + + In the section above we have seen that an unique station ID must be passed + as an argument to the URL for retrieving the time, so how to find out which + is the right station ID to use? The WAP service provides a page for that + as well, so the URL + + \c{http://wap.trafikanten.no/FromLink1.asp?fra=Nydalen} + + will return the following document: + + \snippet examples/xmlpatterns/trafficinfo/station_example.wml 0 + + The names of the available stations are listed as separate text elements + and the station ID is part of the \c href attribute of the parent \c a + (anchor) element. In our example, the \c StationQuery class encapsulates + the action of querying the stations that match the given name pattern with + the following code: + + \snippet examples/xmlpatterns/trafficinfo/stationquery.cpp 0 + + Just as in the \c TimeQuery implementation, the first step is to + synthesize the XQuery strings for selecting the station names and the + station IDs. As the station name that we pass in the URL will be input + from the user, we should protect the XQuery from code injection by using + the QXmlQuery::bindVariable() method to do proper quoting of the variable + content for us instead of concatenating the two strings manually. + + So, we define a XQuery \c $station variable that is bound to the user + input. This variable is concatenated inside the XQuery code with the + \c concat method. To extract the station IDs, we select all \c a elements + that have an \c title attribute with the content "Velg", and from these + elements we take the substring of the \c href attribute that starts at the + 18th character. + + The station name can be extracted a bit more easily by just taking the + text elements of the selected \a elements. + + After some sanity checks we have all the station IDs and the corresponding + names available. + + The rest of the code in this example is just for representing the time and + station information to the user, and uses techniques described in the + \l{Qt Examples#Widgets}{Widgets examples}. +*/ diff --git a/doc/src/examples/transformations.qdoc b/doc/src/examples/transformations.qdoc new file mode 100644 index 0000000..eabb803 --- /dev/null +++ b/doc/src/examples/transformations.qdoc @@ -0,0 +1,385 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example painting/transformations + \title Transformations Example + + The Transformations example shows how transformations influence + the way that QPainter renders graphics primitives. In particular + it shows how the order of transformations affect the result. + + \image transformations-example.png + + The application allows the user to manipulate the rendering of a + shape by changing the translation, rotation and scale of + QPainter's coordinate system. + + The example consists of two classes and a global enum: + + \list + \o The \c RenderArea class controls the rendering of a given shape. + \o The \c Window class is the application's main window. + \o The \c Operation enum describes the various transformation + operations available in the application. + \endlist + + First we will take a quick look at the \c Operation enum, then we + will review the \c RenderArea class to see how a shape is + rendered. Finally, we will take a look at the Transformations + application's features implemented in the \c Window class. + + \section1 Transformation Operations + + Normally, the QPainter operates on the associated device's own + coordinate system, but it also has good support for coordinate + transformations. + + The default coordinate system of a paint device has its origin at + the top-left corner. The x values increase to the right and the y + values increase downwards. You can scale the coordinate system by + a given offset using the QPainter::scale() function, you can + rotate it clockwise using the QPainter::rotate() function and you + can translate it (i.e. adding a given offset to the points) using + the QPainter::translate() function. You can also twist the + coordinate system around the origin (called shearing) using the + QPainter::shear() function. + + All the tranformation operations operate on QPainter's + tranformation matrix that you can retrieve using the + QPainter::matrix() function. A matrix transforms a point in the + plane to another point. For more information about the + transformation matrix, see the \l {The Coordinate System} and + QMatrix documentation. + + \snippet examples/painting/transformations/renderarea.h 0 + + The global \c Operation enum is declared in the \c renderarea.h + file and describes the various transformation operations available + in the Transformations application. + + \section1 RenderArea Class Definition + + The \c RenderArea class inherits QWidget, and controls the + rendering of a given shape. + + \snippet examples/painting/transformations/renderarea.h 1 + + We declare two public functions, \c setOperations() and + \c setShape(), to be able to specify the \c RenderArea widget's shape + and to transform the coordinate system the shape is rendered + within. + + We reimplement the QWidget's \l + {QWidget::minimumSizeHint()}{minimumSizeHint()} and \l + {QWidget::sizeHint()}{sizeHint()} functions to give the \c + RenderArea widget a reasonable size within our application, and we + reimplement the QWidget::paintEvent() event handler to draw the + render area's shape applying the user's transformation choices. + + \snippet examples/painting/transformations/renderarea.h 2 + + We also declare several convenience functions to draw the shape, + the coordinate system's outline and the coordinates, and to + transform the painter according to the chosen transformations. + + In addition, the \c RenderArea widget keeps a list of the + currently applied transformation operations, a reference to its + shape, and a couple of convenience variables that we will use when + rendering the coordinates. + + \section1 RenderArea Class Implementation + + The \c RenderArea widget controls the rendering of a given shape, + including the transformations of the coordinate system, by + reimplementing the QWidget::paintEvent() event handler. But first + we will take a quick look at the constructor and at the functions + that provides access to the \c RenderArea widget: + + \snippet examples/painting/transformations/renderarea.cpp 0 + + In the constructor we pass the parent parameter on to the base + class, and customize the font that we will use to render the + coordinates. The QWidget::font() funtion returns the font + currently set for the widget. As long as no special font has been + set, or after QWidget::setFont() is called, this is either a + special font for the widget class, the parent's font or (if this + widget is a top level widget) the default application font. + + After ensuring that the font's size is 12 points, we extract the + rectangles enclosing the coordinate letters, 'x' and 'y', using the + QFontMetrics class. + + QFontMetrics provides functions to access the individual metrics + of the font, its characters, and for strings rendered in the + font. The QFontMetrics::boundingRect() function returns the + bounding rectangle of the given character relative to the + left-most point on the base line. + + \snippet examples/painting/transformations/renderarea.cpp 1 + \codeline + \snippet examples/painting/transformations/renderarea.cpp 2 + + In the \c setShape() and \c setOperations() functions we update + the \c RenderArea widget by storing the new value or values + followed by a call to the QWidget::update() slot which schedules a + paint event for processing when Qt returns to the main event loop. + + \snippet examples/painting/transformations/renderarea.cpp 3 + \codeline + \snippet examples/painting/transformations/renderarea.cpp 4 + + We reimplement the QWidget's \l + {QWidget::minimumSizeHint()}{minimumSizeHint()} and \l + {QWidget::sizeHint()}{sizeHint()} functions to give the \c + RenderArea widget a reasonable size within our application. The + default implementations of these functions returns an invalid size + if there is no layout for this widget, and returns the layout's + minimum size or preferred size, respectively, otherwise. + + \snippet examples/painting/transformations/renderarea.cpp 5 + + The \c paintEvent() event handler recieves the \c RenderArea + widget's paint events. A paint event is a request to repaint all + or part of the widget. It can happen as a result of + QWidget::repaint() or QWidget::update(), or because the widget was + obscured and has now been uncovered, or for many other reasons. + + First we create a QPainter for the \c RenderArea widget. The \l + {QPainter::RenderHint}{QPainter::Antialiasing} render hint + indicates that the engine should antialias edges of primitives if + possible. Then we erase the area that needs to be repainted using + the QPainter::fillRect() function. + + We also translate the coordinate system with an constant offset to + ensure that the original shape is renderend with a suitable + margin. + + \snippet examples/painting/transformations/renderarea.cpp 6 + + Before we start to render the shape, we call the QPainter::save() + function. + + QPainter::save() saves the current painter state (i.e. pushes the + state onto a stack) including the current coordinate system. The + rationale for saving the painter state is that the following call + to the \c transformPainter() function will transform the + coordinate system depending on the currently chosen transformation + operations, and we need a way to get back to the original state to + draw the outline. + + After transforming the coordinate system, we draw the \c + RenderArea's shape, and then we restore the painter state using + the the QPainter::restore() function (i.e. popping the saved state off + the stack). + + \snippet examples/painting/transformations/renderarea.cpp 7 + + Then we draw the square outline. + + \snippet examples/painting/transformations/renderarea.cpp 8 + + Since we want the coordinates to correspond with the coordinate + system the shape is rendered within, we must make another call to + the \c transformPainter() function. + + The order of the painting operations is essential with respect to + the shared pixels. The reason why we don't render the coordinates + when the coordinate system already is transformed to render the + shape, but instead defer their rendering to the end, is that we + want the coordinates to appear on top of the shape and its + outline. + + There is no need to save the QPainter state this time since + drawing the coordinates is the last painting operation. + + \snippet examples/painting/transformations/renderarea.cpp 9 + \codeline + \snippet examples/painting/transformations/renderarea.cpp 10 + \codeline + \snippet examples/painting/transformations/renderarea.cpp 11 + + The \c drawCoordinates(), \c drawOutline() and \c drawShape() are + convenience functions called from the \c paintEvent() event + handler. For more information about QPainter's basic drawing + operations and how to display basic graphics primitives, see the + \l {painting/basicdrawing}{Basic Drawing} example. + + \snippet examples/painting/transformations/renderarea.cpp 12 + + The \c transformPainter() convenience function is also called from + the \c paintEvent() event handler, and transforms the given + QPainter's coordinate system according to the user's + transformation choices. + + \section1 Window Class Definition + + The \c Window class is the Transformations application's main + window. + + The application displays four \c RenderArea widgets. The left-most + widget renders the shape in QPainter's default coordinate system, + the others render the shape with the chosen transformation in + addition to all the transformations applied to the \c RenderArea + widgets to their left. + + \snippet examples/painting/transformations/window.h 0 + + We declare two public slots to make the application able to + respond to user interaction, updating the displayed \c RenderArea + widgets according to the user's transformation choices. + + The \c operationChanged() slot updates each of the \c RenderArea + widgets applying the currently chosen transformation operations, and + is called whenever the user changes the selected operations. The + \c shapeSelected() slot updates the \c RenderArea widgets' shapes + whenever the user changes the preferred shape. + + \snippet examples/painting/transformations/window.h 1 + + We also declare a private convenience function, \c setupShapes(), + that is used when constructing the \c Window widget, and we + declare pointers to the various components of the widget. We + choose to keep the available shapes in a QList of \l + {QPainterPath}s. In addition we declare a private enum counting + the number of displayed \c RenderArea widgets except the widget + that renders the shape in QPainter's default coordinate system. + + \section1 Window Class Implementation + + In the constructor we create and initialize the application's + components: + + \snippet examples/painting/transformations/window.cpp 0 + + First we create the \c RenderArea widget that will render the + shape in the default coordinate system. We also create the + associated QComboBox that allows the user to choose among four + different shapes: A clock, a house, a text and a truck. The shapes + themselves are created at the end of the constructor, using the + \c setupShapes() convenience function. + + \snippet examples/painting/transformations/window.cpp 1 + + Then we create the \c RenderArea widgets that will render their + shapes with coordinate tranformations. By default the applied + operation is \gui {No Transformation}, i.e. the shapes are + rendered within the default coordinate system. We create and + initialize the associated \l {QComboBox}es with items + corresponding to the various transformation operations decribed by + the global \c Operation enum. + + We also connect the \l {QComboBox}es' \l + {QComboBox::activated()}{activated()} signal to the \c + operationChanged() slot to update the application whenever the + user changes the selected transformation operations. + + \snippet examples/painting/transformations/window.cpp 2 + + Finally, we set the layout for the application window using the + QWidget::setLayout() function, construct the available shapes + using the private \c setupShapes() convenience function, and make + the application show the clock shape on startup using the public + \c shapeSelected() slot before we set the window title. + + + \snippet examples/painting/transformations/window.cpp 3 + \snippet examples/painting/transformations/window.cpp 4 + \snippet examples/painting/transformations/window.cpp 5 + \snippet examples/painting/transformations/window.cpp 6 + \dots + + \snippet examples/painting/transformations/window.cpp 7 + + The \c setupShapes() function is called from the constructor and + create the QPainterPath objects representing the shapes that are + used in the application. For construction details, see the \l + {painting/transformations/window.cpp}{window.cpp} example + file. The shapes are stored in a QList. The QList::append() + function inserts the given shape at the end of the list. + + We also connect the associated QComboBox's \l + {QComboBox::activated()}{activated()} signal to the \c + shapeSelected() slot to update the application when the user + changes the preferred shape. + + \snippet examples/painting/transformations/window.cpp 8 + + The public \c operationChanged() slot is called whenever the user + changes the selected operations. + + We retrieve the chosen transformation operation for each of the + transformed \c RenderArea widgets by querying the associated \l + {QComboBox}{QComboBoxes}. The transformed \c RenderArea widgets + are supposed to render the shape with the transformation specified + by its associated combobox \e {in addition to} all the + transformations applied to the \c RenderArea widgets to its + left. For that reason, for each widget we query, we append the + associated operation to a QList of transformations which we apply + to the widget before proceeding to the next. + + \snippet examples/painting/transformations/window.cpp 9 + + The \c shapeSelected() slot is called whenever the user changes + the preferred shape, updating the \c RenderArea widgets using + their public \c setShape() function. + + \section1 Summary + + The Transformations example shows how transformations influence + the way that QPainter renders graphics primitives. Normally, the + QPainter operates on the device's own coordinate system, but it + also has good support for coordinate transformations. With the + Transformations application you can scale, rotate and translate + QPainter's coordinate system. The order in which these + tranformations are applied is essential for the result. + + All the tranformation operations operate on QPainter's + tranformation matrix. For more information about the + transformation matrix, see the \l {The Coordinate System} and + QMatrix documentation. + + The Qt reference documentation provides several painting + demos. Among these is the \l {demos/affine}{Affine + Transformations} demo that shows Qt's ability to perform + transformations on painting operations. The demo also allows the + user to experiment with the various transformation operations. +*/ diff --git a/doc/src/examples/treemodelcompleter.qdoc b/doc/src/examples/treemodelcompleter.qdoc new file mode 100644 index 0000000..82e9c24 --- /dev/null +++ b/doc/src/examples/treemodelcompleter.qdoc @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/treemodelcompleter + \title Tree Model Completer Example + + The Tree Model Completer example shows how to provide completion + facilities for a hierarchical model, using a period as the separator + to access Child, GrandChild and GrandGrandChild level objects. + + \image treemodelcompleter-example.png + + Similar to the \l{Completer Example}, we provide QComboBox objects to + enable selection for completion mode and case sensitivity, as well as + a QCheckBox for wrap completions. + + \section1 The Resource File + + The contents of the TreeModelCompleter is read from \e treemodel.txt. + This file is embedded within the \e treemodelcompleter.qrc resource file, + which contains the following: + + \quotefile examples/tools/treemodelcompleter/treemodelcompleter.qrc + + \section1 TreeModelCompleter Class Definition + + The \c TreeModelCompleter is a subclass of QCompleter with two + constructors - one with \a parent as an argument and another with + \a parent and \a model as arguments. + + \snippet examples/tools/treemodelcompleter/treemodelcompleter.h 0 + + The class reimplements the protected functions + \l{QCompleter::splitPath()}{splitPath()} and + \l{QCompleter::pathFromIndex()}{pathFromIndex()} to suit a tree model. + For more information on customizing QCompleter to suit tree models, refer + to \l{QCompleter#Handling Tree Models}{Handling Tree Models}. + + \c TreeModelCompleter also has a separator property which is declared + using the Q_PROPERTY() macro. The separator has READ and WRITE attributes + and the corresponding functions \c separator() and \c setSeparator(). For + more information on Q_PROPERTY(), refer to \l{Qt's Property System}. + + \section1 TreeModelCompleter Class Implementation + + The first constructor constructs a \c TreeModelCompleter object with a + parent while the second constructor constructs an object with a parent + and a QAbstractItemModel, \a model. + + \snippet examples/tools/treemodelcompleter/treemodelcompleter.cpp 0 + \codeline + \snippet examples/tools/treemodelcompleter/treemodelcompleter.cpp 1 + + The \c separator() function is a getter function that returns the + separator string. + + \snippet examples/tools/treemodelcompleter/treemodelcompleter.cpp 2 + + As mentioned earlier, the \c splitPath() function is reimplemented because + the default implementation is more suited to QDirModel or list models. In + order for QCompleter to split the path into a list of strings that are + matched at each level, we split it using QString::split() with \c sep as its + separator. + + \snippet examples/tools/treemodelcompleter/treemodelcompleter.cpp 3 + + The \c pathFromIndex() function returns data for the completionRole() for a + tree model. This function is reimplemented as its default implementation is + more suitable for list models. If there is no separator, we use + \l{QCompleter}'s default implementation, otherwise we use the + \l{QStringList::prepend()}{prepend()} function to navigate upwards and + accumulate the data. The function then returns a QStringList, \c dataList, + using a separator to join objects of different levels. + + \snippet examples/tools/treemodelcompleter/treemodelcompleter.cpp 4 + + \section1 MainWindow Class Definition + + The \c MainWindow class is a subclass of QMainWindow and implements five + custom slots: \c about(), \c changeCase(), \c changeMode(), + \c highlight(), and \c updateContentsLabel(). + + \snippet examples/tools/treemodelcompleter/mainwindow.h 0 + + In addition, the class has two private functions, \c createMenu() and + \c modelFromFile(), as well as private instances of QTreeView, QComboBox, + QLabel, \c TreeModelCompleter and QLineEdit. + + \snippet examples/tools/treemodelcompleter/mainwindow.h 1 + + \section1 MainWindow Class Implementation + + The \c{MainWindow}'s constructor creates a \c MainWindow object with a + parent and initializes the \c completer and \c lineEdit. The + \c createMenu() function is invoked to set up the "File" menu and "Help" + menu. The \c{completer}'s model is set to the QAbstractItemModel obtained + from \c modelFromFile(), and the \l{QCompleter::highlighted()} + {highlighted()} signal is connected to \c{MainWindow}'s \c highlight() + slot. + + \snippet examples/tools/treemodelcompleter/mainwindow.cpp 0 + + The QLabel objects \c modelLabel, \c modeLabel and \c caseLabel are + instantiated. Also, the QComboBox objects, \c modeCombo and \c caseCombo, + are instantiated and populated. By default, the \c{completer}'s mode is + "Filtered Popup" and the case is insensitive. + + \snippet examples/tools/treemodelcompleter/mainwindow.cpp 1 + \codeline + \snippet examples/tools/treemodelcompleter/mainwindow.cpp 2 + + We use a QGridLayout to place all the objects in the \c MainWindow. + + \snippet examples/tools/treemodelcompleter/mainwindow.cpp 3 + + The \c createMenu() function sets up the QAction objects required and + adds them to the "File" menu and "Help" menu. The + \l{QAction::triggered()}{triggered()} signals from these actions are + connected to their respective slots. + + \snippet examples/tools/treemodelcompleter/mainwindow.cpp 4 + + The \c changeMode() function accepts an \a index corresponding to the + user's choice of completion mode and changes the \c{completer}'s mode + accordingly. + + \snippet examples/tools/treemodelcompleter/mainwindow.cpp 5 + + The \c about() function provides a brief description on the Tree Model + Completer example. + + \snippet examples/tools/treemodelcompleter/mainwindow.cpp 6 + + The \c changeCase() function alternates between \l{Qt::CaseSensitive} + {Case Sensitive} and \l{Qt::CaseInsensitive}{Case Insensitive} modes, + depending on the value of \a cs. + + \snippet examples/tools/treemodelcompleter/mainwindow.cpp 7 + + \section1 \c main() Function + + The \c main() function instantiates \c MainWindow and invokes the + \l{QWidget::show()}{show()} function to display it. + + \snippet examples/tools/treemodelcompleter/main.cpp 0 +*/ diff --git a/doc/src/examples/trivialwizard.qdoc b/doc/src/examples/trivialwizard.qdoc new file mode 100644 index 0000000..360ea00 --- /dev/null +++ b/doc/src/examples/trivialwizard.qdoc @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example dialogs/trivialwizard + \title Trivial Wizard Example + + The Trivial Wizard example illustrates how to create a linear three-page + registration wizard using three instances of QWizardPage and one instance + of QWizard. + + \image trivialwizard-example-flow.png + + \section1 Introduction Page + + \image trivialwizard-example-introduction.png + + The introduction page is created with the \c createIntroPage() + function where a QWizardPage is created and its title is set to + "Introduction". A QLabel is used to hold the description of \c page. + A QVBoxLayout is used to hold the \c label. This \c page is returned + when the \c createIntroPage() function is called. + + \snippet examples/dialogs/trivialwizard/trivialwizard.cpp 0 + + \section1 Registration Page + + \image trivialwizard-example-registration.png + + The registration page is created with the \c createRegistrationPage() + function. QLineEdit objects are used to allow the user to input a name + and an e-mail address. A QGridLayout is used to hold the QLabel and + QLineEdit objects. + + \snippet examples/dialogs/trivialwizard/trivialwizard.cpp 2 + + \section1 Conclusion Page + + \image trivialwizard-example-conclusion.png + + The conclusion page is created in the \c createConclusionPage() + function. This function's content is similar to \c createIntroPage(). A + QLabel is used to inform the user that the registration process has + completed successfully. + + \snippet examples/dialogs/trivialwizard/trivialwizard.cpp 6 + + \section1 \c main() Function + + The \c main() function instantiates a QWizard object, \c wizard, and + adds all three QWizardPage objects to it. The \c wizard window title is + set to "Trivial Wizard" and its \c show() function is invoked to display + it. + + \snippet examples/dialogs/trivialwizard/trivialwizard.cpp 10 + + \sa QWizard, {Class Wizard Example}, {License Wizard Example} +*/ diff --git a/doc/src/examples/trollprint.qdoc b/doc/src/examples/trollprint.qdoc new file mode 100644 index 0000000..38251ee --- /dev/null +++ b/doc/src/examples/trollprint.qdoc @@ -0,0 +1,275 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example linguist/trollprint + \title Troll Print Example + + Troll Print is an example application that lets the user choose + printer settings. It comes in two versions: English and + Portuguese. + + \image linguist-trollprint_10_en.png + + We've included a translation file, \c trollprint_pt.ts, which contains some + Portuguese translations for this example. + + We will consider two releases of the same application: Troll Print + 1.0 and 1.1. We will learn to reuse the translations created for one + release in a subsequent release. (In this tutorial, you need to edit + some source files. It's probably best to copy all the files to a new + temporary directory and work from there.) + + See the \l{Qt Linguist manual} for more information about + translating Qt application. + + \section1 Line by Line Walkthrough + + The \c PrintPanel class is defined in \c printpanel.h. + + \snippet examples/linguist/trollprint/printpanel.h 0 + + \c PrintPanel is a QWidget. It needs the \c Q_OBJECT macro for \c + tr() to work properly. + + The implementation file is \c printpanel.cpp. + + \snippet examples/linguist/trollprint/printpanel.cpp 0 + + Some of the code is commented out in Troll Print 1.0; you will + uncomment it later, for Troll Print 1.1. + + \snippet examples/linguist/trollprint/printpanel.cpp 1 + \snippet examples/linguist/trollprint/printpanel.cpp 2 + + Notice the two occurrences of \c tr("Enabled") and of \c + tr("Disabled") in PrintPanel. Since both "Enabled"s and "Disabled"s + appear in the same context \e {Qt Linguist} will only display one + occurrence of each and will use the same translations for the + duplicates that it doesn't display. Whilst this is a useful + timesaver, in some languages, such as Portuguese, the second + occurrence requires a separate translation. We will see how \e {Qt + Linguist} can be made to display all the occurrences for separate + translation shortly. + + The header file for \c MainWindow, \c mainwindow.h, contains no + surprises. In the implementation, \c mainwindow.cpp, we have some + user-visible source texts that must be marked for translation. + + \snippet examples/linguist/trollprint/mainwindow.cpp 0 + + We must translate the window title. + + \snippet examples/linguist/trollprint/mainwindow.cpp 1 + \snippet examples/linguist/trollprint/mainwindow.cpp 3 + + We also need to translate the actions and menus. Note that the + two argument form of \c tr() is used for the keyboard + accelerator, "Ctrl+Q", since the second argument is the only clue + the translator has to indicate what function that accelerator + will perform. + + \snippet examples/linguist/trollprint/main.cpp 0 + + The \c main() function in \c main.cpp is the same as the one in + the \l{linguist/arrowpad}{Arrow Pad} example. In particular, it + chooses a translation file based on the current locale. + + \section1 Running Troll Print 1.0 in English and in Portuguese + + We will use the translations in the \c trollprint_pt.ts file that is provided. + + Set the \c LANG environment variable to \c pt, and then run \c + trollprint. You should still see the English version. Now run \c + lrelease, e.g. \c {lrelease trollprint.pro}, and then run the + example again. Now you should see the Portuguese edition (Troll + Imprimir 1.0): + + \image linguist-trollprint_10_pt_bad.png + + Whilst the translation has appeared correctly, it is in fact wrong. In + good Portuguese, the second occurrence of "Enabled" should be + "Ativadas", not "Ativado" and the ending for the second translation of + "Disabled" must change similarly too. + + If you open \c trollprint_pt.ts using \e {Qt Linguist}, you will see that + there is just one occurrence of "Enabled" and of "Disabled" in the + translation source file, even though there are two of each in the + source code. This is because \e {Qt Linguist} tries to minimize the + translator's work by using the same translation for duplicate source + texts. In cases such as this where an identical translation is wrong, + the programmer must disambiguate the duplicate occurrences. This is + easily achieved by using the two argument form of \c tr(). + + We can easily determine which file must be changed because the + translator's "context" is in fact the class name for the class where + the texts that must be changed appears. In this case the file is \c + printpanel.cpp, where the there are four lines to change. Add the + second argument "two-sided" in the appropriate \c tr() calls to the + first pair of radio buttons: + + \snippet doc/src/snippets/code/doc_src_examples_trollprint.qdoc 0 + + and add the second argument "colors" in the appropriate \c tr() calls + for the second pair of radio buttons: + + \snippet doc/src/snippets/code/doc_src_examples_trollprint.qdoc 1 + + Now run \c lupdate and open \c trollprint_pt.ts with \e {Qt Linguist}. You + should now see two changes. + + First, the translation source file now contains \e three "Enabled", + "Disabled" pairs. The first pair is marked "(obs.)" signifying that they + are obsolete. This is because these texts appeared in \c tr() calls that + have been replaced by new calls with two arguments. The second pair has + "two-sided" as their comment, and the third pair has "colors" as their + comment. The comments are shown in the \gui {Source text and comments} + area in \e {Qt Linguist}. + + Second, the translation text "Ativado" and "Desativado" have been + automatically used as translations for the new "Enabled" and "Disabled" + texts, again to minimize the translator's work. Of course in this case + these are not correct for the second occurrence of each word, but they + provide a good starting point. + + Change the second "Ativado" into "Ativadas" and the second + "Desativado" into "Desativadas", then save and quit. Run \c lrelease + to obtain an up-to-date binary \c trollprint_pt.qm file, and run Troll Print + (or rather Troll Imprimir). + + \image linguist-trollprint_10_pt_good.png + + The second argument to \c tr() calls, called "comments" in \e {Qt + Linguist}, distinguish between identical source texts that occur in + the same context (class). They are also useful in other cases to give + clues to the translator, and in the case of Ctrl key accelerators are + the only means of conveying the function performed by the accelerator to + the translator. + + An additional way of helping the translator is to provide information on + how to navigate to the particular part of the application that contains + the source texts they must translate. This helps them see the context + in which the translation appears and also helps them to find and test + the translations. This can be achieved by using a \c TRANSLATOR comment + in the source code: + + \snippet doc/src/snippets/code/doc_src_examples_trollprint.qdoc 2 + + Try adding these comments to some source files, particularly to + dialog classes, describing the navigation necessary to reach the + dialogs. You could also add them to the example files, e.g. \c + mainwindow.cpp and \c printpanel.cpp are appropriate files. Run \c + lupdate and then start \e {Qt Linguist} and load in \c trollprint_pt.ts. + You should see the comments in the \gui {Source text and comments} area + as you browse through the list of source texts. + + Sometimes, particularly with large programs, it can be difficult for + the translator to find their translations and check that they're + correct. Comments that provide good navigation information can save + them time: + + \snippet doc/src/snippets/code/doc_src_examples_trollprint.qdoc 3 + + \section1 Troll Print 1.1 + + We'll now prepare release 1.1 of Troll Print. Start your favorite text + editor and follow these steps: + + \list + \o Uncomment the two lines that create a QLabel with the text + "\<b\>TROLL PRINT\</b\>" in \c printpanel.cpp. + \o Word-tidying: Replace "2-sided" by "Two-sided" in \c printpanel.cpp. + \o Replace "1.0" with "1.1" everywhere it occurs in \c mainwindow.cpp. + \o Update the copyright year to 1999-2000 in \c mainwindow.cpp. + \endlist + + (Of course the version number and copyright year would be consts or + #defines in a real application.) + + Once finished, run \c lupdate, then open \c trollprint_pt.ts in \e {Qt + Linguist}. The following items are of special interest: + + \list + \o \c MainWindow + \list + \o Troll Print 1.0 - marked "(obs.)", obsolete + \o About Troll Print 1.0 - marked "(obs.)", obsolete + \o Troll Print 1.0. Copyright 1999 Software, Inc. - + marked obsolete + \o Troll Print 1.1 - automatically translated as + "Troll Imprimir 1.1" + \o About Troll Print 1.1 - automatically translated as + "Troll Imprimir 1.1" + \o Troll Print 1.1. Copyright 1999-2000 Software, + Inc. - automatically translated as "Troll Imprimir 1.1. + Copyright 1999-2000 Software, Inc." + \endlist + \o \c PrintPanel + \list + \o 2-sided - marked "(obs.)", obsolete + \o \<b\>TROLL PRINT\</b\> - unmarked, i.e. untranslated + \o Two-sided - unmarked, i.e. untranslated. + \endlist + \endlist + + Notice that \c lupdate works hard behind the scenes to make revisions + easier, and it's pretty smart with numbers. + + Go over the translations in \c MainWindow and mark these as "done". + Translate "\<b\>TROLL PRINT\</b\>" as "\<b\>TROLL IMPRIMIR\</b\>". + When you're translating "Two-sided", press the \gui {Guess Again} + button to translate "Two-sided", but change the "2" into "Dois". + + Save and quit, then run \c lrelease. The Portuguese version + should look like this: + + \image linguist-trollprint_11_pt.png + + Choose \gui{Ajuda|Sobre} (\gui{Help|About}) to see the about box. + + If you choose \gui {Ajuda|Sobre Qt} (\gui {Help|About Qt}), you'll get + an English dialog. Oops! Qt itself needs to be translated. See + \l{Internationalization with Qt} for details. + + Now set \c LANG=en to get the original English version: + + \image linguist-trollprint_11_en.png +*/ diff --git a/doc/src/examples/undoframework.qdoc b/doc/src/examples/undoframework.qdoc new file mode 100644 index 0000000..3d0965f --- /dev/null +++ b/doc/src/examples/undoframework.qdoc @@ -0,0 +1,306 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/undoframework + \title Undo Framework Example + + This example shows how to implement undo/redo functionality + with the Qt undo framework. + + \image undoframeworkexample.png The Undo Diagram Example + + In the Qt undo framework, all actions that the user performs are + implemented in classes that inherit QUndoCommand. An undo command + class knows how to both \l{QUndoCommand::}{redo()} - or just do + the first time - and \l{QUndoCommand::}{undo()} an action. For + each action the user performs, a command is placed on a + QUndoStack. Since the stack contains all commands executed + (stacked in chronological order) on the document, it can roll the + state of the document backwards and forwards by undoing and redoing + its commands. See the \l{Overview of Qt's Undo Framework}{overview + document} for a high-level introduction to the undo framework. + + The undo example implements a simple diagram application. It is + possible to add and delete items, which are either box or + rectangular shaped, and move the items by dragging them with the + mouse. The undo stack is shown in a QUndoView, which is a list in + which the commands are shown as list items. Undo and redo are + available through the edit menu. The user can also select a command + from the undo view. + + We use the \l{The Graphics View Framework}{graphics view + framework} to implement the diagram. We only treat the related + code briefly as the framework has examples of its own (e.g., the + \l{Diagram Scene Example}). + + The example consists of the following classes: + + \list + \o \c MainWindow is the main window and arranges the + example's widgets. It creates the commands based + on user input and keeps them on the command stack. + \o \c AddCommand adds an item to the scene. + \o \c DeleteCommand deletes an item from the scene. + \o \c MoveCommand when an item is moved the MoveCommand keeps record + of the start and stop positions of the move, and it + moves the item according to these when \c redo() and \c undo() + is called. + \o \c DiagramScene inherits QGraphicsScene and + emits signals for the \c MoveComands when an item is moved. + \o \c DiagramItem inherits QGraphicsPolygonItem and represents + an item in the diagram. + \endlist + + \section1 MainWindow Class Definition + + \snippet examples/tools/undoframework/mainwindow.h 0 + + The \c MainWindow class maintains the undo stack, i.e., it creates + \l{QUndoCommand}s and pushes and pops them from the stack when it + receives the \c triggered() signal from \c undoAction and \c + redoAction. + + \section1 MainWindow Class Implementation + + We will start with a look at the constructor: + + \snippet examples/tools/undoframework/mainwindow.cpp 0 + + In the constructor, we set up the DiagramScene and QGraphicsView. + + Here is the \c createUndoView() function: + + \snippet examples/tools/undoframework/mainwindow.cpp 1 + + The QUndoView is a widget that display the text, which is set with + the \l{QUndoCommand::}{setText()} function, for each QUndoCommand + in the undo stack in a list. + + Here is the \c createActions() function: + + \snippet examples/tools/undoframework/mainwindow.cpp 2 + \codeline + \snippet examples/tools/undoframework/mainwindow.cpp 3 + \dots + \snippet examples/tools/undoframework/mainwindow.cpp 5 + + The \c createActions() function sets up all the examples actions + in the manner shown above. The + \l{QUndoStack::}{createUndoAction()} and + \l{QUndoStack::}{createRedoAction()} helps us crate actions that + are disabled and enabled based on the state of the stack. Also, + the text of the action will be updated automatically based on the + \l{QUndoCommand::}{text()} of the undo commands. For the other + actions we have implemented slots in the \c MainWindow class. + + Here is the \c createMenus() function: + + \snippet examples/tools/undoframework/mainwindow.cpp 6 + + \dots + \snippet examples/tools/undoframework/mainwindow.cpp 7 + \dots + \snippet examples/tools/undoframework/mainwindow.cpp 8 + + We have to use the QMenu \c aboutToShow() and \c aboutToHide() + signals since we only want \c deleteAction to be enabled when we + have selected an item. + + Here is the \c itemMoved() slot: + + \snippet examples/tools/undoframework/mainwindow.cpp 9 + + We simply push a MoveCommand on the stack, which calls \c redo() + on it. + + Here is the \c deleteItem() slot: + + \snippet examples/tools/undoframework/mainwindow.cpp 10 + + An item must be selected to be deleted. We need to check if it is + selected as the \c deleteAction may be enabled even if an item is + not selected. This can happen as we do not catch a signal or event + when an item is selected. + + Here is the \c itemMenuAboutToShow() and itemMenuAboutToHide() slots: + + \snippet examples/tools/undoframework/mainwindow.cpp 11 + \codeline + \snippet examples/tools/undoframework/mainwindow.cpp 12 + + We implement \c itemMenuAboutToShow() and \c itemMenuAboutToHide() + to get a dynamic item menu. These slots are connected to the + \l{QMenu::}{aboutToShow()} and \l{QMenu::}{aboutToHide()} signals. + We need this to disable or enable the \c deleteAction. + + Here is the \c addBox() slot: + + \snippet examples/tools/undoframework/mainwindow.cpp 13 + + The \c addBox() function creates an AddCommand and pushes it on + the undo stack. + + Here is the \c addTriangle() sot: + + \snippet examples/tools/undoframework/mainwindow.cpp 14 + + The \c addTriangle() function creates an AddCommand and pushes it + on the undo stack. + + Here is the implementation of \c about(): + + \snippet examples/tools/undoframework/mainwindow.cpp 15 + + The about slot is triggered by the \c aboutAction and displays an + about box for the example. + + \section1 AddCommand Class Definition + + \snippet examples/tools/undoframework/commands.h 2 + + The \c AddCommand class adds DiagramItem graphics items to the + DiagramScene. + + \section1 AddCommand Class Implementation + + We start with the constructor: + + \snippet examples/tools/undoframework/commands.cpp 7 + + We first create the DiagramItem to add to the DiagramScene. The + \l{QUndoCommand::}{setText()} function let us set a QString that + describes the command. We use this to get custom messages in the + QUndoView and in the menu of the main window. + + \snippet examples/tools/undoframework/commands.cpp 8 + + \c undo() removes the item from the scene. We need to update the + scene as ...(ask Andreas) + + \snippet examples/tools/undoframework/commands.cpp 9 + + We set the position of the item as we do not do this in the + constructor. + + \section1 DeleteCommand Class Definition + + \snippet examples/tools/undoframework/commands.h 1 + + The DeleteCommand class implements the functionality to remove an + item from the scene. + + \section1 DeleteCommand Class Implementation + + \snippet examples/tools/undoframework/commands.cpp 4 + + We know that there must be one selected item as it is not possible + to create a DeleteCommand unless the item to be deleted is + selected and that only one item can be selected at any time. + The item must be unselected if it is inserted back into the + scene. + + \snippet examples/tools/undoframework/commands.cpp 5 + + The item is simply reinserted into the scene. + + \snippet examples/tools/undoframework/commands.cpp 6 + + The item is removed from the scene. + + \section1 MoveCommand Class Definition + + \snippet examples/tools/undoframework/commands.h 0 + + The \l{QUndoCommand::}{mergeWith()} is reimplemented to make + consecutive moves of an item one MoveCommand, i.e, the item will + be moved back to the start position of the first move. + + \section1 MoveCommand Class Implementation + + + The constructor of MoveCommand looks like this: + + \snippet examples/tools/undoframework/commands.cpp 0 + + We save both the old and new positions for undo and redo + respectively. + + \snippet examples/tools/undoframework/commands.cpp 2 + + We simply set the items old position and update the scene. + + \snippet examples/tools/undoframework/commands.cpp 3 + + We set the item to its new position. + + \snippet examples/tools/undoframework/commands.cpp 1 + + Whenever a MoveCommand is created, this function is called to + check if it should be merged with the previous command. It is the + previous command object that is kept on the stack. The function + returns true if the command is merged; otherwise false. + + We first check whether it is the same item that has been moved + twice, in which case we merge the commands. We update the position + of the item so that it will take the last position in the move + sequence when undone. + + \section1 DiagramScene Class Definition + + \snippet examples/tools/undoframework/diagramscene.h 0 + + The DiagramScene implements the functionality to move a + DiagramItem with the mouse. It emits a signal when a move is + completed. This is caught by the \c MainWindow, which makes + MoveCommands. We do not examine the implementation of DiagramScene + as it only deals with graphics framework issues. + + \section1 The \c main() Function + + The \c main() function of the program looks like this: + + \snippet examples/tools/undoframework/main.cpp 0 + + We draw a grid in the background of the DiagramScene, so we use a + resource file. The rest of the function creates the \c MainWindow and + shows it as a top level window. +*/ diff --git a/doc/src/examples/waitconditions.qdoc b/doc/src/examples/waitconditions.qdoc new file mode 100644 index 0000000..dce0411 --- /dev/null +++ b/doc/src/examples/waitconditions.qdoc @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example threads/waitconditions + \title Wait Conditions Example + + The Wait Conditions example shows how to use QWaitCondition and + QMutex to control access to a circular buffer shared by a + producer thread and a consumer thread. + + The producer writes data to the buffer until it reaches the end + of the buffer, at which point it restarts from the beginning, + overwriting existing data. The consumer thread reads the data as + it is produced and writes it to standard error. + + Wait conditions make it possible to have a higher level of + concurrency than what is possible with mutexes alone. If accesses + to the buffer were simply guarded by a QMutex, the consumer + thread couldn't access the buffer at the same time as the + producer thread. Yet, there is no harm in having both threads + working on \e{different parts} of the buffer at the same time. + + The example comprises two classes: \c Producer and \c Consumer. + Both inherit from QThread. The circular buffer used for + communicating between these two classes and the synchronization + tools that protect it are global variables. + + An alternative to using QWaitCondition and QMutex to solve the + producer-consumer problem is to use QSemaphore. This is what the + \l{threads/semaphores}{Semaphores} example does. + + \section1 Global Variables + + Let's start by reviewing the circular buffer and the associated + synchronization tools: + + \snippet examples/threads/waitconditions/waitconditions.cpp 0 + + \c DataSize is the amount of data that the producer will generate. + To keep the example as simple as possible, we make it a constant. + \c BufferSize is the size of the circular buffer. It is less than + \c DataSize, meaning that at some point the producer will reach + the end of the buffer and restart from the beginning. + + To synchronize the producer and the consumer, we need two wait + conditions and one mutex. The \c bufferNotEmpty condition is + signalled when the producer has generated some data, telling the + consumer that it can start reading it. The \c bufferNotFull + condition is signalled when the consumer has read some data, + telling the producer that it can generate more. The \c numUsedBytes + is the number of bytes in the buffer that contain data. + + Together, the wait conditions, the mutex, and the \c numUsedBytes + counter ensure that the producer is never more than \c BufferSize + bytes ahead of the consumer, and that the consumer never reads + data that the consumer hasn't generated yet. + + \section1 Producer Class + + Let's review the code for the \c Producer class: + + \snippet examples/threads/waitconditions/waitconditions.cpp 1 + \snippet examples/threads/waitconditions/waitconditions.cpp 2 + + The producer generates \c DataSize bytes of data. Before it + writes a byte to the circular buffer, it must first check whether + the buffer is full (i.e., \c numUsedBytes equals \c BufferSize). + If the buffer is full, the thread waits on the \c bufferNotFull + condition. + + At the end, the producer increments \c numUsedBytes and signalls + that the condition \c bufferNotEmpty is true, since \c + numUsedBytes is necessarily greater than 0. + + We guard all accesses to the \c numUsedBytes variable with a + mutex. In addition, the QWaitCondition::wait() function accepts a + mutex as its argument. This mutex is unlocked before the thread + is put to sleep and locked when the thread wakes up. Furthermore, + the transition from the locked state to the wait state is atomic, + to prevent race conditions from occurring. + + \section1 Consumer Class + + Let's turn to the \c Consumer class: + + \snippet examples/threads/waitconditions/waitconditions.cpp 3 + \snippet examples/threads/waitconditions/waitconditions.cpp 4 + + The code is very similar to the producer. Before we read the + byte, we check whether the buffer is empty (\c numUsedBytes is 0) + instead of whether it's full and wait on the \c bufferNotEmpty + condition if it's empty. After we've read the byte, we decrement + \c numUsedBytes (instead of incrementing it), and we signal the + \c bufferNotFull condition (instead of the \c bufferNotEmpty + condition). + + \section1 The main() Function + + In \c main(), we create the two threads and call QThread::wait() + to ensure that both threads get time to finish before we exit: + + \snippet examples/threads/waitconditions/waitconditions.cpp 5 + \snippet examples/threads/waitconditions/waitconditions.cpp 6 + + So what happens when we run the program? Initially, the producer + thread is the only one that can do anything; the consumer is + blocked waiting for the \c bufferNotEmpty condition to be + signalled (\c numUsedBytes is 0). Once the producer has put one + byte in the buffer, \c numUsedBytes is \c BufferSize - 1 and the + \c bufferNotEmpty condition is signalled. At that point, two + things can happen: Either the consumer thread takes over and + reads that byte, or the consumer gets to produce a second byte. + + The producer-consumer model presented in this example makes it + possible to write highly concurrent multithreaded applications. + On a multiprocessor machine, the program is potentially up to + twice as fast as the equivalent mutex-based program, since the + two threads can be active at the same time on different parts of + the buffer. + + Be aware though that these benefits aren't always realized. + Locking and unlocking a QMutex has a cost. In practice, it would + probably be worthwhile to divide the buffer into chunks and to + operate on chunks instead of individual bytes. The buffer size is + also a parameter that must be selected carefully, based on + experimentation. +*/ diff --git a/doc/src/examples/wiggly.qdoc b/doc/src/examples/wiggly.qdoc new file mode 100644 index 0000000..5406c77 --- /dev/null +++ b/doc/src/examples/wiggly.qdoc @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/wiggly + \title Wiggly Example + + The Wiggly example shows how to animate a widget using + QBasicTimer and \l{QObject::timerEvent()}{timerEvent()}. In + addition, the example demonstrates how to use QFontMetrics to + determine the size of text on screen. + + \image wiggly-example.png Screenshot of the Wiggly example + + QBasicTimer is a low-level class for timers. Unlike QTimer, + QBasicTimer doesn't inherit from QObject; instead of emitting a + \l{QTimer::timeout()}{timeout()} signal when a certain amount of + time has passed, it sends a QTimerEvent to a QObject of our + choice. This makes QBasicTimer a more lightweight alternative to + QTimer. Qt's built-in widgets use it internally, and it is + provided in Qt's API for highly-optimized applications (e.g., + \l{Qt for Embedded Linux} applications). + + The example consists of two classes: + + \list + \o \c WigglyWidget is the custom widget displaying the text + in a wiggly line. + + \o \c Dialog is the dialog widget allowing the user to enter a + text. It combines a \c WigglyWidget and a \c QLineEdit. + \endlist + + We will first take a quick look at the \c Dialog class, then we + will review the \c WigglyWidget class. + + \section1 Dialog Class Definition + + \snippet examples/widgets/wiggly/dialog.h 0 + + The \c Dialog class provides a dialog widget that allows the user + to enter a text. The text is then rendered by \c WigglyWidget. + + \section1 Dialog Class Implementation + + \snippet examples/widgets/wiggly/dialog.cpp 0 + + In the constructor we create a wiggly widget along with a + \l{QLineEdit}{line edit}, and we put the two widgets in a + vertical layout. We connect the line edit's \l + {QLineEdit::textChanged()}{textChanged()} signal to the wiggly + widget's \c setText() slot to obtain the real time interaction + with the wiggly widget. The widget's default text is "Hello + world!". + + \section1 WigglyWidget Class Definition + + \snippet examples/widgets/wiggly/wigglywidget.h 0 + + The \c WigglyWidget class provides the wiggly line displaying the + text. We subclass QWidget and reimplement the standard \l + {QWidget::paintEvent()}{paintEvent()} and \l + {QObject::timerEvent()}{timerEvent()} functions to draw and update + the widget. In addition we implement a public \c setText() slot + that sets the widget's text. + + The \c timer variable, of type QBasicTimer, is used to update the + widget at regular intervals, making the widget move. The \c text + variable is used to store the currently displayed text, and \c + step to calculate position and color for each character on the + wiggly line. + + \section1 WigglyWidget Class Implementation + + \snippet examples/widgets/wiggly/wigglywidget.cpp 0 + + In the constructor, we make the widget's background slightly + lighter than the usual background using the QPalette::Midlight + color role. The background role defines the brush from the + widget's palette that Qt uses to paint the background. Then we + enlarge the widget's font with 20 points. + + Finally we start the timer; the call to QBasicTimer::start() + makes sure that \e this particular wiggly widget will receive the + timer events generated when the timer times out (every 60 + milliseconds). + + \snippet examples/widgets/wiggly/wigglywidget.cpp 1 + \snippet examples/widgets/wiggly/wigglywidget.cpp 2 + + The \c paintEvent() function is called whenever a QPaintEvent is + sent to the widget. Paint events are sent to widgets that need to + update themselves, for instance when part of a widget is exposed + because a covering widget was moved. For the wiggly widget, a + paint event will also be generated every 60 milliseconds from + the \c timerEvent() slot. + + The \c sineTable represents y-values of the sine curve, + multiplied by 100. It is used to make the wiggly widget move + along the sine curve. + + The QFontMetrics object provides information about the widget's + font. The \c x variable is the horizontal position where we start + drawing the text. The \c y variable is the vertical position of + the text's base line. Both variables are computed so that the + text is horizontally and vertically centered. To compute the base + line, we take into account the font's ascent (the height of the + font above the base line) and font's descent (the height of the + font below the base line). If the descent equals the ascent, they + cancel out each other and the base line is at \c height() / 2. + + \snippet examples/widgets/wiggly/wigglywidget.cpp 3 + \snippet examples/widgets/wiggly/wigglywidget.cpp 4 + + Each time the \c paintEvent() function is called, we create a + QPainter object \c painter to draw the contents of the widget. + For each character in \c text, we determine the color and the + position on the wiggly line based on \c step. In addition, \c x + is incremented by the character's width. + + For simplicity, we assume that QFontMetrics::width(\c text) + returns the sum of the individual character widths + (QFontMetrics::width(\c text[i])). In practice, this is not + always the case because QFontMetrics::width(\c text) also takes + into account the kerning between certain letters (e.g., 'A' and + 'V'). The result is that the text isn't perfectly centered. You + can verify this by typing "AVAVAVAVAVAV" in the line edit. + + \snippet examples/widgets/wiggly/wigglywidget.cpp 5 + \snippet examples/widgets/wiggly/wigglywidget.cpp 6 + + The \c timerEvent() function receives all the timer events that + are generated for this widget. If a timer event is sent from the + widget's QBasicTimer, we increment \c step to make the text move, + and call QWidget::update() to refresh the display. Any other + timer event is passed on to the base class's implementation of + the \l{QWidget::timerEvent()}{timerEvent()} function. + + The QWidget::update() slot does not cause an immediate repaint; + instead the slot schedules a paint event for processing when Qt + returns to the main event loop. The paint events are then handled + by \c{WigglyWidget}'s \c paintEvent() function. +*/ diff --git a/doc/src/examples/windowflags.qdoc b/doc/src/examples/windowflags.qdoc new file mode 100644 index 0000000..b25206e --- /dev/null +++ b/doc/src/examples/windowflags.qdoc @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/windowflags + \title Window Flags Example + + The Window Flags example shows how to use the window flags + available in Qt. + + A window flag is either a type or a hint. A type is used to + specify various window-system properties for the widget. A widget + can only have one type, and the default is Qt::Widget. However, a + widget can have zero or more hints. The hints are used to + customize the appearance of top-level windows. + + A widget's flags are stored in a Qt::WindowFlags type which stores + an OR combination of the flags. + + \image windowflags-example.png Screenshot of the Window Flags example + + The example consists of two classes: + + \list + \o \c ControllerWindow is the main application widget that allows + the user to choose among the available window flags, and displays + the effect on a separate preview window. + \o \c PreviewWindow is a custom widget displaying the name of + its currently set window flags in a read-only text editor. + \endlist + + We will start by reviewing the \c ControllerWindow class, then we + will take a look at the \c PreviewWindow class. + + \section1 ControllerWindow Class Definition + + \snippet examples/widgets/windowflags/controllerwindow.h 0 + + The \c ControllerWindow class inherits QWidget. The widget allows + the user to choose among the available window flags, and displays + the effect on a separate preview window. + + We declare a private \c updatePreview() slot to refresh the + preview window whenever the user changes the window flags. + + We also declare several private functions to simplify the + constructor: We call the \c createTypeGroupBox() function to + create a radio button for each available window type, using the + private \c createButton() function, and gather them within a group + box. In a similar way we use the \c createHintsGroupBox() function + to create a check box for each available hint, using the private + \c createCheckBox() function. + + In addition to the various radio buttons and checkboxes, we need + an associated \c PreviewWindow to show the effect of the currently + chosen window flags. + + \image windowflags_controllerwindow.png Screenshot of the Controller Window + + \section1 ControllerWindow Class Implementation + + \snippet examples/widgets/windowflags/controllerwindow.cpp 0 + + In the constructor we first create the preview window. Then we + create the group boxes containing the available window flags using + the private \c createTypeGroupBox() and \c createHintsGroupBox() + functions. In addition we create a \gui Quit button. We put the + button and a stretchable space in a separate layout to make the + button appear in the \c WindowFlag widget's right bottom corner. + + Finally, we add the button's layout and the two goup boxes to a + QVBoxLayout, set the window title and refresh the preview window + using the \c updatePreview() slot. + + \snippet examples/widgets/windowflags/controllerwindow.cpp 1 + \snippet examples/widgets/windowflags/controllerwindow.cpp 2 + + The \c updatePreview() slot is called whenever the user changes + any of the window flags. First we create an empty Qt::WindowFlags + \c flags, then we determine which one of the types that is checked + and add it to \c flags. + + \snippet examples/widgets/windowflags/controllerwindow.cpp 3 + + We also determine which of the hints that are checked, and add + them to \c flags using an OR operator. We use \c flags to set the + window flags for the preview window. + + \snippet examples/widgets/windowflags/controllerwindow.cpp 4 + + We adjust the position of the preview window. The reason we do + that, is that playing around with the window's frame may on some + platforms cause the window's position to be changed behind our + back. If a window is located in the upper left corner of the + screen, parts of the window may not be visible. So we adjust the + widget's position to make sure that, if this happens, the window + is moved within the screen's boundaries. Finally, we call + QWidget::show() to make sure the preview window is visible. + + \omit + \skipto pos + \printuntil /^\}/ + \endomit + + \snippet examples/widgets/windowflags/controllerwindow.cpp 5 + + The private \c createTypeGroupBox() function is called from the + constructor. + + First we create a group box, and then we create a radio button + (using the private \c createRadioButton() function) for each of + the available types among the window flags. We make Qt::Window the + initially applied type. We put the radio buttons into a + QGridLayout and install the layout on the group box. + + We do not include the default Qt::Widget type. The reason is that + it behaves somewhat different than the other types. If the type is + not specified for a widget, and it has no parent, the widget is a + window. However, if it has a parent, it is a standard child + widget. The other types are all top-level windows, and since the + hints only affect top-level windows, we abandon the Qt::Widget + type. + + \snippet examples/widgets/windowflags/controllerwindow.cpp 6 + + The private \c createHintsGroupBox() function is also called from + the constructor. + + Again, the first thing we do is to create a group box. Then we + create a checkbox, using the private \c createCheckBox() function, + for each of the available hints among the window flags. We put the + checkboxes into a QGridLayout and install the layout on the group + box. + + \snippet examples/widgets/windowflags/controllerwindow.cpp 7 + + The private \c createCheckBox() function is called from \c + createHintsGroupBox(). + + We simply create a QCheckBox with the provided text, connect it to + the private \c updatePreview() slot, and return a pointer to the + checkbox. + + \snippet examples/widgets/windowflags/controllerwindow.cpp 8 + + In the private \c createRadioButton() function it is a + QRadioButton we create with the provided text, and connect to the + private \c updatePreview() slot. The function is called from \c + createTypeGroupBox(), and returns a pointer to the button. + + \section1 PreviewWindow Class Definition + + \snippet examples/widgets/windowflags/previewwindow.h 0 + + The \c PreviewWindow class inherits QWidget. It is a custom widget + that displays the names of its currently set window flags in a + read-only text editor. It is also provided with a QPushbutton that + closes the window. + + We reimplement the constructor to create the \gui Close button and + the text editor, and the QWidget::setWindowFlags() function to + display the names of the window flags. + + \image windowflags_previewwindow.png Screenshot of the Preview Window + + \section1 PreviewWindow Class Implementation + + \snippet examples/widgets/windowflags/previewwindow.cpp 0 + + In the constructor, we first create a QTextEdit and make sure that + it is read-only. + + We also prohibit any line wrapping in the text editor using the + QTextEdit::setLineWrapMode() function. The result is that a + horizontal scrollbar appears when a window flag's name exceeds the + width of the editor. This is a reasonable solution since we + construct the displayed text with built-in line breaks. If no line + breaks were guaranteed, using another QTextEdit::LineWrapMode + would perhaps make more sense. + + Then we create the \gui Close button, and put both the widgets + into a QVBoxLayout before we set the window title. + + \snippet examples/widgets/windowflags/previewwindow.cpp 1 + + In our reimplementation of the \c setWindowFlags() function, we + first set the widgets flags using the QWidget::setWindowFlags() + function. Then we run through the available window flags, creating + a text that contains the names of the flags that matches the \c + flags parameter. Finally, we display the text in the widgets text + editor. +*/ diff --git a/doc/src/examples/worldtimeclockbuilder.qdoc b/doc/src/examples/worldtimeclockbuilder.qdoc new file mode 100644 index 0000000..644ffdb --- /dev/null +++ b/doc/src/examples/worldtimeclockbuilder.qdoc @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example designer/worldtimeclockbuilder + \title World Time Clock Builder Example + + The World Time Clock Builder example shows how forms created with Qt + Designer that contain custom widgets can be dynamically generated at + run-time. + + \image worldtimeclockbuilder-example.png + + This example uses a form containing the custom widget plugin described in the + \l{designer/worldtimeclockplugin}{World Time Clock Plugin} example, and + dynamically generates a user interface using the QUiLoader class, part of + the QtUiTools module. + + \section1 Preparation + + As with the \l{designer/calculatorbuilder}{Calculator Builder} example, the + project file for this example needs to include the appropriate definitions + to ensure that it is built against the required Qt modules. + + \snippet examples/designer/worldtimeclockbuilder/worldtimeclockbuilder.pro 0 + + By appending \c form to the \c CONFIG declaration, we instruct \c qmake to + generate a dependency on the \c libQtUiTools library containing the QtUiTools + classes. + + Note that we do not inform \c qmake about any .ui files, and so none will + be processed and built into the application. The resource file contains + an entry for the particular form that we wish to use: + + \quotefile examples/designer/worldtimeclockbuilder/worldtimeclockbuilder.qrc + + Forms do not need to be included with the application in this way. We only + include a form in the application's resources for convenience, and to keep + the example short. + + \section1 Loading and Building the Form + + Since this example only loads and displays a pre-prepared form, all of the + work can be done in the main() function. We are using a class from the + QtUiTools library so, in addition to any other Qt classes that are normally + required to write an application, we must include the appropriate header + file: + + \snippet examples/designer/worldtimeclockbuilder/main.cpp 0 + + The main function initializes the resource system with the Q_INIT_RESOURCE() + macro and constructs an QApplication instance in the usual way: + + \snippet examples/designer/worldtimeclockbuilder/main.cpp 1 + + We construct a QUiLoader object to handle the form we want to use. + + The form itself is obtained from the resource file system using the path + defined in the resource file. We use the form loader to load and construct + the form: + + \snippet examples/designer/worldtimeclockbuilder/main.cpp 2 + + Once the form has been loaded, the resource file can be closed and the + widget is shown. + + \snippet examples/designer/worldtimeclockbuilder/main.cpp 3 + + The form loader ensures that all the signal and slot connections between + objects in the form are set up correctly when the form is loaded. As a + result, the time is updated by the World Time Clock widget, and the time + zone spin box can be used to change the position of the hour hand. +*/ diff --git a/doc/src/examples/worldtimeclockplugin.qdoc b/doc/src/examples/worldtimeclockplugin.qdoc new file mode 100644 index 0000000..072b1f0 --- /dev/null +++ b/doc/src/examples/worldtimeclockplugin.qdoc @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example designer/worldtimeclockplugin + \title World Time Clock Plugin Example + + The World Time Clock Plugin example shows how to create a custom + widget plugin for \QD that uses signals and slots. + + \image worldtimeclockplugin-example.png + + In this example, we simply extend the \l + {designer/customwidgetplugin}{Custom Widget Plugin} example and + its custom widget (based on the \l{widgets/analogclock}{Analog + Clock} example), by introducing the concept of signals and slots. + + The World Time Clock Plugin example consists of two classes: + + \list + \o \c WorldTimeClock is a custom clock widget with hour and + minute hands that is automatically updated every few seconds. + \o \c WorldTimeClockPlugin exposes the \c WorldTimeClock class to \QD. + \endlist + + First we will take a look at the \c WorldTimeClock class which + extends the \l {designer/customwidgetplugin}{Custom Widget Plugin} + example's \c AnalogClock class by providing a signal and a + slot. Then we will take a quick look at the \c + WorldTimeClockPlugin class, but this class is in most parts + identical to the \l {designer/customwidgetplugin}{Custom Widget + Plugin} example's implementation. + + Finally we take a look at the plugin's project file. The project + file for custom widget plugins needs some additional information + to ensure that they will work within \QD. This is also covered in + the \l {designer/customwidgetplugin}{Custom Widget Plugin} example, + but due to its importance (custom widget plugins rely on + components supplied with \QD which must be specified in the + project file that we use) we will repeat it here. + + \section1 WorldTimeClock Class + + The \c WorldTimeClock class inherits QWidget, and is a custom + clock widget with hour and minute hands that is automatically + updated every few seconds. What makes this example different from + the \l {designer/customwidgetplugin}{Custom Widget Plugin} + example, is the introduction of the signal and slot in the custom + widget class: + + \snippet examples/designer/worldtimeclockplugin/worldtimeclock.h 1 + + Note the use of the QDESIGNER_WIDGET_EXPORT macro. This is needed + to ensure that \QD can create instances of the widget on some + platforms, but it is a good idea to use it on all platforms. + + We declare the \c setTimeZone() slot with an associated \c + timeZoneOffset variable, and we declare an \c updated() signal + which takes the current time as argument and is emitted whenever + the widget is repainted. + + \image worldtimeclock-connection.png + + In \QD's workspace we can then, for example, connect the \c + WorldTimeClock widget's \c updated() signal to a QTimeEdit's \l + {QDateTimeEdit::setTime()}{setTime()} slot using \QD's mode + for editing signal and slots. + + \image worldtimeclock-signalandslot.png + + We can also connect a QSpinBox's \l + {QSpinBox::valueChanged()}{valueChanged()} signal to the \c + WorldTimeClock's \c setTimeZone() slot. + + \section1 WorldTimeClockPlugin Class + + The \c WorldTimeClockPlugin class exposes the \c WorldTimeClock + class to \QD. Its definition is equivalent to the \l + {designer/customwidgetplugin}{Custom Widget Plugin} example's + plugin class which is explained in detail. The only part of the + class definition that is specific to this particular custom widget + is the class name: + + \snippet examples/designer/worldtimeclockplugin/worldtimeclockplugin.h 0 + + The plugin class provides \QD with basic information about our + plugin, such as its class name and its include file. Furthermore + it knows how to create instances of the \c WorldTimeClockPlugin + widget. \c WorldTimeClockPlugin also defines the \l + {QDesignerCustomWidgetInterface::initialize()}{initialize()} + function which is called after the plugin is loaded into \QD. The + function's QDesignerFormEditorInterface parameter provides the + plugin with a gateway to all of \QD's API's. + + The \c WorldTimeClockPlugin class inherits from both QObject and + QDesignerCustomWidgetInterface. It is important to remember, when + using multiple inheritance, to ensure that all the interfaces + (i.e. the classes that doesn't inherit Q_OBJECT) are made known to + the meta object system using the Q_INTERFACES() macro. This + enables \QD to use \l qobject_cast() to query for supported + interfaces using nothing but a QObject pointer. + + The implementation of the \c WorldTimeClockPlugin is also + equivalent to the plugin interface implementation in the \l + {designer/customwidgetplugin}{Custom Widget Plugin} example (only + the class name and the implementation of + QDesignerCustomWidgetInterface::domXml() differ). The main thing + to remember is to use the Q_EXPORT_PLUGIN2() macro to export the \c + WorldTimeClockPlugin class for use with \QD: + + \snippet examples/designer/worldtimeclockplugin/worldtimeclockplugin.cpp 0 + + Without this macro, there is no way for Qt Designer to use the + widget. + + \section1 The Project File: worldtimeclockplugin.pro + + The project file for custom widget plugins needs some additional + information to ensure that they will work as expected within \QD: + + \snippet examples/designer/worldtimeclockplugin/worldtimeclockplugin.pro 0 + \snippet examples/designer/worldtimeclockplugin/worldtimeclockplugin.pro 1 + + The \c TEMPLATE variable's value make \c qmake create the custom + widget as a library. The \c CONFIG variable contains two values, + \c designer and \c plugin: + + \list + \o \c designer: Since custom widgets plugins rely on components + supplied with \QD, this value ensures that our plugin links against + \QD's library (\c libQtDesigner.so). + + \o \c plugin: We also need to ensure that \c qmake considers the + custom widget a \e plugin library. + \endlist + + When Qt is configured to build in both debug and release modes, + \QD will be built in release mode. When this occurs, it is + necessary to ensure that plugins are also built in release + mode. For that reason you might have to add a \c release value to + your \c CONFIG variable. Otherwise, if a plugin is built in a mode + that is incompatible with \QD, it won't be loaded and + installed. + + The header and source files for the widget are declared in the + usual way, and in addition we provide an implementation of the + plugin interface so that \QD can use the custom widget. + + \snippet examples/designer/worldtimeclockplugin/worldtimeclockplugin.pro 2 + + It is important to ensure that the plugin is installed in a location that + is searched by \QD. We do this by specifying a target path for the project + and adding it to the list of items to install: + + \snippet doc/src/snippets/code/doc_src_examples_worldtimeclockplugin.qdoc 0 + + The custom widget is created as a library, and will be installed + alongside the other \QD plugins when the project is installed + (using \c{make install} or an equivalent installation procedure). + Later, we will ensure that it is recognized as a plugin by \QD by + using the Q_EXPORT_PLUGIN2() macro to export the relevant widget + information. + + Note that if you want the plugins to appear in a Visual Studio + integration, the plugins must be built in release mode and their + libraries must be copied into the plugin directory in the install + path of the integration (for an example, see \c {C:/program + files/trolltech as/visual studio integration/plugins}). + + For more information about plugins, see the \l {How to Create Qt + Plugins} document. +*/ diff --git a/doc/src/examples/xmlstreamlint.qdoc b/doc/src/examples/xmlstreamlint.qdoc new file mode 100644 index 0000000..925a7a0 --- /dev/null +++ b/doc/src/examples/xmlstreamlint.qdoc @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xml/xmlstreamlint + \title XML Stream Lint Example + + The XML Stream Lint example provides a simple command line utility that + accepts a file name as its single argument and writes it to the standard + output file. + + The specified file is parsed using an QXmlStreamReader object and written + to the standard output file using an QXmlStreamWriter object. If the file + does not contain a well-formed XML document or the use of namespaces in + the document is incorrect, a description of the error is printed to + the standard error file and will appear in the console. + + \section1 Basic Operation + + The main function of the example opens the file specified by the user + for input (\c inputFile), and it uses QFile to access the standard output + file. + + Reading XML is handled by an instance of the QXmlStreamReader class, which + operates on the input file object; writing is handled by an instance of + QXmlStreamWriter operating on the output file object: + + \snippet examples/xml/xmlstreamlint/main.cpp 0 + + The work of parsing and rewriting the XML is done in a while loop, and is + driven by input from the reader: + + \snippet examples/xml/xmlstreamlint/main.cpp 1 + + If more input is available, the next token from the input file is read + and parsed. If an error occurred, information is written to the standard + error file via a stream, and the example exits by returning a non-zero + value from the main function. + + \snippet examples/xml/xmlstreamlint/main.cpp 2 + + For valid input, the writer is fed the current token from the reader, + and this is written to the output file that was specified when it was + constructed. + + When there is no more input, the loop terminates, and the example can + exit successfully. +*/ |