QT5 -- Add Qwt 6.1-multiaxes

This commit is contained in:
Mark Liversedge
2013-12-09 10:02:47 +00:00
parent 03d3afdf53
commit 5abf8776f1
492 changed files with 97336 additions and 0 deletions

543
qwt/COPYING Normal file
View File

@@ -0,0 +1,543 @@
Qwt License
Version 1.0, January 1, 2003
The Qwt library and included programs are provided under the terms
of the GNU LESSER GENERAL PUBLIC LICENSE (LGPL) with the following
exceptions:
1. Widgets that are subclassed from Qwt widgets do not
constitute a derivative work.
2. Static linking of applications and widgets to the
Qwt library does not constitute a derivative work
and does not require the author to provide source
code for the application or widget, use the shared
Qwt libraries, or link their applications or
widgets against a user-supplied version of Qwt.
If you link the application or widget to a modified
version of Qwt, then the changes to Qwt must be
provided under the terms of the LGPL in sections
1, 2, and 4.
3. You do not have to provide a copy of the Qwt license
with programs that are linked to the Qwt library, nor
do you have to identify the Qwt license in your
program or documentation as required by section 6
of the LGPL.
However, programs must still identify their use of Qwt.
The following example statement can be included in user
documentation to satisfy this requirement:
[program/widget] is based in part on the work of
the Qwt project (http://qwt.sf.net).
----------------------------------------------------------------------
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

1
qwt/INSTALL Normal file
View File

@@ -0,0 +1 @@
see doc/html/qwtinstall.html

34
qwt/README Normal file
View File

@@ -0,0 +1,34 @@
The Qwt Widget Library
----------------------
Qwt is an extension to the libraries of the Qt Project.
The Qwt library contains widgets and components which are
primarily useful for technical and scientifical purposes.
It includes a 2-D plotting widget, different kinds of sliders,
and much more.
Qwt is hosted at http://qwt.sf.net
Installation
------------
Read INSTALL how to build and install Qwt.
Copyright
---------
Qwt Widget Library
Copyright (C) 1997 Josef Wilgen
Copyright (C) 2002 Uwe Rathmann
Qwt is published under the Qwt License, Version 1.0.
You should have received a copy of this licence in the file
COPYING.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

38
qwt/TODO Normal file
View File

@@ -0,0 +1,38 @@
Qwt TODO list
Ideas
------
- Improve Documention
- QAbstractModel -> QwtSeriesData
- Box/Whisker plot item
- QwtSeriesData + functors
- QwtSeriesData/QwtPlotCurve + Level of details (Douglas Peucker)
- Common zoom stack for all navigation objects
- Watermark Item
- Contour algorithm for vectors: http://apptree.net/conrec.htm
- QwtPlotCanvas rendered via FBO, PBO
- Time/Date scale engine
- TeX texts
- Grid of QwtPlots
- Interval scale labels ( between 2 ticks )
- More than 4 axes
- QwtIntervalSymbol + QPainterPath/...
- QwtPlotScene + breaking composite architecture
- Using QStaticText for markers ( and scales ? )
- Scales/Grid item like in QwtPolarGrid
- Container for a 2D matrix
- Waterfall plots
- transform/invTransform for polygons and lines
- cursor item
- line marker with a line from the position to the axis
- quadtree
- QwtText supporting Qt::TextElideMode
- Multitouch events
- QwtKnob/QwtDial fixed contents size mode
- controls ( f.e QwtWheel ) with a very dark palette
Bugs/Change requests
--------------------
- Remove QwtScaleTransformation::copy()
- Reference value for QwtThermo
- Transparent canvas background + backingstore

326
qwt/admin/svn2package.sh Executable file
View File

@@ -0,0 +1,326 @@
#! /bin/sh
#
# Generates a Qwt package from sourceforge svn
#
# Usage: svn2package.sh [-b|--branch <svn-branch>] [packagename]
#
##########################
# usage
##########################
function usage() {
echo "Usage: $0 [-b|--branch <svn-branch>] [-s|--suffix <suffix>] [-html] [-pdf] [-qch] [packagename]"
exit 1
}
################################
# checkout
################################
function checkoutQwt() {
if [ -x $2 ]
then
rm -r $2
if [ $? -ne 0 ]
then
exit $?
fi
fi
svn -q co https://svn.code.sf.net/p/qwt/code/$1/$2
if [ $? -ne 0 ]
then
echo "Can't access sourceforge SVN"
exit $?
fi
if [ "$3" != "$2" ]
then
rm -rf $3
mv $2 $3
fi
}
##########################
# cleanQwt dirname
##########################
function cleanQwt {
cd $1
if [ $? -ne 0 ]
then
exit $?
fi
find . -name .svn -print | xargs rm -r
rm -f TODO
rm -rf admin
rm -rf doc/tex
PROFILES="qwtbuild.pri"
for PROFILE in $PROFILES
do
sed -i -e 's/= debug/= release/' $PROFILE
sed -i -e 's/= release_and_release/= debug_and_release/' $PROFILE
done
HEADERS=`find . -type f -name '*.h' -print`
SOURCES=`find . -type f -name '*.cpp' -print`
PROFILES=`find . -type f -name '*.pro' -print`
PRIFILES=`find . -type f -name '*.pri' -print`
for EXPANDFILE in $HEADERS $SOURCES $PROFILES $PRIFILES
do
expand -4 $EXPANDFILE > $EXPANDFILE.expand
mv $EXPANDFILE.expand $EXPANDFILE
done
for SRCFILE in $SOURCES $PROFILES $PRIFILES
do
sed -i -e '/#warning/d' $SRCFILE
done
if [ "$SUFFIX" != "" ]
then
sed -i -e "s/\$\$QWT_VERSION-svn/\$\$QWT_VERSION-$SUFFIX/" qwtconfig.pri
sed -i -e "s/\$(QWTVERSION)/$VERSION-$SUFFIX/" doc/install.dox
else
sed -i -e "s/\$\$QWT_VERSION-svn/\$\$QWT_VERSION/" qwtconfig.pri
sed -i -e "s/\$(QWTVERSION)/$VERSION/" doc/install.dox
fi
cd - > /dev/null
}
##########################
# createDocs dirname
##########################
function createDocs {
ODIR=`pwd`
cd $1
if [ $? -ne 0 ]
then
exit $?
fi
if [ "$SUFFIX" != "" ]
then
export QWTVERSION=$VERSION-$SUFFIX
else
export QWTVERSION=$VERSION
fi
cp Doxyfile Doxyfile.doc
if [ $GENERATE_MAN -ne 0 ]
then
sed -i -e '/GENERATE_MAN/d' Doxyfile.doc
echo 'GENERATE_MAN = YES' >> Doxyfile.doc
fi
if [ $GENERATE_PDF -ne 0 ]
then
# We need LateX for the qwtdoc.pdf
sed -i -e '/GENERATE_LATEX/d' -e '/GENERATE_MAN/d' Doxyfile.doc
echo 'GENERATE_LATEX = YES' >> Doxyfile.doc
echo 'GENERATE_MAN = YES' >> Doxyfile.doc
# sed -i -e '/INLINE_INHERITED_MEMB/d' Doxyfile.doc
# echo 'INLINE_INHERITED_MEMB = NO' >> Doxyfile.doc
fi
if [ $GENERATE_QCH -ne 0 ]
then
sed -i -e '/GENERATE_QHP/d' Doxyfile.doc
echo "GENERATE_QHP = YES" >> Doxyfile.doc
fi
cp ../INSTALL ../COPYING ./
doxygen Doxyfile.doc > /dev/null 2>&1
if [ $? -ne 0 ]
then
exit $?
fi
rm Doxyfile.doc Doxygen.log INSTALL COPYING
rm -r images
if [ $GENERATE_PDF -ne 0 ]
then
cd latex
make > /dev/null 2>&1
if [ $? -ne 0 ]
then
exit $?
fi
cd ..
mkdir pdf
mv latex/refman.pdf pdf/qwtdoc-$VERSION.pdf
rm -r latex
fi
cd $ODIR
}
##########################
# posix2dos filename
##########################
function posix2dos {
# At least one unix2dos writes to stdout instead of overwriting the input.
# The -q option is always enabled in stdin->stdout mode.
unix2dos <$1 >$1.dos
mv $1.dos $1
}
##########################
# prepare4Win dirname
##########################
function prepare4Win {
cd $1
if [ $? -ne 0 ]
then
exit $?
fi
rm -rf doc/man 2> /dev/null
# win files, but not uptodate
BATCHES=`find . -type f -name '*.bat' -print`
HEADERS=`find . -type f -name '*.h' -print`
SOURCES=`find . -type f -name '*.cpp' -print`
PROFILES=`find . -type f -name '*.pro' -print`
PRIFILES=`find . -type f -name '*.pri' -print`
PRFFILES=`find . -type f -name '*.prf' -print`
for FILE in $BATCHES $HEADERS $SOURCES $PROFILES $PRIFILES $PRFFILES
do
posix2dos $FILE
done
cd - > /dev/null
}
##########################
# prepare4Unix dirname
##########################
function prepare4Unix {
cd $1
if [ $? -ne 0 ]
then
exit $?
fi
cd - > /dev/null
}
##########################
# main
##########################
QWTDIR=
SVNDIR=trunk
BRANCH=qwt
SUFFIX=
VERSION=
GENERATE_DOC=0
GENERATE_PDF=0
GENERATE_QCH=0
GENERATE_MAN=0
while [ $# -gt 0 ] ; do
case "$1" in
-h|--help)
usage; exit 1 ;;
-b|--branch)
shift; SVNDIR=branches; BRANCH=$1; shift;;
-s|--suffix)
shift; SUFFIX=$1; shift;;
-html)
GENERATE_DOC=1; shift;;
-pdf)
GENERATE_DOC=1; GENERATE_PDF=1; shift;;
-qch)
GENERATE_DOC=1; GENERATE_QCH=1; shift;;
*)
QWTDIR=qwt-$1 ; VERSION=$1; shift;;
esac
done
if [ "$QWTDIR" == "" ]
then
usage
exit 2
fi
QWTNAME=$QWTDIR
if [ "$SUFFIX" != "" ]
then
QWTDIR=$QWTDIR-$SUFFIX
fi
TMPDIR=/tmp/$QWTDIR-tmp
echo -n "checkout to $TMPDIR ... "
checkoutQwt $SVNDIR $BRANCH $TMPDIR
cleanQwt $TMPDIR
echo done
if [ $GENERATE_DOC -ne 0 ]
then
echo -n "generate documentation ... "
export VERSION # used in the doxygen files
createDocs $TMPDIR/doc
if [ $GENERATE_PDF -ne 0 ]
then
mv $TMPDIR/doc/pdf/qwtdoc-$VERSION.pdf $QWTDIR.pdf
rmdir $TMPDIR/doc/pdf
fi
if [ $GENERATE_QCH -ne 0 ]
then
mv $TMPDIR/doc/html/qwtdoc.qch $QWTDIR.qch
fi
fi
echo done
DIR=`pwd`
echo -n "create packages in $DIR ... "
cd /tmp
rm -rf $QWTDIR
cp -a $TMPDIR $QWTDIR
prepare4Unix $QWTDIR
tar cfj $QWTDIR.tar.bz2 $QWTDIR
rm -rf $QWTDIR
cp -a $TMPDIR $QWTDIR
prepare4Win $QWTDIR
zip -r $QWTDIR.zip $QWTDIR > /dev/null
rm -rf $TMPDIR $QWTDIR
mv $QWTDIR.tar.bz2 $QWTDIR.zip $DIR/
echo done
exit 0

132
qwt/designer/designer.pro Normal file
View File

@@ -0,0 +1,132 @@
################################################################
# Qwt Widget Library
# Copyright (C) 1997 Josef Wilgen
# Copyright (C) 2002 Uwe Rathmann
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the Qwt License, Version 1.0
################################################################
QWT_ROOT = $${PWD}/..
include ( $${QWT_ROOT}/qwtconfig.pri )
include ( $${QWT_ROOT}/qwtbuild.pri )
include ( $${QWT_ROOT}/qwtfunctions.pri )
CONFIG( debug_and_release ) {
# When building debug_and_release the designer plugin is built
# for release only. If you want to have a debug version it has to be
# done with "CONFIG += debug" only.
message("debug_and_release: building the Qwt designer plugin in release mode only")
CONFIG -= debug_and_release
CONFIG += release
}
contains(QWT_CONFIG, QwtDesigner) {
CONFIG += qt plugin
CONFIG += warn_on
greaterThan(QT_MAJOR_VERSION, 4) {
QT += designer
}
else {
CONFIG += designer
}
TEMPLATE = lib
TARGET = qwt_designer_plugin
DESTDIR = plugins/designer
INCLUDEPATH += $${QWT_ROOT}/src
DEPENDPATH += $${QWT_ROOT}/src
contains(QWT_CONFIG, QwtDll) {
contains(QWT_CONFIG, QwtDesignerSelfContained) {
QWT_CONFIG += include_src
}
} else {
# for linking against a static library the
# plugin will be self contained anyway
}
contains(QWT_CONFIG, include_src) {
# compile all qwt classes into the plugin
include ( $${QWT_ROOT}/src/src.pri )
for( header, HEADERS) {
QWT_HEADERS += $${QWT_ROOT}/src/$${header}
}
for( source, SOURCES ) {
QWT_SOURCES += $${QWT_ROOT}/src/$${source}
}
HEADERS = $${QWT_HEADERS}
SOURCES = $${QWT_SOURCES}
} else {
# compile the path for finding the Qwt library
# into the plugin. Not supported on Windows !
QMAKE_RPATHDIR *= $${QWT_INSTALL_LIBS}
contains(QWT_CONFIG, QwtFramework) {
LIBS += -F$${QWT_ROOT}/lib
}
else {
LIBS += -L$${QWT_ROOT}/lib
}
qwtAddLibrary(qwt)
contains(QWT_CONFIG, QwtDll) {
win32 {
DEFINES += QT_DLL QWT_DLL
}
}
}
!contains(QWT_CONFIG, QwtPlot) {
DEFINES += NO_QWT_PLOT
}
!contains(QWT_CONFIG, QwtWidgets) {
DEFINES += NO_QWT_WIDGETS
}
HEADERS += qwt_designer_plugin.h
SOURCES += qwt_designer_plugin.cpp
contains(QWT_CONFIG, QwtPlot) {
HEADERS += qwt_designer_plotdialog.h
SOURCES += qwt_designer_plotdialog.cpp
}
RESOURCES += qwt_designer_plugin.qrc
target.path = $${QWT_INSTALL_PLUGINS}
INSTALLS += target
}
else {
TEMPLATE = subdirs # do nothing
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 992 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 807 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,42 @@
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#include <QLineEdit>
#include <QTabWidget>
#include <QHBoxLayout>
#include <QPushButton>
#include "qwt_designer_plotdialog.h"
using namespace QwtDesignerPlugin;
PlotDialog::PlotDialog( const QString &properties, QWidget *parent ):
QDialog( parent )
{
setWindowTitle( "Plot Properties" );
QLineEdit *lineEdit = new QLineEdit( properties );
connect( lineEdit, SIGNAL( textChanged( const QString & ) ),
SIGNAL( edited( const QString & ) ) );
QTabWidget *tabWidget = new QTabWidget( this );
tabWidget->addTab( lineEdit, "General" );
QPushButton *closeButton = new QPushButton( "Close" );
connect( closeButton, SIGNAL( clicked() ), this, SLOT( accept() ) );
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch( 1 );
buttonLayout->addWidget( closeButton );
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget( tabWidget );
mainLayout->addLayout( buttonLayout );
setLayout( mainLayout );
}

View File

@@ -0,0 +1,31 @@
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#ifndef QWT_DESIGNER_PLOTDIALOG_H
#define QWT_DESIGNER_PLOTDIALOG_H
#include <QDialog>
namespace QwtDesignerPlugin
{
class PlotDialog: public QDialog
{
Q_OBJECT
public:
PlotDialog( const QString &properties, QWidget *parent = NULL );
Q_SIGNALS:
void edited( const QString& );
};
}
#endif

View File

@@ -0,0 +1,570 @@
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#if defined(_MSC_VER) /* MSVC Compiler */
#pragma warning ( disable : 4786 )
#endif
#include <qglobal.h>
#include <qaction.h>
#include <QtPlugin>
#include <QDesignerFormEditorInterface>
#include <QDesignerFormWindowInterface>
#include <QDesignerFormWindowCursorInterface>
#include <QExtensionManager>
#include <QErrorMessage>
#include "qwt_designer_plugin.h"
#ifndef NO_QWT_PLOT
#include "qwt_designer_plotdialog.h"
#include "qwt_plot.h"
#include "qwt_plot_canvas.h"
#include "qwt_scale_widget.h"
#endif
#ifndef NO_QWT_WIDGETS
#include "qwt_counter.h"
#include "qwt_wheel.h"
#include "qwt_thermo.h"
#include "qwt_knob.h"
#include "qwt_slider.h"
#include "qwt_dial.h"
#include "qwt_dial_needle.h"
#include "qwt_analog_clock.h"
#include "qwt_compass.h"
#endif
#include "qwt_text_label.h"
using namespace QwtDesignerPlugin;
CustomWidgetInterface::CustomWidgetInterface( QObject *parent ):
QObject( parent ),
d_isInitialized( false )
{
}
bool CustomWidgetInterface::isContainer() const
{
return false;
}
bool CustomWidgetInterface::isInitialized() const
{
return d_isInitialized;
}
QIcon CustomWidgetInterface::icon() const
{
return d_icon;
}
QString CustomWidgetInterface::codeTemplate() const
{
return d_codeTemplate;
}
QString CustomWidgetInterface::domXml() const
{
return d_domXml;
}
QString CustomWidgetInterface::group() const
{
return "Qwt Widgets";
}
QString CustomWidgetInterface::includeFile() const
{
return d_include;
}
QString CustomWidgetInterface::name() const
{
return d_name;
}
QString CustomWidgetInterface::toolTip() const
{
return d_toolTip;
}
QString CustomWidgetInterface::whatsThis() const
{
return d_whatsThis;
}
void CustomWidgetInterface::initialize(
QDesignerFormEditorInterface *formEditor )
{
if ( d_isInitialized )
return;
QExtensionManager *manager = formEditor->extensionManager();
if ( manager )
{
manager->registerExtensions( new TaskMenuFactory( manager ),
Q_TYPEID( QDesignerTaskMenuExtension ) );
}
d_isInitialized = true;
}
#ifndef NO_QWT_PLOT
PlotInterface::PlotInterface( QObject *parent ):
CustomWidgetInterface( parent )
{
d_name = "QwtPlot";
d_include = "qwt_plot.h";
d_icon = QPixmap( ":/pixmaps/qwtplot.png" );
d_domXml =
"<widget class=\"QwtPlot\" name=\"qwtPlot\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>400</width>\n"
" <height>200</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n";
}
QWidget *PlotInterface::createWidget( QWidget *parent )
{
return new QwtPlot( parent );
}
PlotCanvasInterface::PlotCanvasInterface( QObject *parent ):
CustomWidgetInterface( parent )
{
d_name = "QwtPlotCanvas";
d_include = "qwt_plot_canvas.h";
d_icon = QPixmap( ":/pixmaps/qwtplot.png" );
d_domXml =
"<widget class=\"QwtPlotCanvas\" name=\"qwtPlotCanvas\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>400</width>\n"
" <height>200</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n";
}
QWidget *PlotCanvasInterface::createWidget( QWidget *parent )
{
return new QwtPlotCanvas( qobject_cast<QwtPlot *>( parent ) );
}
#endif
#ifndef NO_QWT_WIDGETS
AnalogClockInterface::AnalogClockInterface( QObject *parent ):
CustomWidgetInterface( parent )
{
d_name = "QwtAnalogClock";
d_include = "qwt_analog_clock.h";
d_icon = QPixmap( ":/pixmaps/qwtanalogclock.png" );
d_domXml =
"<widget class=\"QwtAnalogClock\" name=\"AnalogClock\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>200</width>\n"
" <height>200</height>\n"
" </rect>\n"
" </property>\n"
" <property name=\"lineWidth\">\n"
" <number>4</number>\n"
" </property>\n"
"</widget>\n";
}
QWidget *AnalogClockInterface::createWidget( QWidget *parent )
{
return new QwtAnalogClock( parent );
}
#endif
#ifndef NO_QWT_WIDGETS
CompassInterface::CompassInterface( QObject *parent ):
CustomWidgetInterface( parent )
{
d_name = "QwtCompass";
d_include = "qwt_compass.h";
d_icon = QPixmap( ":/pixmaps/qwtcompass.png" );
d_domXml =
"<widget class=\"QwtCompass\" name=\"Compass\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>200</width>\n"
" <height>200</height>\n"
" </rect>\n"
" </property>\n"
" <property name=\"lineWidth\">\n"
" <number>4</number>\n"
" </property>\n"
"</widget>\n";
}
QWidget *CompassInterface::createWidget( QWidget *parent )
{
QwtCompass *compass = new QwtCompass( parent );
compass->setNeedle( new QwtCompassMagnetNeedle(
QwtCompassMagnetNeedle::TriangleStyle,
compass->palette().color( QPalette::Mid ),
compass->palette().color( QPalette::Dark ) ) );
return compass;
}
#endif
#ifndef NO_QWT_WIDGETS
CounterInterface::CounterInterface( QObject *parent ):
CustomWidgetInterface( parent )
{
d_name = "QwtCounter";
d_include = "qwt_counter.h";
d_icon = QPixmap( ":/pixmaps/qwtcounter.png" );
d_domXml =
"<widget class=\"QwtCounter\" name=\"Counter\">\n"
"</widget>\n";
}
QWidget *CounterInterface::createWidget( QWidget *parent )
{
return new QwtCounter( parent );
}
#endif
#ifndef NO_QWT_WIDGETS
DialInterface::DialInterface( QObject *parent ):
CustomWidgetInterface( parent )
{
d_name = "QwtDial";
d_include = "qwt_dial.h";
d_icon = QPixmap( ":/pixmaps/qwtdial.png" );
d_domXml =
"<widget class=\"QwtDial\" name=\"Dial\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>200</width>\n"
" <height>200</height>\n"
" </rect>\n"
" </property>\n"
" <property name=\"lineWidth\">\n"
" <number>4</number>\n"
" </property>\n"
"</widget>\n";
}
QWidget *DialInterface::createWidget( QWidget *parent )
{
QwtDial *dial = new QwtDial( parent );
dial->setNeedle( new QwtDialSimpleNeedle(
QwtDialSimpleNeedle::Arrow, true,
dial->palette().color( QPalette::Dark ),
dial->palette().color( QPalette::Mid ) ) );
return dial;
}
#endif
#ifndef NO_QWT_WIDGETS
KnobInterface::KnobInterface( QObject *parent ):
CustomWidgetInterface( parent )
{
d_name = "QwtKnob";
d_include = "qwt_knob.h";
d_icon = QPixmap( ":/pixmaps/qwtknob.png" );
d_domXml =
"<widget class=\"QwtKnob\" name=\"Knob\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>150</width>\n"
" <height>150</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n";
}
QWidget *KnobInterface::createWidget( QWidget *parent )
{
return new QwtKnob( parent );
}
#endif
#ifndef NO_QWT_PLOT
ScaleWidgetInterface::ScaleWidgetInterface( QObject *parent ):
CustomWidgetInterface( parent )
{
d_name = "QwtScaleWidget";
d_include = "qwt_scale_widget.h";
d_icon = QPixmap( ":/pixmaps/qwtscale.png" );
d_domXml =
"<widget class=\"QwtScaleWidget\" name=\"ScaleWidget\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>60</width>\n"
" <height>250</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n";
}
QWidget *ScaleWidgetInterface::createWidget( QWidget *parent )
{
return new QwtScaleWidget( QwtScaleDraw::LeftScale, parent );
}
#endif
#ifndef NO_QWT_WIDGETS
SliderInterface::SliderInterface( QObject *parent ):
CustomWidgetInterface( parent )
{
d_name = "QwtSlider";
d_include = "qwt_slider.h";
d_icon = QPixmap( ":/pixmaps/qwtslider.png" );
d_domXml =
"<widget class=\"QwtSlider\" name=\"Slider\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>60</width>\n"
" <height>250</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n";
}
QWidget *SliderInterface::createWidget( QWidget *parent )
{
return new QwtSlider( parent );
}
#endif
TextLabelInterface::TextLabelInterface( QObject *parent ):
CustomWidgetInterface( parent )
{
d_name = "QwtTextLabel";
d_include = "qwt_text_label.h";
d_icon = QPixmap( ":/pixmaps/qwtwidget.png" );
d_domXml =
"<widget class=\"QwtTextLabel\" name=\"TextLabel\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>20</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n";
}
QWidget *TextLabelInterface::createWidget( QWidget *parent )
{
return new QwtTextLabel( QwtText( "Label" ), parent );
}
#ifndef NO_QWT_WIDGETS
ThermoInterface::ThermoInterface( QObject *parent ):
CustomWidgetInterface( parent )
{
d_name = "QwtThermo";
d_include = "qwt_thermo.h";
d_icon = QPixmap( ":/pixmaps/qwtthermo.png" );
d_domXml =
"<widget class=\"QwtThermo\" name=\"Thermo\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>60</width>\n"
" <height>250</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n";
}
QWidget *ThermoInterface::createWidget( QWidget *parent )
{
return new QwtThermo( parent );
}
#endif
#ifndef NO_QWT_WIDGETS
WheelInterface::WheelInterface( QObject *parent ):
CustomWidgetInterface( parent )
{
d_name = "QwtWheel";
d_include = "qwt_wheel.h";
d_icon = QPixmap( ":/pixmaps/qwtwheel.png" );
d_domXml =
"<widget class=\"QwtWheel\" name=\"Wheel\">\n"
"</widget>\n";
}
QWidget *WheelInterface::createWidget( QWidget *parent )
{
return new QwtWheel( parent );
}
#endif
CustomWidgetCollectionInterface::CustomWidgetCollectionInterface(
QObject *parent ):
QObject( parent )
{
#ifndef NO_QWT_PLOT
d_plugins.append( new PlotInterface( this ) );
#if 0
// better not: the designer crashes TODO ..
d_plugins.append( new PlotCanvasInterface( this ) );
#endif
d_plugins.append( new ScaleWidgetInterface( this ) );
#endif
#ifndef NO_QWT_WIDGETS
d_plugins.append( new AnalogClockInterface( this ) );
d_plugins.append( new CompassInterface( this ) );
d_plugins.append( new CounterInterface( this ) );
d_plugins.append( new DialInterface( this ) );
d_plugins.append( new KnobInterface( this ) );
d_plugins.append( new SliderInterface( this ) );
d_plugins.append( new ThermoInterface( this ) );
d_plugins.append( new WheelInterface( this ) );
#endif
d_plugins.append( new TextLabelInterface( this ) );
}
QList<QDesignerCustomWidgetInterface*>
CustomWidgetCollectionInterface::customWidgets( void ) const
{
return d_plugins;
}
TaskMenuFactory::TaskMenuFactory( QExtensionManager *parent ):
QExtensionFactory( parent )
{
}
QObject *TaskMenuFactory::createExtension(
QObject *object, const QString &iid, QObject *parent ) const
{
if ( iid == Q_TYPEID( QDesignerTaskMenuExtension ) )
{
#ifndef NO_QWT_PLOT
if ( QwtPlot *plot = qobject_cast<QwtPlot*>( object ) )
return new TaskMenuExtension( plot, parent );
#endif
#ifndef NO_QWT_WIDGETS
if ( QwtDial *dial = qobject_cast<QwtDial*>( object ) )
return new TaskMenuExtension( dial, parent );
#endif
}
return QExtensionFactory::createExtension( object, iid, parent );
}
TaskMenuExtension::TaskMenuExtension( QWidget *widget, QObject *parent ):
QObject( parent ),
d_widget( widget )
{
d_editAction = new QAction( tr( "Edit Qwt Attributes ..." ), this );
connect( d_editAction, SIGNAL( triggered() ),
this, SLOT( editProperties() ) );
}
QList<QAction *> TaskMenuExtension::taskActions() const
{
QList<QAction *> list;
list.append( d_editAction );
return list;
}
QAction *TaskMenuExtension::preferredEditAction() const
{
return d_editAction;
}
void TaskMenuExtension::editProperties()
{
const QVariant v = d_widget->property( "propertiesDocument" );
if ( v.type() != QVariant::String )
return;
#ifndef NO_QWT_PLOT
QString properties = v.toString();
if ( qobject_cast<QwtPlot*>( d_widget ) )
{
PlotDialog dialog( properties );
connect( &dialog, SIGNAL( edited( const QString& ) ),
SLOT( applyProperties( const QString & ) ) );
( void )dialog.exec();
return;
}
#endif
static QErrorMessage *errorMessage = NULL;
if ( errorMessage == NULL )
errorMessage = new QErrorMessage();
errorMessage->showMessage( "Not implemented yet." );
}
void TaskMenuExtension::applyProperties( const QString &properties )
{
QDesignerFormWindowInterface *formWindow =
QDesignerFormWindowInterface::findFormWindow( d_widget );
if ( formWindow && formWindow->cursor() )
formWindow->cursor()->setProperty( "propertiesDocument", properties );
}
#if QT_VERSION < 0x050000
Q_EXPORT_PLUGIN2( QwtDesignerPlugin, CustomWidgetCollectionInterface )
#endif

View File

@@ -0,0 +1,248 @@
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#ifndef QWT_DESIGNER_PLUGIN_H
#define QWT_DESIGNER_PLUGIN_H
#include <QDesignerCustomWidgetInterface>
#include <QDesignerTaskMenuExtension>
#include <QExtensionFactory>
namespace QwtDesignerPlugin
{
class CustomWidgetInterface: public QObject,
public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
CustomWidgetInterface( QObject *parent );
virtual bool isContainer() const;
virtual bool isInitialized() const;
virtual QIcon icon() const;
virtual QString codeTemplate() const;
virtual QString domXml() const;
virtual QString group() const;
virtual QString includeFile() const;
virtual QString name() const;
virtual QString toolTip() const;
virtual QString whatsThis() const;
virtual void initialize( QDesignerFormEditorInterface * );
protected:
QString d_name;
QString d_include;
QString d_toolTip;
QString d_whatsThis;
QString d_domXml;
QString d_codeTemplate;
QIcon d_icon;
private:
bool d_isInitialized;
};
class CustomWidgetCollectionInterface: public QObject,
public QDesignerCustomWidgetCollectionInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetCollectionInterface )
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetCollectionInterface" )
#endif
public:
CustomWidgetCollectionInterface( QObject *parent = NULL );
virtual QList<QDesignerCustomWidgetInterface*> customWidgets() const;
private:
QList<QDesignerCustomWidgetInterface*> d_plugins;
};
#ifndef NO_QWT_PLOT
class PlotInterface: public CustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
PlotInterface( QObject *parent );
virtual QWidget *createWidget( QWidget *parent );
};
class PlotCanvasInterface: public CustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
PlotCanvasInterface( QObject *parent );
virtual QWidget *createWidget( QWidget *parent );
};
#endif
#ifndef NO_QWT_WIDGETS
class AnalogClockInterface: public CustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
AnalogClockInterface( QObject *parent );
virtual QWidget *createWidget( QWidget *parent );
};
#endif
#ifndef NO_QWT_WIDGETS
class CompassInterface: public CustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
CompassInterface( QObject *parent );
virtual QWidget *createWidget( QWidget *parent );
};
#endif
#ifndef NO_QWT_WIDGETS
class CounterInterface: public CustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
CounterInterface( QObject *parent );
virtual QWidget *createWidget( QWidget *parent );
};
#endif
#ifndef NO_QWT_WIDGETS
class DialInterface: public CustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
DialInterface( QObject *parent );
virtual QWidget *createWidget( QWidget *parent );
};
#endif
#ifndef NO_QWT_WIDGETS
class KnobInterface: public CustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
KnobInterface( QObject *parent );
virtual QWidget *createWidget( QWidget *parent );
};
#endif
#ifndef NO_QWT_PLOT
class ScaleWidgetInterface: public CustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
ScaleWidgetInterface( QObject *parent );
virtual QWidget *createWidget( QWidget *parent );
};
#endif
#ifndef NO_QWT_WIDGETS
class SliderInterface: public CustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
SliderInterface( QObject *parent );
virtual QWidget *createWidget( QWidget *parent );
};
#endif
class TextLabelInterface: public CustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
TextLabelInterface( QObject *parent );
virtual QWidget *createWidget( QWidget *parent );
};
#ifndef NO_QWT_WIDGETS
class ThermoInterface: public CustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
ThermoInterface( QObject *parent );
virtual QWidget *createWidget( QWidget *parent );
};
#endif
#ifndef NO_QWT_WIDGETS
class WheelInterface: public CustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES( QDesignerCustomWidgetInterface )
public:
WheelInterface( QObject *parent );
virtual QWidget *createWidget( QWidget *parent );
};
#endif
class TaskMenuFactory: public QExtensionFactory
{
Q_OBJECT
public:
TaskMenuFactory( QExtensionManager *parent = 0 );
protected:
QObject *createExtension( QObject *object,
const QString &iid, QObject *parent ) const;
};
class TaskMenuExtension: public QObject,
public QDesignerTaskMenuExtension
{
Q_OBJECT
Q_INTERFACES( QDesignerTaskMenuExtension )
public:
TaskMenuExtension( QWidget *widget, QObject *parent );
QAction *preferredEditAction() const;
QList<QAction *> taskActions() const;
private Q_SLOTS:
void editProperties();
void applyProperties( const QString & );
private:
QAction *d_editAction;
QWidget *d_widget;
};
};
#endif

View File

@@ -0,0 +1,15 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>pixmaps/qwtplot.png</file>
<file>pixmaps/qwtanalogclock.png</file>
<file>pixmaps/qwtcounter.png</file>
<file>pixmaps/qwtcompass.png</file>
<file>pixmaps/qwtdial.png</file>
<file>pixmaps/qwtknob.png</file>
<file>pixmaps/qwtscale.png</file>
<file>pixmaps/qwtslider.png</file>
<file>pixmaps/qwtthermo.png</file>
<file>pixmaps/qwtwheel.png</file>
<file>pixmaps/qwtwidget.png</file>
</qresource>
</RCC>

1799
qwt/doc/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

8
qwt/doc/articles/TODO Normal file
View File

@@ -0,0 +1,8 @@
1) Installation guides
2) QwtSeriesData + QAbstractModel
3) Navigation
4) Scales
5) Alive plots + sampling threads
6) Exporting + printing plots
7) Plot Items
8) Raster items

306
qwt/doc/changes.dox Normal file
View File

@@ -0,0 +1,306 @@
/*!
\page qwtchangelog What's new in Qwt 6.1
\tableofcontents
\section ITEMS New plot items
- QwtPlotBarChart\n
Bar chart, see "examples/distrowatch"
- QwtPlotMultiBarChart\n
Chart of grouped bars - stacked or aligned side by side.
See "examples/barchart"
- QwtPlotTradingCurve\n
Candlestick or OHLC charts typically used to describe
price movements over time. See "examples/stockchart"
- QwtPlotShapeItem\n
A plot item to display rectangles, circles, polygons and all
other type of shapes ( built from intersections or unifications ),
that can be expressed by a QPainterPath. See "examples/itemeditor"
- QwtPlotLegendItem\n
A legend on the plot canvas. See "examples/legends"
- QwtPlotZoneItem\n
A horizontal or vertical section
- QwtPlotTextLabel\n
In opposite to a QwtPlotMarker the text is not aligned to a plot coordinate
but according to the geometry of the canvas ( f.e top/centered for a title ).
See "playground/curvetracker".
\section SCALES Scales beyond linear and logarithmic transformations
QwtScaleTransformation has been replaced by QwtTransform and its derived classes:
- QwtTransform
- QwtNullTransform
- QwtLogTransform
- QwtPowerTransform
Individual transformations ( f.e. different scaling for special sections )
can be implemented by overloading QwtTransform ( see playground/scaleengine ).
QwtLinearScaleEngine and QwtLogScaleEngine are not limited to
base 10 anymore.
\subsection DATETIME Datetime scales
A set of a new classes for displaying datetime values:
- QwtDate\n
A collection of methods to convert between QDateTime and doubles
- QwtDateScaleEngine\n
A scale engine that aligns and finds ticks in terms of datetime units.
- QwtDateScaleDraw\n
A scale draw mapping values to datetime strings.
Scales for Qt::UTC and Qt::LocalTime are supported.
\section CONTROLS Redesign of the dial and meter widgets
Many parts of the class design of the dial and meter widgets were left over
from the 90s ( Qwt 0.2, Qt 1.1 ).
The derivation tree is simpler and more logical:
- QwtAbstractScale is a QWidget
- QwtAbstractSlider is a QwtAbstractScale.
( for sliders without scales QAbstractSlider should be the base class )
- QwtThermo is also a QwtAbstractScale
- QwtDial, QwtKnob, QwtSlider are derived from QwtAbstractSlider
- QwtCounter is derived from QWidget
QwtDoubleRange has been removed.
All classes use the terminology known from QAbstractSlider - as far as possible.
The extended \ref SCALES "system for scales" is completely supported.
\section OPENGL Basic support for an OpenGL plot canvas
QwtPlotGLCanvas offers the option to draw plot items using an
OpenGL paint engine ( QPaintEngine::OpenGL/OpenGL2 ),
This is not what could be implemented with native OpenGL,
but it offers hardware acceleration in environments,
where the raster paint engine is the only option.
( f.e Qt4/Windows, or Qt5 on all platforms ).
QwtPlotGLCanvas is in an experimental state and is not recommended for average
use cases.
\section LEGEND A new system for plot legends
QwtLegend has been decoupled from QwtPlot and can be replaced by
application specific implementations. Plot items and the legend
exchange the information using QwtLegendData.
QwtPlotLegendItem is a new plot item that displays a legend on the
plot canvas.
The following examples demonstrate how to use the new system:
- examples/legends\n
shows how to use the new legend system
- examples/stockchart\n
implementats a QTreeView with checkable items as legend
\section GRAPHIC Off-screen paint device for vector graphics
QwtGraphic can be copied like QImage or QPixmap but is scalable like QSvgGenerator.
It is implemented as a record/replay paint device like QPicture.
\section OVERLAY QwtWidgetOverlay
QwtWidgetOverlay is a base class for implementing widget overlays - primarily
used for use cases like graphical editors or running cursors for the plot canvas.
The following examples show how to use overlays:
- examples/itemeditor
- examples/curvetracker
QwtPicker ( -> QwtPlotPicker, QwtPlotZoomer ) internally uses
QwtWidgetOverlay now, making it easier to implement individual rubber bands.
\section SYMBOL QwtSymbol
New symbol types have been introduced:
- QwtSymbol::Path
- QwtSymbol::Pixmap
- QwtSymbol::Graphic
- QwtSymbol::SvgDocument
QwtSymbol autodetect the most performant paint strategy for a paint device
what is in most situations using a QPixmap cache.
QwtSymbol::setPinPoint() allows to align the symbol individually, f.e to the position
of the peak of an arrow.
\section PLOTCURVE QwtPlotCurve
Some optimizations that got lost with introducing the floating point
based render code with Qwt 6.0 have been reenabled. Other specific optimizations
have been added.
New paint attributes:
- QwtPlotCurve::FilterPoints
- QwtPlotCurve::MinimizeMemory
- QwtPlotCurve::ImageBuffer
QwtPlotCurve::CacheSymbols has been removed, as caching is implemented
in QwtSymbol now.
QwtPlotCurve::drawLines(), QwtPlotCurve::drawDots(),
QwtPlotCurve::drawSteps() and QwtPlotCurve::drawSticks() are virtual now.
\section PLOT QwtPlot
A footer similar to a title has been added.
QwtPlot::ExternalLegend is obsolete with the
new \ref LEGEND "system for legends". The signals
QwtPlot::legendClicked(), QwtPlot::legendChecked() have been
removed. Applications need to connect to QwtLegend::clicked()
and QwtLegend::checked().
To support using an OpenGL canvas QwtPlot::setCanvas has been added.
This has 2 important implications for the application code:
- QwtPlot::canvas() returns QWidget and needs to be casted, when
using methods of QwtPlotCanvas.
- QwtPlotCanvas can be created and assigned in application code,
what makes it possible to derive and overload methods.
The initialization of a plot canvas with Qwt 6.1 will probably look like
this:
\code
QwtPlotCanvas* canvas = new QwtPlotCanvas();
canvas->setXY( ... );
...
plot->setCanvas( canvas );
\endcode
To have a consistent API QwtPlot::setPlotLayout() has been added,
\section OTHER Other
\subsection SCALEDIV QwtScaleDiv
The following methods have been added:
- QwtScaleDiv::inverted()
- QwtScaleDiv::bounded()
- QwtScaleDiv::isEmpty()
- QwtScaleDiv::isIncreasing()
- QDebug operator
The following methods have been removed:
- QwtScaleDiv::isValid(), QwtScaleDiv::invalidate()\n
The valid state was left over from early Qwt versions indicating
a state of the autoscaler.
\subsection SCALEENGINE QwtScaleEngine
The following methods have been added:
- QwtScaleEngine::setBase()
- QwtScaleEngine::setTransformation()
\subsection PLOTLAYOUT QwtPlotLayout
The following flags have been added:
- QwtPlotLayout::IgnoreTitle
- QwtPlotLayout::IgnoreFooter
- QwtPlotLayout::setAlignCanvasToScale()
\subsection PLOTCANVAS QwtPlotCanvas
Rounded borders ( like with style sheets ) can configured
using QwtPlotCanvas::setBorderRadius();
\subsection OTHERS Other changes
- QwtWeedingCurveFitter\n
QwtWeedingCurveFitter::setChunkSize() has been added, with drastic
performance improvements for huge sets of points.
- QwtPlotRenderer
The frame of the plot canvas can be rendered, what makes the result
even closer to WYSWYG. QwtPlotRenderer::exportTo() has been added.
- QwtSystemClock
For Qt >= 4.9 QwtSystemClock uses QElapsedTimer internally. As it doesn't
support a similar feature, QwtSystemClock::precision() has been removed.
- QwtPlotAbstractSeriesItem\n
QwtPlotAbstractSeriesItem has been split into QwtPlotSeriesItem
and QwtPlotAbstractSeriesStore.
- QwtText\n
A metatype declaration has been added, so that QwtText can be used
with QVariant.
- QwtEventPattern, QwtPanner, QwtMagnifier\n
Forgotten Qt3 leftovers have been fixed: int -> Qt::KeyboardModifiers
- QPen Qt5/Qt4 incompatibility
The default pen width for Qt5 is 1, what makes it a non cosmetic.
To hide this nasty incompatibility several setPen() methods have been added
the build pens with a width 0. See QPen::isCosmetic(),
- qwtUpperSampleIndex()\n
A binary search algorithm for sorted samples
- QwtMatrixRasterData
QwtMatrixRasterData::setValue() has been added
- QwtPicker
QwtPicker::rubberBandWidget(), QwtPicker::trackerWidget() have been replaced by
QwtPicker::rubberBandOverlay(), QwtPicker::trackerOverlay().
QwtPicker::rubberBandMask() has been added. QwtPicker::pickRect() has been
replaced by QwtPicker::pickArea()
- QwtPlotItem
QwtPlotItem::ItemInterest has been added. QwtPlotItem::setRenderThreadCount()
was shifted from QwtPlotRasterItem.
- ...
\section CLASSES Summary of the new classes
- QwtAbstractLegend
- QwtDate
- QwtDateScaleDraw
- QwtDateScaleEngine
- QwtGraphic
- QwtLegendData
- QwtLegendLabel
- QwtPainterCommand
- QwtPixelMatrix
- QwtPlotAbstractBarChart
- QwtPlotBarChart
- QwtPlotMultiBarChart
- QwtPlotGLCanvas
- QwtPlotLegendItem
- QwtPlotShapeItem
- QwtPlotTextLabel
- QwtPlotTradingCurve
- QwtPlotZoneItem
- QwtPointData
- QwtPointMapper
- QwtTransform, QwtNullTransform, QwtLogTransform, QwtPowerTransform
- QwtWidgetOverlay
*/

22
qwt/doc/doc.pro Normal file
View File

@@ -0,0 +1,22 @@
################################################################
# Qwt Widget Library
# Copyright (C) 1997 Josef Wilgen
# Copyright (C) 2002 Uwe Rathmann
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the Qwt License, Version 1.0
################################################################
# qmake project file for installing the documentation
QWT_ROOT = $${PWD}/..
include( $${QWT_ROOT}/qwtconfig.pri )
TEMPLATE = subdirs
doc.files = $${QWT_ROOT}/doc/html
unix:doc.files += $${QWT_ROOT}/doc/man
doc.path = $${QWT_INSTALL_DOCS}
INSTALLS = doc

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
qwt/doc/images/cpuplot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
qwt/doc/images/curves.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
qwt/doc/images/dials1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
qwt/doc/images/dials2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
qwt/doc/images/graph.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
qwt/doc/images/knob.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
qwt/doc/images/plot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
qwt/doc/images/radio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
qwt/doc/images/sinus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
qwt/doc/images/sliders.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
qwt/doc/images/sysinfo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

305
qwt/doc/install.dox Normal file
View File

@@ -0,0 +1,305 @@
/*!
\page qwtinstall Installing Qwt
\tableofcontents
\section DOWNLOAD Download
Stable Qwt releases are available from the
Qwt <a href="http://sourceforge.net/projects/qwt/files/qwt">project page</a>.
Qwt-$(QWTVERSION) consists of 4 files:
- qwt-$(QWTVERSION).zip\n
Zip file with the Qwt sources and the html documentation for Windows
- qwt-$(QWTVERSION).tar.bz2\n
Compressed tar file with the Qwt sources and the html documentation
for UNIX systems ( Linux, Mac, ... )
- qwt-$(QWTVERSION).pdf\n
Qwt documentation as PDF document.
- qwt-$(QWTVERSION).qch\n
Qwt documentation as Qt Compressed Help document, that can be loaded into
the Qt Assistant or Creator. In the Qt Creator context sensitive help will be
available like for Qt classes.
Precompiled Qwt Designer plugins, that are compatible with some binary packages
of the Qt Creator:
- qwtdesigner-$(QWTVERSION)-*.zip
\section INSTALL Installing Qwt
Beside headers, libraries and the html version of the class documentation a proper
Qwt installation contains a Designer plugin and a Qwt features file for building
applications using Qwt.
All files will be copied to an installation directory, that is configurable
by editing qwtconfig.pri. Its default settings is:
- Windows\n
C:\\Qwt-$(QWTVERSION)
- Unix like systems\n
/usr/local/qwt-$(QWTVERSION)
For the rest of the document this install path will be written as <i>${QWT_ROOT}</i>
and needs to be replaced by the real path in all commands below.
It is not unlikely, to have more than one installation of Qwt
on the same system. F.e for using the Qwt Designer plugin in the Qt Creator
a version of Qwt is necessary with the same Qt and compiler combination, that had
been used for building the Qt Creator ( see "Help->About Qt Creator ..." ).
Installing Qwt is done in 3 steps, that are quite common on UNIX systems.
-# Configuration\n
In the configuration step all parameters are set to control how
to build and install Qwt
-# Build\n
In the build step binaries are built from the source files.
-# Installation\n
The installation copies and rearranges all files that are necessary to build
Qwt applications to a target directory.
The installation doesn't modify the system beside copying files to a
directory in a proper way. After removing build and installation directories the
system is in the same state as it was before.
\subsection CONFIGSUBSECTION Configuration
Configuring Qwt has to be done by editing the Project files used for building:
- qwtbuild.pri\n
qwtbuild.pri contains settings for how to build Qwt. All settings
of this file are only for building Qwt itself and doesn't have an impact
on how an application using Qwt is built. Usually its default settings
doesn't need to be modified.
- qwtconfig.pri\n
qwtconfig.pri defines what modules of Qwt will be built and where to
install them. qwtconfig.pri gets installed together with the Qwt features
file qwt.prf and all its settings are known to project files for building
Qwt applications.
In qwtconfig.pri the meaning of each option is explained in detail - it's worth
reading it before running into problems later.
\subsection BUILDSUBSECTION Build and installation
The Qt Creator is a graphical frontend for calling qmake/make and - technically -
it could be used for building and installing Qwt. But as this way requires a lot
more understanding of details the following step by step instructions are for
the easier way using the command line.
\subsubsection qwtinstall-unix Unix-like systems
The first step before creating the Makefile is to check that the correct version
of qmake is used. F.e. on older Linux distribution you often find a Qt3 qmake
and in the path.
The default setting of qmake is to generate a makefile that builds Qwt for the
same environment where the version of qmake has been built for.
So creating a makefile usually means something like:
\code
cd qwt-$(QWTVERSION)
/usr/local/Qt-5.0.1/bin/qmake qwt.pro
\endcode
The generated Makefile includes all paths related to the chosen Qt version
and the next step is:
\code
make
\endcode
( On multicore systems you can speed up building the Qwt libraries with running several
jobs simultaneously: f.e. "make -j4" on a dual core. )
Finally you have to install everything below the directories you have specified
in qwtconfig.pri. Usually this is one of the system directories ( /usr/local, /opt, ... )
where you don't have write permission and then the installation
needs to be done as root:
\code
sudo make install
\endcode
( On systems where sudo is not supported you can do the same with: su -c "make install" )
\subsubsection qwtinstall-windows Windows
Qt packages offer a command line interface, that can be found in the Qt application
menu: f.e "All Programs -> Qt -> Command Prompt". It is not mandatory to use it, but
probably the easiest way as it offers an environment, where everything is
initialized for a version of Qt ( f.e qmake is in the PATH ).
Creating a makefile usually means something like:
\code
cd qwt-$(QWTVERSION)
qmake qwt.pro
\endcode
The generated makefile includes all paths related to the chosen Qt version.
\paragraph qwtinstall-windows-mingw MinGW
For MinGW builds the name of the make tool is "mingw32-make"
\code
mingw32-make
\endcode
( On multicore systems you can speed up building the Qwt libraries with running several
jobs simultaneously: "mingw32-make -j" )
Finally you have to install everything below the directories you have specified
in qwtconfig.pri.
\code
mingw32-make install
\endcode
\paragraph qwtinstall-windows-msvc MSVC
For MSVC builds the name of the make tool is "nmake". Alternatively
it is possible to use "jom" ( http://qt-project.org/wiki/jom ),
that is usually included in a Qt Creator package.
\code
nmake
\endcode
Finally you have to install everything below the directories you have specified
in qwtconfig.pri.
\code
nmake install
\endcode
\section INTEGRATION Qwt and the Qt tool chain
\subsection USEPLUGIN Designer plugin
The Designer plugin and the corresponding Qwt library ( if the plugin has not
been built self containing ) have to be compatible with Qt version of the application
loading it ( usually the Qt Creator ) - what is often a different version of the
Qt libraries you want to build your application with. F.e on Windows the Qt Creator
is usually built with a MSVC compiler - even if included in a MinGW package !
To help Qt Designer/Creator with locating the Qwt Designer plugin
you have to set the environment variable QT_PLUGIN_PATH, modify qt.conf -
or install the plugin to one of the application default paths.
The Qt documentation explains all options in detail:
- http://qt-project.org/doc/qt-5.0/qtdoc/deployment-plugins.html
- http://qt-project.org/doc/qtcreator-2.7/adding-plugins.html.
F.e. on a Linux system you could add the following lines to .bashrc:
\code
QT_PLUGIN_PATH="${QWT_ROOT}/plugins:$QT_PLUGIN_PATH"
export QT_PLUGIN_PATH
\endcode
When the plugin has not been built including the Qwt library
( see QwtDesignerSelfContained in qwtconfig.pri )
the Qt Designer/Creator also needs to locate the Qwt libraries. On Unix systems the
path to the installed library is compiled into the plugin ( see rpath, ldd ), but on
Windows the Qt Creator needs to be configured ( ( \ref RUNAPP ) in the same way as for
any application using Qwt.
In case of problems the diagnostics of Qt Creator and Designer are very limited
( usually none ), but setting the environment variable QT_DEBUG_PLUGINS might help.
In the Qt Creator it is possible to check which plugins were loaded
successfully and for certain problems it also lists those that were recognized
but failed ( <i>Tools > Form Editor > About Qt Designer Plugins</i> ).
\subsection USEHELP Online Help
The Qwt class documentation can be loaded into the Qt Creator:
- open the settings dialog from the <i>Tools->Options</i> menu
- raise the tab "Help->Documentation".
- press the <i>Add</i> button and select qwt-$(QWTVERSION).qch.
Now the context sensitive help ( <i>F1</i> ) works for Qwt classes.
For browsing the documentation in the Qt Assistant:
- open the settings dialog from the <i>Edit->Preferences</i> menu
- raise the tab <i>Documentation</i>.
- press the <i>Add</i> button and select qwt-$(QWTVERSION).qch.
\section COMPILEANDLINKAPP Building a Qwt application
All flags and settings that are necessary to compile and link an application using Qwt
can be found in the file ${QWT_ROOT}/features/qwt.prf.
When using qmake it can included from the application project file in 2 different ways:
- Adding Qwt as qmake feature\n\n
When using the qmake feature mechanism you can bind a special version
of qmake to a special installation of Qwt without having to add
this dependency to the application project.
How to add Qwt as feature is documented in the
<a href="https://qt-project.org/doc/qt-5.0/qtdoc/qmake-advanced-usage.html#adding-new-configuration-features">qmake docs</a>.
After adding Qwt as a feature f.e on Linux as a persistent property ....
@code
qmake -set QMAKEFEATURES ${QWT_ROOT}/features
@endcode
.. the following line can be added to the application project file:
\code
CONFIG += qwt
\endcode
- Including qwt.prf in the application project file\n\n
Instead of using qwt.prf as qmake feature it can be included from
the application project file:\n\n
\code
include ( ${QWT_ROOT}/features/qwt.prf )
\endcode \n
The advantage of using a direct include is, that all settings of qwt.prf
are known to the application project file ( qmake features are included after the
application project file has been parsed ) and it can be implemented depending on -
f.e. settings made in qwtconfig.pri.
On Unix platforms it is possible to link a runtime path into the executable, so that the
location of the Qwt libraries can be found without having to configure a runtime environment:
- <a href="https://qt-project.org/doc/qt-5.0/qtdoc/qmake-variable-reference.html#qmake-lflags-rpath">QMAKE_LFLAGS_RPATH</a>
- <a href="https://qt-project.org/doc/qt-5.0/qtdoc/qmake-variable-reference.html#qmake-rpath">QMAKE_RPATH</a>
- <a href="https://qt-project.org/doc/qt-5.0/qtdoc/qmake-variable-reference.html#qmake-rpathdir">QMAKE_RPATHDIR</a>
\section RUNAPP Running a Qwt application
When using Qwt as shared library ( DLL ) the
<a href="http://en.wikipedia.org/wiki/Dynamic_linker">dynamic linker</a> has to find
it according to the rules of the operating system.
\subsection RUNWINDOWS Windows
The only reasonable way to configure the runtime environment - without having to copy the
Qwt libraries around - is to modify the PATH variable. F.e. this could be done by adding
the following line to some batch file:
\code
set PATH=%PATH%;${QWT_ROOT}\lib
\endcode
\subsection RUNLINUX GNU/Linux
Read the documentation about:
- <i>ldconfig</i>
- <i>/etc/ld.so.conf</i>
- <i>LD_LIBRARY_PATH</i>
Using the <i>ldd</i> command a configuration can be tested.
*/

153
qwt/doc/qwt.dox Normal file
View File

@@ -0,0 +1,153 @@
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
/*
This file contains NO source code, just some documentation for doxygen to
parse.
*/
/*!
\mainpage Qwt - Qt Widgets for Technical Applications
The Qwt library contains GUI Components and utility classes which are primarily
useful for programs with a technical background. Beside a framework for 2D plots
it provides scales, sliders, dials, compasses, thermometers, wheels and knobs
to control or display values, arrays, or ranges of type double.
\image html plot.png
\if homepage
\section homepage Project page
The official project page is hosted at
<a href="http://qwt.sourceforge.net">sourceforge</a>
\endif
\section license License
Qwt is distributed under the terms of the \ref qwtlicense.
\section platforms Platforms
Qwt 6.1 might be usable in all environments where you find
<a href="https://qt-project.org">Qt</a>.
It is compatible with Qt4 ( >= 4.4 ) and Qt5.
\section changelogonmainpage What's new
Read the \ref qwtchangelog "summary" of the most important changes.
\section screenshotsonmainpage Screenshots
- \ref curvescreenshots\n
- \ref scatterscreenshots\n
- \ref spectrogramscreenshots\n
- \ref histogramscreenshots\n
- \ref controlscreenshots\n
\latexonly Screenshots are only available in the HTML docs.\endlatexonly
\section downloads Downloads
Stable releases or prereleases are available at the Qwt <a href="http://sourceforge.net/projects/qwt/files">project page</a>.
For getting a snapshot with all bugfixes for the latest 5.2 release:
\code svn checkout svn://svn.code.sf.net/p/qwt/code/branches/qwt-5.2 \endcode
For getting a snapshot with all bugfixes for the latest 6.1 release:
\code svn checkout svn://svn.code.sf.net/p/qwt/code/branches/qwt-6.1 \endcode
For getting a development snapshot from the SVN repository:
\code svn checkout svn://svn.code.sf.net/p/qwt/code/trunk/qwt \endcode
\section installonmainpage Installation
Qwt doesn't distribute binary packages, but today all major Linux distributors
offer one. Note, that these packages often don't include the examples.
When no binary packages are available ( f.e. on Windows ) Qwt needs to be
\ref qwtinstall "compiled and installed" on the target system.
\section support Support
- Mailing list\n
For all kind of Qwt related questions use the Qwt <a href="http://sourceforge.net/mail/?group_id=13693">mailing list</a>.\n
If you prefer newsgroups use the mail to news gateway of <a href="http://dir.gmane.org/gmane.comp.graphics.qwt.general">Gmane</a>.
- Forum\n
<a href="http://www.qtcentre.org">Qt Centre</a> is a great resource for Qt
related questions. It has a sub forum, that is dedicated to
Qwt related questions.
- Individual support\n
If you are looking for individual support, or need someone who implements
your Qwt component/application contact support@qwt-project.org. Sending
requests to this address without a good reason for not using public
support channels might be silently ignored.
\section relatedprojects Related Projects
<a href="http://qwtpolar.sourceforge.net">QwtPolar</a>, a polar plot widget.\n
<a href="http://qwtplot3d.sourceforge.net">QwtPlot3D</a>, an OpenGL 3D plot widget.\n
\section donations Donations
Sourceforge offers a <a href="http://sourceforge.net/docman/display_doc.php?docid=20244&group_id=1"> Donation System</a> via PayPal.
You can use it, if you like to <a href="http://sourceforge.net/project/project_donations.php?group_id=13693">support</a> the development of Qwt.
\section credits Credits:
\par Authors:
Uwe Rathmann, Josef Wilgen ( <= Qwt 0.2 )
\par Project admin:
Uwe Rathmann \<rathmann@users.sourceforge.net\>
*/
/*!
\page qwtlicense Qwt License, Version 1.0
\include "COPYING"
*/
/*!
\page curvescreenshots Curve Plots
\image html plot.png
\image html sinus.png
\image html cpuplot.png
\image html graph.png
\image html curves.png
*/
/*!
\page scatterscreenshots Scatter Plot
\image html scatterplot.png
*/
/*!
\page spectrogramscreenshots Spectrogram, Contour Plot
\image html spectrogram1.png
\image html spectrogram2.png
\image html spectrogram3.png
/*!
\page histogramscreenshots Histogram
\image html histogram.png
*/
/*!
\page controlscreenshots Dials, Compasses, Knobs, Wheels, Sliders, Thermos
\image html radio.png
\image html sliders.png
\image html dials1.png
\image html dials2.png
\image html sysinfo.png
*/

155
qwt/doc/tex/plotlayout.tex Normal file
View File

@@ -0,0 +1,155 @@
\begin{tikzpicture}{0pt}{0pt}{500pt}{400pt}
\clip(0pt,400pt) -- (425.118pt,400pt) -- (425.118pt,63.8605pt) -- (0pt,63.8605pt) -- (0pt,400pt);
\color[rgb]{0.501961,0.501961,0.501961}
\fill(0pt,400pt) -- (424.267pt,400pt) -- (424.267pt,64.7008pt) -- (0pt,64.7008pt) -- (0pt,400pt);
\color[rgb]{0.752941,0.752941,0.752941}
\fill(130.086pt,326.89pt) -- (353.698pt,326.89pt) -- (353.698pt,114.281pt) -- (130.086pt,114.281pt) -- (130.086pt,326.89pt);
\color[rgb]{0,0,0}
\pgftext[center, base, at={\pgfpoint{242.317pt}{215.964pt}}]{\fontsize{14}{0}\selectfont{Canvas}}
\color[rgb]{1,1,1}
\fill(68.0188pt,391.597pt) -- (415.765pt,391.597pt) -- (415.765pt,373.109pt) -- (68.0188pt,373.109pt) -- (68.0188pt,391.597pt);
\color[rgb]{0,0,0}
\pgftext[center, base, at={\pgfpoint{242.317pt}{377.311pt}}]{\fontsize{14}{0}\selectfont{\textbf{Title}}}
\color[rgb]{1,1,1}
\fill(8.50235pt,326.89pt) -- (62.9174pt,326.89pt) -- (62.9174pt,114.281pt) -- (8.50235pt,114.281pt) -- (8.50235pt,326.89pt);
\begin{scope}
\clip(8.50235pt,326.89pt) -- (63.7676pt,326.89pt) -- (63.7676pt,305.881pt) -- (8.50235pt,305.881pt) -- (8.50235pt,326.89pt);
\color[rgb]{0,0,0}
\fill(10.2028pt,319.747pt) -- (17.0047pt,319.747pt) -- (17.0047pt,313.024pt) -- (10.2028pt,313.024pt) -- (10.2028pt,319.747pt);
\color[rgb]{0,0,0}
\pgftext[center, base, at={\pgfpoint{39.5359pt}{311.763pt}}]{\fontsize{14}{0}\selectfont{Item 1}}
\end{scope}
\begin{scope}
\clip(8.50235pt,300.839pt) -- (63.7676pt,300.839pt) -- (63.7676pt,279.83pt) -- (8.50235pt,279.83pt) -- (8.50235pt,300.839pt);
\color[rgb]{0,0,0}
\fill(10.2028pt,293.696pt) -- (17.0047pt,293.696pt) -- (17.0047pt,286.973pt) -- (10.2028pt,286.973pt) -- (10.2028pt,293.696pt);
\color[rgb]{0,0,0}
\pgftext[center, base, at={\pgfpoint{39.5359pt}{285.713pt}}]{\fontsize{14}{0}\selectfont{Item 2}}
\end{scope}
\begin{scope}
\color[rgb]{1,1,1}
\fill(68.0188pt,328.57pt) -- (129.236pt,328.57pt) -- (129.236pt,113.441pt) -- (68.0188pt,113.441pt) -- (68.0188pt,328.57pt);
\color[rgb]{0,0,0}
\pgftext[center, base, at={\pgfpoint{80.7724pt}{220.586pt}},rotate=90]{\fontsize{12}{0}\selectfont{\textbf{Axis: yLeft}}}
\pgftext[center, base, at={\pgfpoint{101.603pt}{113.861pt}}]{\fontsize{10}{0}\selectfont{-1,000}}
\pgftext[center, base, at={\pgfpoint{105.854pt}{165.333pt}}]{\fontsize{10}{0}\selectfont{-500}}
\pgftext[center, base, at={\pgfpoint{113.506pt}{216.804pt}}]{\fontsize{10}{0}\selectfont{0}}
\pgftext[center, base, at={\pgfpoint{107.555pt}{268.275pt}}]{\fontsize{10}{0}\selectfont{500}}
\pgftext[center, base, at={\pgfpoint{103.304pt}{319.747pt}}]{\fontsize{10}{0}\selectfont{1,000}}
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,127.727pt) -- (124.134pt,127.727pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,137.811pt) -- (124.134pt,137.811pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,148.736pt) -- (124.134pt,148.736pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,158.82pt) -- (124.134pt,158.82pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,178.988pt) -- (124.134pt,178.988pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,189.913pt) -- (124.134pt,189.913pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,199.997pt) -- (124.134pt,199.997pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,210.081pt) -- (124.134pt,210.081pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,231.09pt) -- (124.134pt,231.09pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,241.174pt) -- (124.134pt,241.174pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,251.258pt) -- (124.134pt,251.258pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,261.342pt) -- (124.134pt,261.342pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,282.351pt) -- (124.134pt,282.351pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,292.435pt) -- (124.134pt,292.435pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,302.52pt) -- (124.134pt,302.52pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,313.444pt) -- (124.134pt,313.444pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,117.643pt) -- (120.733pt,117.643pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,168.904pt) -- (120.733pt,168.904pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,220.165pt) -- (120.733pt,220.165pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,272.267pt) -- (120.733pt,272.267pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,323.528pt) -- (120.733pt,323.528pt);
\draw[line width=0pt, line join=bevel, line cap=rect](127.535pt,323.528pt) -- (127.535pt,117.643pt);
\color[rgb]{1,1,1}
\fill(354.548pt,328.57pt) -- (415.765pt,328.57pt) -- (415.765pt,113.441pt) -- (354.548pt,113.441pt) -- (354.548pt,328.57pt);
\color[rgb]{0,0,0}
\pgftext[center, base, at={\pgfpoint{403.862pt}{220.586pt}},rotate=-90]{\fontsize{12}{0}\selectfont{\textbf{Axis: yRight}}}
\pgftext[center, base, at={\pgfpoint{382.181pt}{113.861pt}}]{\fontsize{10}{0}\selectfont{-1,000}}
\pgftext[center, base, at={\pgfpoint{377.93pt}{165.333pt}}]{\fontsize{10}{0}\selectfont{-500}}
\pgftext[center, base, at={\pgfpoint{370.277pt}{216.804pt}}]{\fontsize{10}{0}\selectfont{0}}
\pgftext[center, base, at={\pgfpoint{376.229pt}{268.275pt}}]{\fontsize{10}{0}\selectfont{500}}
\pgftext[center, base, at={\pgfpoint{380.48pt}{319.747pt}}]{\fontsize{10}{0}\selectfont{1,000}}
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,127.727pt) -- (359.65pt,127.727pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,137.811pt) -- (359.65pt,137.811pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,148.736pt) -- (359.65pt,148.736pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,158.82pt) -- (359.65pt,158.82pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,178.988pt) -- (359.65pt,178.988pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,189.913pt) -- (359.65pt,189.913pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,199.997pt) -- (359.65pt,199.997pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,210.081pt) -- (359.65pt,210.081pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,231.09pt) -- (359.65pt,231.09pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,241.174pt) -- (359.65pt,241.174pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,251.258pt) -- (359.65pt,251.258pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,261.342pt) -- (359.65pt,261.342pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,282.351pt) -- (359.65pt,282.351pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,292.435pt) -- (359.65pt,292.435pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,302.52pt) -- (359.65pt,302.52pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,313.444pt) -- (359.65pt,313.444pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,117.643pt) -- (363.05pt,117.643pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,168.904pt) -- (363.05pt,168.904pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,220.165pt) -- (363.05pt,220.165pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,272.267pt) -- (363.05pt,272.267pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,323.528pt) -- (363.05pt,323.528pt);
\draw[line width=0pt, line join=bevel, line cap=rect](356.249pt,323.528pt) -- (356.249pt,117.643pt);
\color[rgb]{1,1,1}
\fill(118.183pt,113.441pt) -- (363.05pt,113.441pt) -- (363.05pt,73.1043pt) -- (118.183pt,73.1043pt) -- (118.183pt,113.441pt);
\color[rgb]{0,0,0}
\pgftext[center, base, at={\pgfpoint{241.042pt}{76.4657pt}}]{\fontsize{12}{0}\selectfont{\textbf{Axis: xBottom}}}
\pgftext[center, base, at={\pgfpoint{133.487pt}{92.4323pt}}]{\fontsize{10}{0}\selectfont{-1,000}}
\pgftext[center, base, at={\pgfpoint{187.689pt}{92.4323pt}}]{\fontsize{10}{0}\selectfont{-500}}
\pgftext[center, base, at={\pgfpoint{241.892pt}{92.4323pt}}]{\fontsize{10}{0}\selectfont{0}}
\pgftext[center, base, at={\pgfpoint{296.094pt}{92.4323pt}}]{\fontsize{10}{0}\selectfont{500}}
\pgftext[center, base, at={\pgfpoint{350.297pt}{92.4323pt}}]{\fontsize{10}{0}\selectfont{1,000}}
\draw[line width=0pt, line join=bevel, line cap=rect](144.54pt,111.76pt) -- (144.54pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](155.593pt,111.76pt) -- (155.593pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](165.796pt,111.76pt) -- (165.796pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](176.849pt,111.76pt) -- (176.849pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](198.955pt,111.76pt) -- (198.955pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](209.158pt,111.76pt) -- (209.158pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](220.211pt,111.76pt) -- (220.211pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](231.264pt,111.76pt) -- (231.264pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](252.52pt,111.76pt) -- (252.52pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](263.573pt,111.76pt) -- (263.573pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](274.626pt,111.76pt) -- (274.626pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](285.679pt,111.76pt) -- (285.679pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](306.935pt,111.76pt) -- (306.935pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](317.988pt,111.76pt) -- (317.988pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](329.041pt,111.76pt) -- (329.041pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](339.244pt,111.76pt) -- (339.244pt,108.399pt);
\draw[line width=0pt, line join=bevel, line cap=rect](133.487pt,111.76pt) -- (133.487pt,105.038pt);
\draw[line width=0pt, line join=bevel, line cap=rect](187.902pt,111.76pt) -- (187.902pt,105.038pt);
\draw[line width=0pt, line join=bevel, line cap=rect](242.317pt,111.76pt) -- (242.317pt,105.038pt);
\draw[line width=0pt, line join=bevel, line cap=rect](295.882pt,111.76pt) -- (295.882pt,105.038pt);
\draw[line width=0pt, line join=bevel, line cap=rect](350.297pt,111.76pt) -- (350.297pt,105.038pt);
\draw[line width=0pt, line join=bevel, line cap=rect](133.487pt,111.76pt) -- (350.297pt,111.76pt);
\color[rgb]{1,1,1}
\fill(118.183pt,368.067pt) -- (363.05pt,368.067pt) -- (363.05pt,327.73pt) -- (118.183pt,327.73pt) -- (118.183pt,368.067pt);
\color[rgb]{0,0,0}
\pgftext[center, base, at={\pgfpoint{241.042pt}{355.462pt}}]{\fontsize{12}{0}\selectfont{\textbf{Axis: xTop}}}
\pgftext[center, base, at={\pgfpoint{133.487pt}{341.176pt}}]{\fontsize{10}{0}\selectfont{-1,000}}
\pgftext[center, base, at={\pgfpoint{187.689pt}{341.176pt}}]{\fontsize{10}{0}\selectfont{-500}}
\pgftext[center, base, at={\pgfpoint{241.892pt}{341.176pt}}]{\fontsize{10}{0}\selectfont{0}}
\pgftext[center, base, at={\pgfpoint{296.094pt}{341.176pt}}]{\fontsize{10}{0}\selectfont{500}}
\pgftext[center, base, at={\pgfpoint{350.297pt}{341.176pt}}]{\fontsize{10}{0}\selectfont{1,000}}
\draw[line width=0pt, line join=bevel, line cap=rect](144.54pt,329.411pt) -- (144.54pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](155.593pt,329.411pt) -- (155.593pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](165.796pt,329.411pt) -- (165.796pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](176.849pt,329.411pt) -- (176.849pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](198.955pt,329.411pt) -- (198.955pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](209.158pt,329.411pt) -- (209.158pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](220.211pt,329.411pt) -- (220.211pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](231.264pt,329.411pt) -- (231.264pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](252.52pt,329.411pt) -- (252.52pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](263.573pt,329.411pt) -- (263.573pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](274.626pt,329.411pt) -- (274.626pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](285.679pt,329.411pt) -- (285.679pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](306.935pt,329.411pt) -- (306.935pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](317.988pt,329.411pt) -- (317.988pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](329.041pt,329.411pt) -- (329.041pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](339.244pt,329.411pt) -- (339.244pt,332.772pt);
\draw[line width=0pt, line join=bevel, line cap=rect](133.487pt,329.411pt) -- (133.487pt,336.133pt);
\draw[line width=0pt, line join=bevel, line cap=rect](187.902pt,329.411pt) -- (187.902pt,336.133pt);
\draw[line width=0pt, line join=bevel, line cap=rect](242.317pt,329.411pt) -- (242.317pt,336.133pt);
\draw[line width=0pt, line join=bevel, line cap=rect](295.882pt,329.411pt) -- (295.882pt,336.133pt);
\draw[line width=0pt, line join=bevel, line cap=rect](350.297pt,329.411pt) -- (350.297pt,336.133pt);
\draw[line width=0pt, line join=bevel, line cap=rect](133.487pt,329.411pt) -- (350.297pt,329.411pt);
\end{scope}
\end{tikzpicture}

234
qwt/doc/tex/qwtplot.tex Normal file
View File

@@ -0,0 +1,234 @@
\documentclass[12pt,a4paper]{book}
\usepackage[latin1]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{makeidx}
\usepackage{pdfpages}
\usepackage{tikz}
%\usepackage{fullpage}
\usepackage[left=1cm,right=2cm,top=2cm,footskip=1.5cm,bottom=1cm]{geometry}
\usepackage{listings}
\usepackage{color}
%\setlength{\parskip}{\baselineskip}
\setlength{\parindent}{0pt}
\definecolor{lightgray}{gray}{0.97}
\lstset{frame=single}
\lstset{framesep=5pt}
\lstset{language=C++}
\lstset{keywordstyle=\color{black}\bfseries\emph}
\lstset{backgroundcolor=\color{lightgray}}
\author{Uwe Rathmann}
\title{Qwt Plot Framework}
\begin{document}
\maketitle
\pagestyle{headings}
\tableofcontents
\chapter{Introduction}
Introduction bla bla
\chapter{Plot Widget}
\section{Composite Widget Architecture}
QwtPlot is a composite widget, that contains a QwtPlotCanvas,
4 QwtScaleWidgets, a QwtTextWidget for the title and an optional QwtLegend.
All widgets might be hidden or visible depending on the current configuration
of the plot widget. Many attributes of a plot are in fact
attributes of the internal child widgets,
\\
\\
QwtPlot has its own layout engine, that is implemented as QwtPlotLayout.
The following picture shows a layout of a plot widget, where all internal widgets are visible.
\begin{center}
\input{plotlayout}
\end{center}
\bigskip
\begin{center}
\input{plotlayout}
\end{center}
The composite widget architecture\footnote{Subject of redesign}
of QwtPlot has some consequences for the programming interface:
\begin{itemize}
\item Attributes\\
Most attributes of child widgets or the layout object can't be
changed using QwtPlot methods. Instead the application code has to
use a getter method for the child and access it directly.
Beside making the programming interface less obvious it has the effect,
that the plot can't be configured in the designer ( or creator )
\footnote{A proof of concept has been made how to embed a special
editor for QwtPlot into the designer and how to pass the edited
properties using QwtPlot::applyProperties() - but it was never implemented.}.
\item Events\\
Overloading event callbacks of QwtPlot has no effect when an event is posted to a child widget. When the application wants to implement a specific event handling it needs to use a technique called event filtering.
\end{itemize}
\begin{lstlisting}
#include <qwt_plot.h>
#include <qwt_plot_canvas.h>
#include <qwt_scale_widget.h>
class MyPlot: public QwtPlot
{
public:
MyPlot(QWidget *parent = NULL);
virtual bool eventFilter(QObject *obj, QEvent *event)
};
MyPlot::MyPlot(QWidget *parent):
QwtPlot(parent)
{
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
axisWidget(axis)->setFont( QFont( ... ) );
canvas()->setPalette( QPalette( Qt::darkBlue ) );
canvas()->installEventFilter(this);
}
bool MyPlot::eventFilter(QObject *object, QEvent *event)
{
if ( object == canvas() )
{
...
}
return QwtPlot::eventFilter(object, event);
}
\end{lstlisting}
\section{Scale Widget}
\section{Legend}
\chapter{Scales, Axes and Transformations}
\section{Scale Divisions}
\section{Scale Maps}
\section{Scale Engine}
\section{Scale Renderer}
\chapter{Navigation and Selection}
\section{Picking}
\section{Zooming}
\section{Panning}
\chapter{Items on the Plot Canvas}
Decorations + items representing some sort of data.
\section{Overview}
\section{The Grid}
\section{Axes}
\section{Markers for Coordinates or Points}
\section{Curves displaying a series of 2D Points}
\subsection{Symbols}
\subsection{Styles}
\subsection{Curve Fitting}
\section{Curves displaying a series of 3D Points}
\section{Curves displaying a series of intervals}
\section{Histograms displaying ...}
\section{Spectrograms and other items displaying raster data}
\section{SVG Item}
\chapter{Exporting and Printing}
\chapter{Text Engines}
All Qwt widgets use QwtText objects to specify text labels.
Their format attribute specifies the text engine, that is
responsible for interpreting and rendering the string.
Today there are 3 different text engines available.
\footnote{A text engine for TeX documents would be a great
solution to display labels in mathematical notation.
There are a couple Qt/KDE applications available,
that can display TeX documents. Most of them simply write
the TeX document to a file generate an image from it using the
TeX tools and load the image then - but maybe there is
somewhere an "real" implementation inside, that
translates a TeX document to QPainter calls. }
\begin{itemize}
\item Plain Text\\
QwtPlainTextEngine doesn't take care of any syntax and lays out and renders
the string using QPainter and QFontMetrics.
\item Rich Text\\
QwtRichTextEngine is able to display a subset of HTML 4 markup using the renderer,
that is built into the Scribe classes of Qt. It is often used because of
sub- or superscripts to display very simple mathematical expressions.
\item Mathematical Markup Language (MathML)\\
QwtMathMLTextEngine uses the MathML renderer from the Qt solutions
\footnote{
Unfortunately we don't know much about the quality of the MathML renderer yet
as it is not much in use because of earlier license issues.
Today the solution package is LGPL'd like the rest of Qt and in Qwt 6 it can be
installed and used easily.
}
package. In MathML it should be able to define almost any kind of formula
\end{itemize}
The text engines for plain and rich texts are always available.
The MathML text engine ( like any other homebrew text engine ) has to be
registered by the application code:
\bigskip
\begin{lstlisting}
#include <qwt_mathml_text_engine.h>
QwtText::setTextEngine(QwtText::MathMLText, new QwtMathMLTextEngine());
\end{lstlisting}
\bigskip
QwtText might also have a couple of additional properties, controlling how to display a text.
\begin{itemize}
\item Font
\item Color
\item Background color and border pen
\end{itemize}
\chapter{Advanced Topics}
\section{Incremental Painting}
\section{Building Plot Grids}
\section{Controlling the Aspect Ratio}
\section{Levels of Detail}
\end{document}

View File

@@ -0,0 +1,19 @@
################################################################
# Qwt Widget Library
# Copyright (C) 1997 Josef Wilgen
# Copyright (C) 2002 Uwe Rathmann
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the Qwt License, Version 1.0
################################################################
include( $${PWD}/../examples.pri )
TARGET = animation
HEADERS = \
plot.h
SOURCES = \
plot.cpp \
main.cpp

View File

@@ -0,0 +1,46 @@
#include <qapplication.h>
#include "plot.h"
#ifndef QWT_NO_OPENGL
#define USE_OPENGL 1
#endif
#if USE_OPENGL
#include <qgl.h>
#include <qwt_plot_glcanvas.h>
#else
#include <qwt_plot_canvas.h>
#endif
int main ( int argc, char **argv )
{
#if USE_OPENGL
#if QT_VERSION >= 0x040600 && QT_VERSION < 0x050000
// on my box QPaintEngine::OpenGL2 has serious problems, f.e:
// the lines of a simple drawRect are wrong.
QGL::setPreferredPaintEngine( QPaintEngine::OpenGL );
#endif
#endif
QApplication a( argc, argv );
Plot plot;
#if USE_OPENGL
QwtPlotGLCanvas *canvas = new QwtPlotGLCanvas();
canvas->setFrameStyle( QwtPlotGLCanvas::NoFrame );
#else
QwtPlotCanvas *canvas = new QwtPlotCanvas();
canvas->setFrameStyle( QFrame::NoFrame );
canvas->setPaintAttribute( QwtPlotCanvas::BackingStore, false );
#endif
plot.setCanvas( canvas );
plot.setCanvasBackground( QColor( 30, 30, 50 ) );
plot.resize( 400, 400 );
plot.show();
return a.exec();
}

View File

@@ -0,0 +1,241 @@
#include <qapplication.h>
#include <qwt_math.h>
#include <qwt_symbol.h>
#include <qwt_curve_fitter.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_layout.h>
#include <qevent.h>
#include "plot.h"
class Curve: public QwtPlotCurve
{
public:
void setTransformation( const QTransform &transform )
{
d_transform = transform;
}
virtual void updateSamples( double phase )
{
setSamples( d_transform.map( points( phase ) ) );
}
private:
virtual QPolygonF points( double phase ) const = 0;
private:
QTransform d_transform;
};
class Curve1: public Curve
{
public:
Curve1()
{
setPen( QColor( 150, 150, 200 ), 2 );
setStyle( QwtPlotCurve::Lines );
QwtSplineCurveFitter *curveFitter = new QwtSplineCurveFitter();
curveFitter->setSplineSize( 150 );
setCurveFitter( curveFitter );
setCurveAttribute( QwtPlotCurve::Fitted, true );
QwtSymbol *symbol = new QwtSymbol( QwtSymbol::XCross );
symbol->setPen( Qt::yellow );
symbol->setSize( 7 );
setSymbol( symbol );
// somewhere to the left
QTransform transform;
transform.scale( 1.5, 1.0 );
transform.translate( 1.5, 3.0 );
setTransformation( transform );
}
virtual QPolygonF points( double phase ) const
{
QPolygonF points;
const int numSamples = 15;
for ( int i = 0; i < numSamples; i++ )
{
const double v = 6.28 * double( i ) / double( numSamples - 1 );
points += QPointF( qSin( v - phase ), v );
}
return points;
}
};
class Curve2: public Curve
{
public:
Curve2()
{
setStyle( QwtPlotCurve::Sticks );
setPen( QColor( 200, 150, 50 ) );
setSymbol( new QwtSymbol( QwtSymbol::Ellipse,
QColor( Qt::gray ), QColor( Qt::yellow ), QSize( 5, 5 ) ) );
}
private:
virtual QPolygonF points( double phase ) const
{
QPolygonF points;
const int numSamples = 50;
for ( int i = 0; i < numSamples; i++ )
{
const double v = 10.0 * i / double( numSamples - 1 );
points += QPointF( v, qCos( 3.0 * ( v + phase ) ) );
}
return points;
}
};
class Curve3: public Curve
{
public:
Curve3()
{
setStyle( QwtPlotCurve::Lines );
setPen( QColor( 100, 200, 150 ), 2 );
QwtSplineCurveFitter* curveFitter = new QwtSplineCurveFitter();
curveFitter->setFitMode( QwtSplineCurveFitter::ParametricSpline );
curveFitter->setSplineSize( 200 );
setCurveFitter( curveFitter );
setCurveAttribute( QwtPlotCurve::Fitted, true );
// somewhere in the top right corner
QTransform transform;
transform.translate( 7.0, 7.5 );
transform.scale( 2.0, 2.0 );
setTransformation( transform );
}
private:
virtual QPolygonF points( double phase ) const
{
QPolygonF points;
const int numSamples = 9;
for ( int i = 0; i < numSamples; i++ )
{
const double v = i * 2.0 * M_PI / ( numSamples - 1 );
points += QPointF( qSin( v - phase ), qCos( 3.0 * ( v + phase ) ) );
}
return points;
}
};
class Curve4: public Curve
{
public:
Curve4()
{
setStyle( QwtPlotCurve::Lines );
setPen( Qt::red, 2 );
initSamples();
// somewhere in the center
QTransform transform;
transform.translate( 7.0, 3.0 );
transform.scale( 1.5, 1.5 );
setTransformation( transform );
}
private:
virtual QPolygonF points( double phase ) const
{
const double speed = 0.05;
const double s = speed * qSin( phase );
const double c = qSqrt( 1.0 - s * s );
for ( int i = 0; i < d_points.size(); i++ )
{
const QPointF p = d_points[i];
const double u = p.x();
const double v = p.y();
d_points[i].setX( u * c - v * s );
d_points[i].setY( v * c + u * s );
}
return d_points;
}
void initSamples()
{
const int numSamples = 15;
for ( int i = 0; i < numSamples; i++ )
{
const double angle = i * ( 2.0 * M_PI / ( numSamples - 1 ) );
QPointF p( qCos( angle ), qSin( angle ) );
if ( i % 2 )
p *= 0.4;
d_points += p;
}
}
private:
mutable QPolygonF d_points;
};
Plot::Plot( QWidget *parent ):
QwtPlot( parent)
{
setAutoReplot( false );
setTitle( "Animated Curves" );
// hide all axes
for ( int axis = 0; axis < QwtAxis::PosCount; axis++ )
setAxisVisible( axis, false );
plotLayout()->setCanvasMargin( 10 );
d_curves[0] = new Curve1();
d_curves[1] = new Curve2();
d_curves[2] = new Curve3();
d_curves[3] = new Curve4();
updateCurves();
for ( int i = 0; i < CurveCount; i++ )
d_curves[i]->attach( this );
d_time.start();
( void )startTimer( 40 );
}
void Plot::timerEvent( QTimerEvent * )
{
updateCurves();
replot();
}
void Plot::updateCurves()
{
const double speed = 2 * M_PI / 25000.0; // a cycle every 25 seconds
const double phase = d_time.elapsed() * speed;
for ( int i = 0; i < CurveCount; i++ )
d_curves[i]->updateSamples( phase );
}

View File

@@ -0,0 +1,21 @@
#include <qwt_plot.h>
#include <qdatetime.h>
class Curve;
class Plot: public QwtPlot
{
public:
Plot( QWidget * = NULL);
protected:
virtual void timerEvent( QTimerEvent * );
private:
void updateCurves();
enum { CurveCount = 4 };
Curve *d_curves[CurveCount];
QTime d_time;
};

View File

@@ -0,0 +1,132 @@
#include "barchart.h"
#include <qwt_plot_renderer.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_multi_barchart.h>
#include <qwt_column_symbol.h>
#include <qwt_plot_layout.h>
#include <qwt_legend.h>
#include <qwt_scale_draw.h>
BarChart::BarChart( QWidget *parent ):
QwtPlot( parent )
{
setAutoFillBackground( true );
setPalette( Qt::white );
canvas()->setPalette( QColor( "LemonChiffon" ) );
setTitle( "Bar Chart" );
setAxisTitle( QwtAxis::yLeft, "Whatever" );
setAxisTitle( QwtAxis::xBottom, "Whatever" );
d_barChartItem = new QwtPlotMultiBarChart( "Bar Chart " );
d_barChartItem->setLayoutPolicy( QwtPlotMultiBarChart::AutoAdjustSamples );
d_barChartItem->setSpacing( 20 );
d_barChartItem->setMargin( 3 );
d_barChartItem->attach( this );
insertLegend( new QwtLegend() );
populate();
setOrientation( 0 );
setAutoReplot( true );
}
void BarChart::populate()
{
static const char *colors[] = { "DarkOrchid", "SteelBlue", "Gold" };
const int numSamples = 5;
const int numBars = sizeof( colors ) / sizeof( colors[0] );
QList<QwtText> titles;
for ( int i = 0; i < numBars; i++ )
{
QString title("Bar %1");
titles += title.arg( i );
}
d_barChartItem->setBarTitles( titles );
d_barChartItem->setLegendIconSize( QSize( 10, 14 ) );
for ( int i = 0; i < numBars; i++ )
{
QwtColumnSymbol *symbol = new QwtColumnSymbol( QwtColumnSymbol::Box );
symbol->setLineWidth( 2 );
symbol->setFrameStyle( QwtColumnSymbol::Raised );
symbol->setPalette( QPalette( colors[i] ) );
d_barChartItem->setSymbol( i, symbol );
}
QVector< QVector<double> > series;
for ( int i = 0; i < numSamples; i++ )
{
QVector<double> values;
for ( int j = 0; j < numBars; j++ )
values += ( 2 + qrand() % 8 );
series += values;
}
d_barChartItem->setSamples( series );
}
void BarChart::setMode( int mode )
{
if ( mode == 0 )
{
d_barChartItem->setStyle( QwtPlotMultiBarChart::Grouped );
}
else
{
d_barChartItem->setStyle( QwtPlotMultiBarChart::Stacked );
}
}
void BarChart::setOrientation( int orientation )
{
QwtAxis::Position axis1, axis2;
if ( orientation == 0 )
{
axis1 = QwtAxis::xBottom;
axis2 = QwtAxis::yLeft;
d_barChartItem->setOrientation( Qt::Vertical );
}
else
{
axis1 = QwtAxis::yLeft;
axis2 = QwtAxis::xBottom;
d_barChartItem->setOrientation( Qt::Horizontal );
}
setAxisScale( axis1, 0, d_barChartItem->dataSize() - 1, 1.0 );
setAxisAutoScale( axis2 );
QwtScaleDraw *scaleDraw1 = axisScaleDraw( axis1 );
scaleDraw1->enableComponent( QwtScaleDraw::Backbone, false );
scaleDraw1->enableComponent( QwtScaleDraw::Ticks, false );
QwtScaleDraw *scaleDraw2 = axisScaleDraw( axis2 );
scaleDraw2->enableComponent( QwtScaleDraw::Backbone, true );
scaleDraw2->enableComponent( QwtScaleDraw::Ticks, true );
plotLayout()->setAlignCanvasToScale( axis1, true );
plotLayout()->setAlignCanvasToScale( axis2, false );
plotLayout()->setCanvasMargin( 0 );
updateCanvasMargins();
replot();
}
void BarChart::exportChart()
{
QwtPlotRenderer renderer;
renderer.exportTo( this, "barchart.pdf" );
}

View File

@@ -0,0 +1,25 @@
#ifndef _BAR_CHART_H_
#include <qwt_plot.h>
class QwtPlotMultiBarChart;
class BarChart: public QwtPlot
{
Q_OBJECT
public:
BarChart( QWidget * = NULL );
public Q_SLOTS:
void setMode( int );
void setOrientation( int );
void exportChart();
private:
void populate();
QwtPlotMultiBarChart *d_barChartItem;
};
#endif

View File

@@ -0,0 +1,19 @@
################################################################
# Qwt Widget Library
# Copyright (C) 1997 Josef Wilgen
# Copyright (C) 2002 Uwe Rathmann
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the Qwt License, Version 1.0
################################################################
include( $${PWD}/../examples.pri )
TARGET = barchart
SOURCES = \
barchart.cpp \
main.cpp
HEADERS = \
barchart.h

View File

@@ -0,0 +1,64 @@
#include <qapplication.h>
#include <qmainwindow.h>
#include <qtoolbar.h>
#include <qtoolbutton.h>
#include <qcombobox.h>
#include "barchart.h"
class MainWindow: public QMainWindow
{
public:
MainWindow( QWidget * = NULL );
private:
BarChart *d_chart;
};
MainWindow::MainWindow( QWidget *parent ):
QMainWindow( parent )
{
d_chart = new BarChart( this );
setCentralWidget( d_chart );
QToolBar *toolBar = new QToolBar( this );
QComboBox *typeBox = new QComboBox( toolBar );
typeBox->addItem( "Grouped" );
typeBox->addItem( "Stacked" );
typeBox->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
QComboBox *orientationBox = new QComboBox( toolBar );
orientationBox->addItem( "Vertical" );
orientationBox->addItem( "Horizontal" );
orientationBox->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
QToolButton *btnExport = new QToolButton( toolBar );
btnExport->setText( "Export" );
btnExport->setToolButtonStyle( Qt::ToolButtonTextUnderIcon );
connect( btnExport, SIGNAL( clicked() ), d_chart, SLOT( exportChart() ) );
toolBar->addWidget( typeBox );
toolBar->addWidget( orientationBox );
toolBar->addWidget( btnExport );
addToolBar( toolBar );
d_chart->setMode( typeBox->currentIndex() );
connect( typeBox, SIGNAL( currentIndexChanged( int ) ),
d_chart, SLOT( setMode( int ) ) );
d_chart->setOrientation( orientationBox->currentIndex() );
connect( orientationBox, SIGNAL( currentIndexChanged( int ) ),
d_chart, SLOT( setOrientation( int ) ) );
}
int main( int argc, char **argv )
{
QApplication a( argc, argv );
MainWindow mainWindow;
mainWindow.resize( 600, 400 );
mainWindow.show();
return a.exec();
}

View File

@@ -0,0 +1,23 @@
################################################################
# Qwt Widget Library
# Copyright (C) 1997 Josef Wilgen
# Copyright (C) 2002 Uwe Rathmann
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the Qwt License, Version 1.0
################################################################
include( $${PWD}/../examples.pri )
TARGET = bode
HEADERS = \
mainwindow.h \
plot.h \
complexnumber.h \
pixmaps.h
SOURCES = \
plot.cpp \
mainwindow.cpp \
main.cpp

View File

@@ -0,0 +1,83 @@
#ifndef _COMPLEX_NUMBER_H_
#define _COMPLEX_NUMBER_H_
#include <math.h>
class ComplexNumber
{
public:
ComplexNumber() ;
ComplexNumber( double r, double i = 0.0 );
double real() const;
double imag() const;
friend ComplexNumber operator*(
const ComplexNumber &, const ComplexNumber & );
friend ComplexNumber operator+(
const ComplexNumber &, const ComplexNumber & );
friend ComplexNumber operator-(
const ComplexNumber &, const ComplexNumber & );
friend ComplexNumber operator/(
const ComplexNumber &, const ComplexNumber & );
private:
double d_real;
double d_imag;
};
inline ComplexNumber::ComplexNumber():
d_real( 0.0 ),
d_imag( -0.0 )
{
}
inline ComplexNumber::ComplexNumber( double re, double im ):
d_real( re ),
d_imag( im )
{
}
inline double ComplexNumber::real() const
{
return d_real;
}
inline double ComplexNumber::imag() const
{
return d_imag;
}
inline ComplexNumber operator+(
const ComplexNumber &x1, const ComplexNumber &x2 )
{
return ComplexNumber( x1.d_real + x2.d_real, x1.d_imag + x2.d_imag );
}
inline ComplexNumber operator-(
const ComplexNumber &x1, const ComplexNumber &x2 )
{
return ComplexNumber( x1.d_real - x2.d_real, x1.d_imag - x2.d_imag );
}
inline ComplexNumber operator*(
const ComplexNumber &x1, const ComplexNumber &x2 )
{
return ComplexNumber( x1.d_real * x2.d_real - x1.d_imag * x2.d_imag,
x1.d_real * x2.d_imag + x2.d_real * x1.d_imag );
}
inline ComplexNumber operator/(
const ComplexNumber &x1, const ComplexNumber &x2 )
{
double denom = x2.d_real * x2.d_real + x2.d_imag * x2.d_imag;
return ComplexNumber(
( x1.d_real * x2.d_real + x1.d_imag * x2.d_imag ) / denom,
( x1.d_imag * x2.d_real - x2.d_imag * x1.d_real ) / denom
);
}
#endif

View File

@@ -0,0 +1,13 @@
#include <qapplication.h>
#include "mainwindow.h"
int main ( int argc, char **argv )
{
QApplication a( argc, argv );
MainWindow w;
w.resize( 1000, 800 );
w.show();
return a.exec();
}

View File

@@ -0,0 +1,231 @@
#include <qregexp.h>
#include <qtoolbar.h>
#include <qtoolbutton.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qstatusbar.h>
#include <qprinter.h>
#include <qpicture.h>
#include <qpainter.h>
#include <qprintdialog.h>
#include <qwt_counter.h>
#include <qwt_picker_machine.h>
#include <qwt_plot_zoomer.h>
#include <qwt_plot_panner.h>
#include <qwt_plot_renderer.h>
#include <qwt_text.h>
#include <qwt_math.h>
#include "pixmaps.h"
#include "plot.h"
#include "mainwindow.h"
class Zoomer: public QwtPlotZoomer
{
public:
Zoomer( int xAxis, int yAxis, QWidget *canvas ):
QwtPlotZoomer( xAxis, yAxis, canvas )
{
setTrackerMode( QwtPicker::AlwaysOff );
setRubberBand( QwtPicker::NoRubberBand );
// RightButton: zoom out by 1
// Ctrl+RightButton: zoom out to full size
setMousePattern( QwtEventPattern::MouseSelect2,
Qt::RightButton, Qt::ControlModifier );
setMousePattern( QwtEventPattern::MouseSelect3,
Qt::RightButton );
}
};
//-----------------------------------------------------------------
//
// bode.cpp -- A demo program featuring QwtPlot and QwtCounter
//
// This example demonstrates the mapping of different curves
// to different axes in a QwtPlot widget. It also shows how to
// display the cursor position and how to implement zooming.
//
//-----------------------------------------------------------------
MainWindow::MainWindow( QWidget *parent ):
QMainWindow( parent )
{
d_plot = new Plot( this );
const int margin = 5;
d_plot->setContentsMargins( margin, margin, margin, 0 );
setContextMenuPolicy( Qt::NoContextMenu );
d_zoomer[0] = new Zoomer(
QwtAxis::xBottom, QwtAxis::yLeft, d_plot->canvas() );
d_zoomer[0]->setRubberBand( QwtPicker::RectRubberBand );
d_zoomer[0]->setRubberBandPen( QColor( Qt::green ) );
d_zoomer[0]->setTrackerMode( QwtPicker::ActiveOnly );
d_zoomer[0]->setTrackerPen( QColor( Qt::white ) );
d_zoomer[1] = new Zoomer( QwtAxis::xTop, QwtAxis::yRight,
d_plot->canvas() );
d_panner = new QwtPlotPanner( d_plot->canvas() );
d_panner->setMouseButton( Qt::MidButton );
d_picker = new QwtPlotPicker( QwtAxis::xBottom, QwtAxis::yLeft,
QwtPlotPicker::CrossRubberBand, QwtPicker::AlwaysOn,
d_plot->canvas() );
d_picker->setStateMachine( new QwtPickerDragPointMachine() );
d_picker->setRubberBandPen( QColor( Qt::green ) );
d_picker->setRubberBand( QwtPicker::CrossRubberBand );
d_picker->setTrackerPen( QColor( Qt::white ) );
setCentralWidget( d_plot );
QToolBar *toolBar = new QToolBar( this );
QToolButton *btnZoom = new QToolButton( toolBar );
btnZoom->setText( "Zoom" );
btnZoom->setIcon( QPixmap( zoom_xpm ) );
btnZoom->setCheckable( true );
btnZoom->setToolButtonStyle( Qt::ToolButtonTextUnderIcon );
toolBar->addWidget( btnZoom );
connect( btnZoom, SIGNAL( toggled( bool ) ), SLOT( enableZoomMode( bool ) ) );
#ifndef QT_NO_PRINTER
QToolButton *btnPrint = new QToolButton( toolBar );
btnPrint->setText( "Print" );
btnPrint->setIcon( QPixmap( print_xpm ) );
btnPrint->setToolButtonStyle( Qt::ToolButtonTextUnderIcon );
toolBar->addWidget( btnPrint );
connect( btnPrint, SIGNAL( clicked() ), SLOT( print() ) );
#endif
QToolButton *btnExport = new QToolButton( toolBar );
btnExport->setText( "Export" );
btnExport->setIcon( QPixmap( print_xpm ) );
btnExport->setToolButtonStyle( Qt::ToolButtonTextUnderIcon );
toolBar->addWidget( btnExport );
connect( btnExport, SIGNAL( clicked() ), SLOT( exportDocument() ) );
toolBar->addSeparator();
QWidget *hBox = new QWidget( toolBar );
QHBoxLayout *layout = new QHBoxLayout( hBox );
layout->setSpacing( 0 );
layout->addWidget( new QWidget( hBox ), 10 ); // spacer
layout->addWidget( new QLabel( "Damping Factor", hBox ), 0 );
layout->addSpacing( 10 );
QwtCounter *cntDamp = new QwtCounter( hBox );
cntDamp->setRange( 0.0, 5.0 );
cntDamp->setSingleStep( 0.01 );
cntDamp->setValue( 0.0 );
layout->addWidget( cntDamp, 0 );
( void )toolBar->addWidget( hBox );
addToolBar( toolBar );
#ifndef QT_NO_STATUSBAR
( void )statusBar();
#endif
enableZoomMode( false );
showInfo();
connect( cntDamp, SIGNAL( valueChanged( double ) ),
d_plot, SLOT( setDamp( double ) ) );
connect( d_picker, SIGNAL( moved( const QPoint & ) ),
SLOT( moved( const QPoint & ) ) );
connect( d_picker, SIGNAL( selected( const QPolygon & ) ),
SLOT( selected( const QPolygon & ) ) );
}
#ifndef QT_NO_PRINTER
void MainWindow::print()
{
QPrinter printer( QPrinter::HighResolution );
QString docName = d_plot->title().text();
if ( !docName.isEmpty() )
{
docName.replace ( QRegExp ( QString::fromLatin1 ( "\n" ) ), tr ( " -- " ) );
printer.setDocName ( docName );
}
printer.setCreator( "Bode example" );
printer.setOrientation( QPrinter::Landscape );
QPrintDialog dialog( &printer );
if ( dialog.exec() )
{
QwtPlotRenderer renderer;
if ( printer.colorMode() == QPrinter::GrayScale )
{
renderer.setDiscardFlag( QwtPlotRenderer::DiscardBackground );
renderer.setDiscardFlag( QwtPlotRenderer::DiscardCanvasBackground );
renderer.setDiscardFlag( QwtPlotRenderer::DiscardCanvasFrame );
renderer.setLayoutFlag( QwtPlotRenderer::FrameWithScales );
}
renderer.renderTo( d_plot, printer );
}
}
#endif
void MainWindow::exportDocument()
{
QwtPlotRenderer renderer;
renderer.exportTo( d_plot, "bode.pdf" );
}
void MainWindow::enableZoomMode( bool on )
{
d_panner->setEnabled( on );
d_zoomer[0]->setEnabled( on );
d_zoomer[0]->zoom( 0 );
d_zoomer[1]->setEnabled( on );
d_zoomer[1]->zoom( 0 );
d_picker->setEnabled( !on );
showInfo();
}
void MainWindow::showInfo( QString text )
{
if ( text == QString::null )
{
if ( d_picker->rubberBand() )
text = "Cursor Pos: Press left mouse button in plot region";
else
text = "Zoom: Press mouse button and drag";
}
#ifndef QT_NO_STATUSBAR
statusBar()->showMessage( text );
#endif
}
void MainWindow::moved( const QPoint &pos )
{
QString info;
info.sprintf( "Freq=%g, Ampl=%g, Phase=%g",
d_plot->invTransform( QwtAxis::xBottom, pos.x() ),
d_plot->invTransform( QwtAxis::yLeft, pos.y() ),
d_plot->invTransform( QwtAxis::yRight, pos.y() )
);
showInfo( info );
}
void MainWindow::selected( const QPolygon & )
{
showInfo();
}

View File

@@ -0,0 +1,35 @@
#include <qmainwindow.h>
class QwtPlotZoomer;
class QwtPlotPicker;
class QwtPlotPanner;
class Plot;
class QPolygon;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow( QWidget *parent = 0 );
private Q_SLOTS:
void moved( const QPoint & );
void selected( const QPolygon & );
#ifndef QT_NO_PRINTER
void print();
#endif
void exportDocument();
void enableZoomMode( bool );
private:
void showInfo( QString text = QString::null );
Plot *d_plot;
QwtPlotZoomer *d_zoomer[2];
QwtPlotPicker *d_picker;
QwtPlotPanner *d_panner;
};

View File

@@ -0,0 +1,99 @@
#ifndef PIXMAPS_H
#define PIXMAPS_H
static const char *print_xpm[] =
{
"32 32 12 1",
"a c #ffffff",
"h c #ffff00",
"c c #ffffff",
"f c #dcdcdc",
"b c #c0c0c0",
"j c #a0a0a4",
"e c #808080",
"g c #808000",
"d c #585858",
"i c #00ff00",
"# c #000000",
". c None",
"................................",
"................................",
"...........###..................",
"..........#abb###...............",
".........#aabbbbb###............",
".........#ddaaabbbbb###.........",
"........#ddddddaaabbbbb###......",
".......#deffddddddaaabbbbb###...",
"......#deaaabbbddddddaaabbbbb###",
".....#deaaaaaaabbbddddddaaabbbb#",
"....#deaaabbbaaaa#ddedddfggaaad#",
"...#deaaaaaaaaaa#ddeeeeafgggfdd#",
"..#deaaabbbaaaa#ddeeeeabbbbgfdd#",
".#deeefaaaaaaa#ddeeeeabbhhbbadd#",
"#aabbbeeefaaa#ddeeeeabbbbbbaddd#",
"#bbaaabbbeee#ddeeeeabbiibbadddd#",
"#bbbbbaaabbbeeeeeeabbbbbbaddddd#",
"#bjbbbbbbaaabbbbeabbbbbbadddddd#",
"#bjjjjbbbbbbaaaeabbbbbbaddddddd#",
"#bjaaajjjbbbbbbaaabbbbadddddddd#",
"#bbbbbaaajjjbbbbbbaaaaddddddddd#",
"#bjbbbbbbaaajjjbbbbbbddddddddd#.",
"#bjjjjbbbbbbaaajjjbbbdddddddd#..",
"#bjaaajjjbbbbbbjaajjbddddddd#...",
"#bbbbbaaajjjbbbjbbaabdddddd#....",
"###bbbbbbaaajjjjbbbbbddddd#.....",
"...###bbbbbbaaajbbbbbdddd#......",
"......###bbbbbbjbbbbbddd#.......",
".........###bbbbbbbbbdd#........",
"............###bbbbbbd#.........",
"...............###bbb#..........",
"..................###..........."
};
static const char *zoom_xpm[] =
{
"32 32 8 1",
"# c #000000",
"b c #c0c0c0",
"a c #ffffff",
"e c #585858",
"d c #a0a0a4",
"c c #0000ff",
"f c #00ffff",
". c None",
"..######################........",
".#a#baaaaaaaaaaaaaaaaaa#........",
"#aa#baaaaaaaaaaaaaccaca#........",
"####baaaaaaaaaaaaaaaaca####.....",
"#bbbbaaaaaaaaaaaacccaaa#da#.....",
"#aaaaaaaaaaaaaaaacccaca#da#.....",
"#aaaaaaaaaaaaaaaaaccaca#da#.....",
"#aaaaaaaaaabe###ebaaaaa#da#.....",
"#aaaaaaaaa#########aaaa#da#.....",
"#aaaaaaaa###dbbbb###aaa#da#.....",
"#aaaaaaa###aaaaffb###aa#da#.....",
"#aaaaaab##aaccaaafb##ba#da#.....",
"#aaaaaae#daaccaccaad#ea#da#.....",
"#aaaaaa##aaaaaaccaab##a#da#.....",
"#aaaaaa##aacccaaaaab##a#da#.....",
"#aaaaaa##aaccccaccab##a#da#.....",
"#aaaaaae#daccccaccad#ea#da#.....",
"#aaaaaab##aacccaaaa##da#da#.....",
"#aaccacd###aaaaaaa###da#da#.....",
"#aaaaacad###daaad#####a#da#.....",
"#acccaaaad##########da##da#.....",
"#acccacaaadde###edd#eda#da#.....",
"#aaccacaaaabdddddbdd#eda#a#.....",
"#aaaaaaaaaaaaaaaaaadd#eda##.....",
"#aaaaaaaaaaaaaaaaaaadd#eda#.....",
"#aaaaaaaccacaaaaaaaaadd#eda#....",
"#aaaaaaaaaacaaaaaaaaaad##eda#...",
"#aaaaaacccaaaaaaaaaaaaa#d#eda#..",
"########################dd#eda#.",
"...#dddddddddddddddddddddd##eda#",
"...#aaaaaaaaaaaaaaaaaaaaaa#.####",
"...########################..##."
};
#endif

208
qwt/examples/bode/plot.cpp Normal file
View File

@@ -0,0 +1,208 @@
#include <qwt_math.h>
#include <qwt_scale_engine.h>
#include <qwt_symbol.h>
#include <qwt_plot_grid.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_curve.h>
#include <qwt_legend.h>
#include <qwt_text.h>
#include <qwt_plot_canvas.h>
#include <qmath.h>
#include "complexnumber.h"
#include "plot.h"
#if QT_VERSION < 0x040601
#define qExp(x) ::exp(x)
#define qAtan2(y, x) ::atan2(y, x)
#endif
static void logSpace( double *array, int size, double xmin, double xmax )
{
if ( ( xmin <= 0.0 ) || ( xmax <= 0.0 ) || ( size <= 0 ) )
return;
const int imax = size - 1;
array[0] = xmin;
array[imax] = xmax;
const double lxmin = log( xmin );
const double lxmax = log( xmax );
const double lstep = ( lxmax - lxmin ) / double( imax );
for ( int i = 1; i < imax; i++ )
array[i] = qExp( lxmin + double( i ) * lstep );
}
Plot::Plot( QWidget *parent ):
QwtPlot( parent )
{
setAutoReplot( false );
setTitle( "Frequency Response of a Second-Order System" );
setFooter( "Footer Response of a Second-Order System" );
setCanvasBackground( QColor( "MidnightBlue" ) );
// legend
QwtLegend *legend = new QwtLegend;
insertLegend( legend, QwtPlot::BottomLegend );
// grid
QwtPlotGrid *grid = new QwtPlotGrid;
grid->enableXMin( true );
grid->setMajorPen( Qt::white, 0, Qt::DotLine );
grid->setMinorPen( Qt::gray, 0 , Qt::DotLine );
grid->setAxes( QwtAxisId( QwtAxis::xTop, 2 ), QwtAxisId( QwtAxis::yRight, 1 ) );
grid->attach( this );
// axes
for ( int axisPos = 0; axisPos < QwtAxis::PosCount; axisPos++ )
{
setAxesCount( axisPos, 3 );
for ( int i = 0; i < axesCount( axisPos ); i++ )
{
QwtAxisId axisId( axisPos, i );
QString title( "Normalized Frequency or any other important stuff" );
setAxisTitle( axisId, title + QString().setNum( i ) );
if ( i == 1 )
{
setAxisScale( axisId, 1000000, 500000 );
if ( QwtAxis::isYAxis( axisPos ) )
setAxisLabelRotation( axisId, -60 );
}
if ( i == 2 )
setAxisScale( axisId, 70.457895, 0.00000555 );
}
}
setAxisVisible( QwtAxis::yRight );
setAxisVisible( QwtAxis::xTop );
setAxisMaxMajor( QwtAxis::xBottom, 6 );
setAxisMaxMinor( QwtAxis::xBottom, 9 );
setAxisScaleEngine( QwtAxis::xBottom, new QwtLogScaleEngine );
// curves
d_curve1 = new QwtPlotCurve( "Amplitude" );
d_curve1->setRenderHint( QwtPlotItem::RenderAntialiased );
d_curve1->setPen( Qt::yellow );
d_curve1->setLegendAttribute( QwtPlotCurve::LegendShowLine );
d_curve1->setYAxis( QwtAxis::yLeft );
d_curve1->attach( this );
d_curve2 = new QwtPlotCurve( "Phase" );
d_curve2->setRenderHint( QwtPlotItem::RenderAntialiased );
d_curve2->setPen( Qt::cyan );
d_curve2->setLegendAttribute( QwtPlotCurve::LegendShowLine );
d_curve2->setYAxis( QwtAxis::yRight );
d_curve2->attach( this );
// marker
d_marker1 = new QwtPlotMarker();
d_marker1->setValue( 0.0, 0.0 );
d_marker1->setLineStyle( QwtPlotMarker::VLine );
d_marker1->setLabelAlignment( Qt::AlignRight | Qt::AlignBottom );
d_marker1->setLinePen( Qt::green, 0, Qt::DashDotLine );
d_marker1->attach( this );
d_marker2 = new QwtPlotMarker();
d_marker2->setLineStyle( QwtPlotMarker::HLine );
d_marker2->setLabelAlignment( Qt::AlignRight | Qt::AlignBottom );
d_marker2->setLinePen( QColor( 200, 150, 0 ), 0, Qt::DashDotLine );
d_marker2->setSymbol( new QwtSymbol( QwtSymbol::Diamond,
QColor( Qt::yellow ), QColor( Qt::green ), QSize( 8, 8 ) ) );
d_marker2->attach( this );
setDamp( 0.0 );
setAutoReplot( true );
}
void Plot::showData( const double *frequency, const double *amplitude,
const double *phase, int count )
{
d_curve1->setSamples( frequency, amplitude, count );
d_curve2->setSamples( frequency, phase, count );
}
void Plot::showPeak( double freq, double amplitude )
{
QString label;
label.sprintf( "Peak: %.3g dB", amplitude );
QwtText text( label );
text.setFont( QFont( "Helvetica", 10, QFont::Bold ) );
text.setColor( QColor( 200, 150, 0 ) );
d_marker2->setValue( freq, amplitude );
d_marker2->setLabel( text );
}
void Plot::show3dB( double freq )
{
QString label;
label.sprintf( "-3 dB at f = %.3g", freq );
QwtText text( label );
text.setFont( QFont( "Helvetica", 10, QFont::Bold ) );
text.setColor( Qt::green );
d_marker1->setValue( freq, 0.0 );
d_marker1->setLabel( text );
}
//
// re-calculate frequency response
//
void Plot::setDamp( double damping )
{
const bool doReplot = autoReplot();
setAutoReplot( false );
const int ArraySize = 200;
double frequency[ArraySize];
double amplitude[ArraySize];
double phase[ArraySize];
// build frequency vector with logarithmic division
logSpace( frequency, ArraySize, 0.01, 100 );
int i3 = 1;
double fmax = 1;
double amax = -1000.0;
for ( int i = 0; i < ArraySize; i++ )
{
double f = frequency[i];
const ComplexNumber g =
ComplexNumber( 1.0 ) / ComplexNumber( 1.0 - f * f, 2.0 * damping * f );
amplitude[i] = 20.0 * log10( qSqrt( g.real() * g.real() + g.imag() * g.imag() ) );
phase[i] = qAtan2( g.imag(), g.real() ) * ( 180.0 / M_PI );
if ( ( i3 <= 1 ) && ( amplitude[i] < -3.0 ) )
i3 = i;
if ( amplitude[i] > amax )
{
amax = amplitude[i];
fmax = frequency[i];
}
}
double f3 = frequency[i3] - ( frequency[i3] - frequency[i3 - 1] )
/ ( amplitude[i3] - amplitude[i3 -1] ) * ( amplitude[i3] + 3 );
showPeak( fmax, amax );
show3dB( f3 );
showData( frequency, amplitude, phase, ArraySize );
setAutoReplot( doReplot );
replot();
}

31
qwt/examples/bode/plot.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef _PLOT_H_
#define _PLOT_H_
#include <qwt_plot.h>
class QwtPlotCurve;
class QwtPlotMarker;
class Plot: public QwtPlot
{
Q_OBJECT
public:
Plot( QWidget *parent );
public Q_SLOTS:
void setDamp( double damping );
private:
void showData( const double *frequency, const double *amplitude,
const double *phase, int count );
void showPeak( double freq, double amplitude );
void show3dB( double freq );
QwtPlotCurve *d_curve1;
QwtPlotCurve *d_curve2;
QwtPlotMarker *d_marker1;
QwtPlotMarker *d_marker2;
};
#endif

View File

@@ -0,0 +1,34 @@
################################################################
# Qwt Widget Library
# Copyright (C) 1997 Josef Wilgen
# Copyright (C) 2002 Uwe Rathmann
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the Qwt License, Version 1.0
################################################################
include( $${PWD}/../examples.pri )
TARGET = controls
HEADERS = \
sliderbox.h \
slidertab.h \
wheelbox.h \
wheeltab.h \
knobbox.h \
knobtab.h \
dialbox.h \
dialtab.h
SOURCES = \
sliderbox.cpp \
slidertab.cpp \
wheelbox.cpp \
wheeltab.cpp \
knobbox.cpp \
knobtab.cpp \
dialbox.cpp \
dialtab.cpp \
main.cpp

View File

@@ -0,0 +1,163 @@
#include <qlabel.h>
#include <qlayout.h>
#include <qwt_dial.h>
#include <qwt_dial_needle.h>
#include <qwt_scale_engine.h>
#include <qwt_transform.h>
#include <qwt_round_scale_draw.h>
#include "dialbox.h"
DialBox::DialBox( QWidget *parent, int type ):
QWidget( parent )
{
d_dial = createDial( type );
d_label = new QLabel( this );
d_label->setAlignment( Qt::AlignCenter );
QVBoxLayout *layout = new QVBoxLayout( this );;
layout->setSpacing( 0 );
layout->addWidget( d_dial, 10 );
layout->addWidget( d_label );
connect( d_dial, SIGNAL( valueChanged( double ) ),
this, SLOT( setNum( double ) ) );
setNum( d_dial->value() );
}
QwtDial *DialBox::createDial( int type ) const
{
QwtDial *dial = new QwtDial();
dial->setTracking( true );
dial->setFocusPolicy( Qt::StrongFocus );
dial->setObjectName( QString( "Dial %1" ).arg( type + 1 ) );
QColor needleColor( Qt::red );
switch( type )
{
case 0:
{
dial->setOrigin( 135.0 );
dial->setScaleArc( 0.0, 270.0 );
dial->setScaleMaxMinor( 4 );
dial->setScaleMaxMajor( 10 );
dial->setScale( -100.0, 100.0 );
needleColor = QColor( "Goldenrod" );
break;
}
case 1:
{
dial->setOrigin( 135.0 );
dial->setScaleArc( 0.0, 270.0 );
dial->setScaleMaxMinor( 10 );
dial->setScaleMaxMajor( 10 );
dial->setScale( 10.0, 0.0 );
QwtRoundScaleDraw *scaleDraw = new QwtRoundScaleDraw();
scaleDraw->setSpacing( 8 );
scaleDraw->enableComponent(
QwtAbstractScaleDraw::Backbone, false );
scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 2 );
scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 4 );
scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 8 );
dial->setScaleDraw( scaleDraw );
break;
}
case 2:
{
dial->setOrigin( 150.0 );
dial->setScaleArc( 0.0, 240.0 );
QwtLinearScaleEngine *scaleEngine = new QwtLinearScaleEngine( 2 );
scaleEngine->setTransformation( new QwtPowerTransform( 2 ) );
dial->setScaleEngine( scaleEngine );
QList< double > ticks[ QwtScaleDiv::NTickTypes ];
ticks[ QwtScaleDiv::MajorTick ] << 0 << 4
<< 16 << 32 << 64 << 96 << 128;
ticks[ QwtScaleDiv::MediumTick ] << 24 << 48 << 80 << 112;
ticks[ QwtScaleDiv::MinorTick ]
<< 0.5 << 1 << 2
<< 7 << 10 << 13
<< 20 << 28
<< 40 << 56
<< 72 << 88
<< 104 << 120;
dial->setScale( QwtScaleDiv( 0, 128, ticks ) );
break;
}
case 3:
{
dial->setOrigin( 135.0 );
dial->setScaleArc( 0.0, 270.0 );
dial->setScaleMaxMinor( 9 );
dial->setScaleEngine( new QwtLogScaleEngine );
dial->setScale( 1.0e-2, 1.0e2 );
break;
}
case 4:
{
dial->setOrigin( 225.0 );
dial->setScaleArc( 0.0, 360.0 );
dial->setScaleMaxMinor( 5 );
dial->setScaleStepSize( 20 );
dial->setScale( 100.0, -100.0 );
dial->setWrapping( true );
dial->setTotalSteps( 40 );
dial->setMode( QwtDial::RotateScale );
dial->setValue( 70.0 );
needleColor = QColor( "DarkSlateBlue" );
break;
}
case 5:
{
dial->setOrigin( 45.0 );
dial->setScaleArc( 0.0, 225.0 );
dial->setScaleMaxMinor( 5 );
dial->setScaleMaxMajor( 10 );
dial->setScale( 0.0, 10.0 );
break;
}
}
QwtDialSimpleNeedle *needle = new QwtDialSimpleNeedle(
QwtDialSimpleNeedle::Arrow, true, needleColor,
QColor( Qt::gray ).light( 130 ) );
dial->setNeedle( needle );
//const QColor base( QColor( "DimGray" ) );
const QColor base( QColor( Qt::darkGray ).dark( 150 ) );
QPalette palette;
palette.setColor( QPalette::Base, base );
palette.setColor( QPalette::Window, base.dark( 150 ) );
palette.setColor( QPalette::Mid, base.dark( 110 ) );
palette.setColor( QPalette::Light, base.light( 170 ) );
palette.setColor( QPalette::Dark, base.dark( 170 ) );
palette.setColor( QPalette::Text, base.dark( 200 ).light( 800 ) );
palette.setColor( QPalette::WindowText, base.dark( 200 ) );
dial->setPalette( palette );
dial->setLineWidth( 4 );
dial->setFrameShadow( QwtDial::Sunken );
return dial;
}
void DialBox::setNum( double v )
{
QString text;
text.setNum( v, 'f', 2 );
d_label->setText( text );
}

View File

@@ -0,0 +1,25 @@
#ifndef _DIAL_BOX_H_
#define _DIAL_BOX_H_
#include <qwidget.h>
class QLabel;
class QwtDial;
class DialBox: public QWidget
{
Q_OBJECT
public:
DialBox( QWidget *parent, int type );
private Q_SLOTS:
void setNum( double v );
private:
QwtDial *createDial( int type ) const;
QwtDial *d_dial;
QLabel *d_label;
};
#endif

View File

@@ -0,0 +1,17 @@
#include "dialtab.h"
#include "dialbox.h"
#include <qlayout.h>
DialTab::DialTab( QWidget *parent ):
QWidget( parent )
{
QGridLayout *layout = new QGridLayout( this );
const int numRows = 3;
for ( int i = 0; i < 2 * numRows; i++ )
{
DialBox *dialBox = new DialBox( this, i );
layout->addWidget( dialBox, i / numRows, i % numRows );
}
}

View File

@@ -0,0 +1,12 @@
#ifndef _DIAL_TAB_H
#define _DIAL_TAB_H 1
#include <qwidget.h>
class DialTab: public QWidget
{
public:
DialTab( QWidget *parent = NULL );
};
#endif

View File

@@ -0,0 +1,119 @@
#include <qlabel.h>
#include <qlayout.h>
#include <qwt_knob.h>
#include <qwt_scale_engine.h>
#include <qwt_transform.h>
#include "knobbox.h"
KnobBox::KnobBox( QWidget *parent, int knobType ):
QWidget( parent )
{
d_knob = createKnob( knobType );
d_knob->setKnobWidth( 100 );
d_label = new QLabel( this );
d_label->setAlignment( Qt::AlignCenter );
QVBoxLayout *layout = new QVBoxLayout( this );;
layout->setSpacing( 0 );
layout->addWidget( d_knob, 10 );
layout->addWidget( d_label );
layout->addStretch( 10 );
connect( d_knob, SIGNAL( valueChanged( double ) ),
this, SLOT( setNum( double ) ) );
setNum( d_knob->value() );
}
QwtKnob *KnobBox::createKnob( int knobType ) const
{
QwtKnob *knob = new QwtKnob();
knob->setTracking( true );
switch( knobType )
{
case 0:
{
knob->setKnobStyle( QwtKnob::Sunken );
knob->setMarkerStyle( QwtKnob::Nub );
knob->setWrapping( true );
knob->setNumTurns( 4 );
knob->setScaleStepSize( 10.0 );
knob->setScale( 0, 400 );
knob->setTotalSteps( 400 );
break;
}
case 1:
{
knob->setKnobStyle( QwtKnob::Sunken );
knob->setMarkerStyle( QwtKnob::Dot );
break;
}
case 2:
{
knob->setKnobStyle( QwtKnob::Sunken );
knob->setMarkerStyle( QwtKnob::Tick );
QwtLinearScaleEngine *scaleEngine = new QwtLinearScaleEngine( 2 );
scaleEngine->setTransformation( new QwtPowerTransform( 2 ) );
knob->setScaleEngine( scaleEngine );
QList< double > ticks[ QwtScaleDiv::NTickTypes ];
ticks[ QwtScaleDiv::MajorTick ] << 0 << 4
<< 16 << 32 << 64 << 96 << 128;
ticks[ QwtScaleDiv::MediumTick ] << 24 << 48 << 80 << 112;
ticks[ QwtScaleDiv::MinorTick ]
<< 0.5 << 1 << 2
<< 7 << 10 << 13
<< 20 << 28
<< 40 << 56
<< 72 << 88
<< 104 << 120;
knob->setScale( QwtScaleDiv( 0, 128, ticks ) );
knob->setTotalSteps( 100 );
knob->setStepAlignment( false );
knob->setSingleSteps( 1 );
knob->setPageSteps( 5 );
break;
}
case 3:
{
knob->setKnobStyle( QwtKnob::Flat );
knob->setMarkerStyle( QwtKnob::Notch );
knob->setScaleEngine( new QwtLogScaleEngine() );
knob->setScaleStepSize( 1.0 );
knob->setScale( 0.1, 1000.0 );
knob->setScaleMaxMinor( 10 );
break;
}
case 4:
{
knob->setKnobStyle( QwtKnob::Raised );
knob->setMarkerStyle( QwtKnob::Dot );
knob->setWrapping( true );
break;
}
case 5:
{
knob->setKnobStyle( QwtKnob::Styled );
knob->setMarkerStyle( QwtKnob::Triangle );
knob->setTotalAngle( 180.0 );
knob->setScale( 100, -100 );
break;
}
}
return knob;
}
void KnobBox::setNum( double v )
{
QString text;
text.setNum( v, 'f', 2 );
d_label->setText( text );
}

View File

@@ -0,0 +1,25 @@
#ifndef _KNOB_BOX_H_
#define _KNOB_BOX_H_
#include <qwidget.h>
class QLabel;
class QwtKnob;
class KnobBox: public QWidget
{
Q_OBJECT
public:
KnobBox( QWidget *parent, int knobType );
private Q_SLOTS:
void setNum( double v );
private:
QwtKnob *createKnob( int knobType ) const;
QwtKnob *d_knob;
QLabel *d_label;
};
#endif

View File

@@ -0,0 +1,17 @@
#include "knobtab.h"
#include "knobbox.h"
#include <qlayout.h>
KnobTab::KnobTab( QWidget *parent ):
QWidget( parent )
{
QGridLayout *layout = new QGridLayout( this );
const int numRows = 3;
for ( int i = 0; i < 2 * numRows; i++ )
{
KnobBox *knobBox = new KnobBox( this, i );
layout->addWidget( knobBox, i / numRows, i % numRows );
}
}

View File

@@ -0,0 +1,12 @@
#ifndef _KNOB_TAB_H
#define _KNOB_TAB_H 1
#include <qwidget.h>
class KnobTab: public QWidget
{
public:
KnobTab( QWidget *parent = NULL );
};
#endif

View File

@@ -0,0 +1,41 @@
#include <qapplication.h>
#include <qtabwidget.h>
#include "slidertab.h"
#include "wheeltab.h"
#include "knobtab.h"
#include "dialtab.h"
int main ( int argc, char **argv )
{
QApplication a( argc, argv );
QTabWidget tabWidget;
SliderTab *sliderTab = new SliderTab();
sliderTab->setAutoFillBackground( true );
sliderTab->setPalette( QColor( "DimGray" ) );
WheelTab *wheelTab = new WheelTab();
wheelTab->setAutoFillBackground( true );
wheelTab->setPalette( QColor( "Silver" ) );
KnobTab *knobTab = new KnobTab();
knobTab->setAutoFillBackground( true );
knobTab->setPalette( Qt::darkGray );
DialTab *dialTab = new DialTab();
dialTab->setAutoFillBackground( true );
dialTab->setPalette( Qt::darkGray );
tabWidget.addTab( new SliderTab, "Slider" );
tabWidget.addTab( new WheelTab, "Wheel/Thermo" );
tabWidget.addTab( knobTab, "Knob" );
tabWidget.addTab( dialTab, "Dial" );
tabWidget.resize( 800, 600 );
tabWidget.show();
return a.exec();
}

View File

@@ -0,0 +1,172 @@
#include <qlabel.h>
#include <qlayout.h>
#include <qwt_slider.h>
#include <qwt_scale_engine.h>
#include <qwt_transform.h>
#include "sliderbox.h"
SliderBox::SliderBox( int sliderType, QWidget *parent ):
QWidget( parent )
{
d_slider = createSlider( sliderType );
QFlags<Qt::AlignmentFlag> alignment;
if ( d_slider->orientation() == Qt::Horizontal )
{
if ( d_slider->scalePosition() == QwtSlider::TrailingScale )
alignment = Qt::AlignBottom;
else
alignment = Qt::AlignTop;
alignment |= Qt::AlignHCenter;
}
else
{
if ( d_slider->scalePosition() == QwtSlider::TrailingScale )
alignment = Qt::AlignRight;
else
alignment = Qt::AlignLeft;
alignment |= Qt::AlignVCenter;
}
d_label = new QLabel( this );
d_label->setAlignment( alignment );
d_label->setFixedWidth( d_label->fontMetrics().width( "10000.9" ) );
connect( d_slider, SIGNAL( valueChanged( double ) ), SLOT( setNum( double ) ) );
QBoxLayout *layout;
if ( d_slider->orientation() == Qt::Horizontal )
layout = new QHBoxLayout( this );
else
layout = new QVBoxLayout( this );
layout->addWidget( d_slider );
layout->addWidget( d_label );
setNum( d_slider->value() );
}
QwtSlider *SliderBox::createSlider( int sliderType ) const
{
QwtSlider *slider = new QwtSlider();
switch( sliderType )
{
case 0:
{
slider->setOrientation( Qt::Horizontal );
slider->setScalePosition( QwtSlider::TrailingScale );
slider->setTrough( true );
slider->setGroove( false );
slider->setSpacing( 0 );
slider->setHandleSize( QSize( 30, 16 ) );
slider->setScale( 10.0, -10.0 );
slider->setTotalSteps( 8 );
slider->setSingleSteps( 1 );
slider->setPageSteps( 1 );
slider->setWrapping( true );
break;
}
case 1:
{
slider->setOrientation( Qt::Horizontal );
slider->setScalePosition( QwtSlider::NoScale );
slider->setTrough( true );
slider->setGroove( true );
slider->setScale( 0.0, 1.0 );
slider->setTotalSteps( 100 );
slider->setSingleSteps( 1 );
slider->setPageSteps( 5 );
break;
}
case 2:
{
slider->setOrientation( Qt::Horizontal );
slider->setScalePosition( QwtSlider::LeadingScale );
slider->setTrough( false );
slider->setGroove( true );
slider->setHandleSize( QSize( 12, 25 ) );
slider->setScale( 1000.0, 3000.0 );
slider->setTotalSteps( 200.0 );
slider->setSingleSteps( 2 );
slider->setPageSteps( 10 );
break;
}
case 3:
{
slider->setOrientation( Qt::Horizontal );
slider->setScalePosition( QwtSlider::TrailingScale );
slider->setTrough( true );
slider->setGroove( true );
QwtLinearScaleEngine *scaleEngine = new QwtLinearScaleEngine( 2 );
scaleEngine->setTransformation( new QwtPowerTransform( 2 ) );
slider->setScaleEngine( scaleEngine );
slider->setScale( 0.0, 128.0 );
slider->setTotalSteps( 100 );
slider->setStepAlignment( false );
slider->setSingleSteps( 1 );
slider->setPageSteps( 5 );
break;
}
case 4:
{
slider->setOrientation( Qt::Vertical );
slider->setScalePosition( QwtSlider::TrailingScale );
slider->setTrough( false );
slider->setGroove( true );
slider->setScale( 100.0, 0.0 );
slider->setInvertedControls( true );
slider->setTotalSteps( 100 );
slider->setPageSteps( 5 );
slider->setScaleMaxMinor( 5 );
break;
}
case 5:
{
slider->setOrientation( Qt::Vertical );
slider->setScalePosition( QwtSlider::NoScale );
slider->setTrough( true );
slider->setGroove( false );
slider->setScale( 0.0, 100.0 );
slider->setTotalSteps( 100 );
slider->setPageSteps( 10 );
break;
}
case 6:
{
slider->setOrientation( Qt::Vertical );
slider->setScalePosition( QwtSlider::LeadingScale );
slider->setTrough( true );
slider->setGroove( true );
slider->setScaleEngine( new QwtLogScaleEngine );
slider->setStepAlignment( false );
slider->setHandleSize( QSize( 20, 32 ) );
slider->setBorderWidth( 1 );
slider->setScale( 1.0, 1.0e4 );
slider->setTotalSteps( 100 );
slider->setPageSteps( 10 );
slider->setScaleMaxMinor( 9 );
break;
}
}
if ( slider )
{
QString name( "Slider %1" );
slider->setObjectName( name.arg( sliderType ) );
}
return slider;
}
void SliderBox::setNum( double v )
{
QString text;
text.setNum( v, 'f', 2 );
d_label->setText( text );
}

View File

@@ -0,0 +1,25 @@
#ifndef _SLIDER_BOX_H_
#define _SLIDER_BOX_H_ 1
#include <qwidget.h>
class QLabel;
class QwtSlider;
class SliderBox: public QWidget
{
Q_OBJECT
public:
SliderBox( int sliderType, QWidget *parent = NULL );
private Q_SLOTS:
void setNum( double v );
private:
QwtSlider *createSlider( int sliderType ) const;
QwtSlider *d_slider;
QLabel *d_label;
};
#endif

View File

@@ -0,0 +1,37 @@
#include "slidertab.h"
#include "sliderbox.h"
#include <qlayout.h>
SliderTab::SliderTab( QWidget *parent ):
QWidget( parent )
{
int i;
QBoxLayout *hLayout = createLayout( Qt::Vertical );
for ( i = 0; i < 4; i++ )
hLayout->addWidget( new SliderBox( i ) );
hLayout->addStretch();
QBoxLayout *vLayout = createLayout( Qt::Horizontal );
for ( ; i < 7; i++ )
vLayout->addWidget( new SliderBox( i ) );
QBoxLayout *mainLayout = createLayout( Qt::Horizontal, this );
mainLayout->addLayout( vLayout );
mainLayout->addLayout( hLayout, 10 );
}
QBoxLayout *SliderTab::createLayout(
Qt::Orientation orientation, QWidget *widget )
{
QBoxLayout *layout =
new QBoxLayout( QBoxLayout::LeftToRight, widget );
if ( orientation == Qt::Vertical )
layout->setDirection( QBoxLayout::TopToBottom );
layout->setSpacing( 20 );
layout->setMargin( 0 );
return layout;
}

View File

@@ -0,0 +1,18 @@
#ifndef _SLIDER_TAB_H
#define _SLIDER_TAB_H 1
#include <qwidget.h>
class QBoxLayout;
class SliderTab: public QWidget
{
public:
SliderTab( QWidget *parent = NULL );
private:
QBoxLayout *createLayout( Qt::Orientation,
QWidget *widget = NULL );
};
#endif

View File

@@ -0,0 +1,188 @@
#include <qlabel.h>
#include <qlayout.h>
#include <qwt_wheel.h>
#include <qwt_thermo.h>
#include <qwt_scale_engine.h>
#include <qwt_transform.h>
#include <qwt_color_map.h>
#include "wheelbox.h"
WheelBox::WheelBox( Qt::Orientation orientation,
int type, QWidget *parent ):
QWidget( parent )
{
QWidget *box = createBox( orientation, type );
d_label = new QLabel( this );
d_label->setAlignment( Qt::AlignHCenter | Qt::AlignTop );
QBoxLayout *layout = new QVBoxLayout( this );
layout->addWidget( box );
layout->addWidget( d_label );
setNum( d_wheel->value() );
connect( d_wheel, SIGNAL( valueChanged( double ) ),
this, SLOT( setNum( double ) ) );
}
QWidget *WheelBox::createBox(
Qt::Orientation orientation, int type )
{
d_wheel = new QwtWheel();
d_wheel->setValue( 80 );
d_wheel->setWheelWidth( 20 );
d_wheel->setMass( 1.0 );
d_thermo = new QwtThermo();
d_thermo->setOrientation( orientation );
if ( orientation == Qt::Horizontal )
{
d_thermo->setScalePosition( QwtThermo::LeadingScale );
d_wheel->setOrientation( Qt::Vertical );
}
else
{
d_thermo->setScalePosition( QwtThermo::TrailingScale );
d_wheel->setOrientation( Qt::Horizontal );
}
switch( type )
{
case 0:
{
QwtLinearColorMap *colorMap = new QwtLinearColorMap();
colorMap->setColorInterval( Qt::blue, Qt::red );
d_thermo->setColorMap( colorMap );
break;
}
case 1:
{
QwtLinearColorMap *colorMap = new QwtLinearColorMap();
colorMap->setMode( QwtLinearColorMap::FixedColors );
int idx = 4;
colorMap->setColorInterval( Qt::GlobalColor( idx ),
Qt::GlobalColor( idx + 10 ) );
for ( int i = 1; i < 10; i++ )
{
colorMap->addColorStop( i / 10.0,
Qt::GlobalColor( idx + i ) );
}
d_thermo->setColorMap( colorMap );
break;
}
case 2:
{
d_wheel->setRange( 10, 1000 );
d_wheel->setSingleStep( 1.0 );
d_thermo->setScaleEngine( new QwtLogScaleEngine );
d_thermo->setScaleMaxMinor( 10 );
d_thermo->setFillBrush( Qt::darkCyan );
d_thermo->setAlarmBrush( Qt::magenta );
d_thermo->setAlarmLevel( 500.0 );
d_wheel->setValue( 800 );
break;
}
case 3:
{
d_wheel->setRange( -1000, 1000 );
d_wheel->setSingleStep( 1.0 );
d_wheel->setPalette( QColor( "Tan" ) );
QwtLinearScaleEngine *scaleEngine = new QwtLinearScaleEngine();
scaleEngine->setTransformation( new QwtPowerTransform( 2 ) );
d_thermo->setScaleMaxMinor( 5 );
d_thermo->setScaleEngine( scaleEngine );
QPalette pal = palette();
pal.setColor( QPalette::Base, Qt::darkGray );
pal.setColor( QPalette::ButtonText, QColor( "darkKhaki" ) );
d_thermo->setPalette( pal );
break;
}
case 4:
{
d_wheel->setRange( -100, 300 );
d_wheel->setInverted( true );
QwtLinearColorMap *colorMap = new QwtLinearColorMap();
colorMap->setColorInterval( Qt::darkCyan, Qt::yellow );
d_thermo->setColorMap( colorMap );
d_wheel->setValue( 243 );
break;
}
case 5:
{
d_thermo->setFillBrush( Qt::darkCyan );
d_thermo->setAlarmBrush( Qt::magenta );
d_thermo->setAlarmLevel( 60.0 );
break;
}
case 6:
{
d_thermo->setOriginMode( QwtThermo::OriginMinimum );
d_thermo->setFillBrush( QBrush( "DarkSlateBlue" ) );
d_thermo->setAlarmBrush( QBrush( "DarkOrange" ) );
d_thermo->setAlarmLevel( 60.0 );
break;
}
case 7:
{
d_wheel->setRange( -100, 100 );
d_thermo->setOriginMode( QwtThermo::OriginCustom );
d_thermo->setOrigin( 0.0 );
d_thermo->setFillBrush( Qt::darkBlue );
break;
}
}
double min = d_wheel->minimum();
double max = d_wheel->maximum();
if ( d_wheel->isInverted() )
qSwap( min, max );
d_thermo->setScale( min, max );
d_thermo->setValue( d_wheel->value() );
connect( d_wheel, SIGNAL( valueChanged( double ) ),
d_thermo, SLOT( setValue( double ) ) );
QWidget *box = new QWidget();
QBoxLayout *layout;
if ( orientation == Qt::Horizontal )
layout = new QHBoxLayout( box );
else
layout = new QVBoxLayout( box );
layout->addWidget( d_thermo, Qt::AlignCenter );
layout->addWidget( d_wheel );
return box;
}
void WheelBox::setNum( double v )
{
QString text;
text.setNum( v, 'f', 2 );
d_label->setText( text );
}

View File

@@ -0,0 +1,29 @@
#ifndef _WHEEL_BOX_H_
#define _WHEEL_BOX_H_ 1
#include <qwidget.h>
class QLabel;
class QwtThermo;
class QwtWheel;
class WheelBox: public QWidget
{
Q_OBJECT
public:
WheelBox( Qt::Orientation,
int type, QWidget *parent = NULL );
private Q_SLOTS:
void setNum( double v );
private:
QWidget *createBox( Qt::Orientation, int type );
private:
QwtWheel *d_wheel;
QwtThermo *d_thermo;
QLabel *d_label;
};
#endif

View File

@@ -0,0 +1,28 @@
#include "wheeltab.h"
#include "wheelbox.h"
#include <qlayout.h>
WheelTab::WheelTab( QWidget *parent ):
QWidget( parent )
{
const int numBoxes = 4;
QGridLayout *layout1 = new QGridLayout();
for ( int i = 0; i < numBoxes; i++ )
{
WheelBox *box = new WheelBox( Qt::Vertical, i );
layout1->addWidget( box, i / 2, i % 2 );
}
QGridLayout *layout2 = new QGridLayout();
for ( int i = 0; i < numBoxes; i++ )
{
WheelBox *box = new WheelBox( Qt::Horizontal, i + numBoxes );
layout2->addWidget( box, i / 2, i % 2 );
}
QHBoxLayout *layout = new QHBoxLayout( this );
layout->addLayout( layout1, 2 );
layout->addLayout( layout2, 5 );
}

View File

@@ -0,0 +1,12 @@
#ifndef _WHEEL_TAB_H
#define _WHEEL_TAB_H 1
#include <qwidget.h>
class WheelTab: public QWidget
{
public:
WheelTab( QWidget *parent = NULL );
};
#endif

View File

@@ -0,0 +1,55 @@
#include <qpainter.h>
#include <qwt_scale_map.h>
#include <qwt_plot_curve.h>
#include "cpuplot.h"
#include "cpupiemarker.h"
CpuPieMarker::CpuPieMarker()
{
setZ( 1000 );
setRenderHint( QwtPlotItem::RenderAntialiased, true );
}
int CpuPieMarker::rtti() const
{
return QwtPlotItem::Rtti_PlotUserItem;
}
void CpuPieMarker::draw( QPainter *painter,
const QwtScaleMap &, const QwtScaleMap &,
const QRectF &rect ) const
{
const CpuPlot *cpuPlot = static_cast<CpuPlot *> ( plot() );
const QwtScaleMap yMap = cpuPlot->canvasMap( QwtAxis::yLeft );
const int margin = 5;
QRectF pieRect;
pieRect.setX( rect.x() + margin );
pieRect.setY( rect.y() + margin );
pieRect.setHeight( yMap.transform( 80.0 ) );
pieRect.setWidth( pieRect.height() );
const int dataType[] = { CpuPlot::User, CpuPlot::System, CpuPlot::Idle };
int angle = static_cast<int>( 5760 * 0.75 );
for ( unsigned int i = 0;
i < sizeof( dataType ) / sizeof( dataType[0] ); i++ )
{
const QwtPlotCurve *curve = cpuPlot->cpuCurve( dataType[i] );
if ( curve->dataSize() > 0 )
{
const int value = static_cast<int>( 5760 * curve->sample( 0 ).y() / 100.0 );
painter->save();
painter->setBrush( QBrush( curve->pen().color(), Qt::SolidPattern ) );
if ( value != 0 )
painter->drawPie( pieRect, -angle, -value );
painter->restore();
angle += value;
}
}
}

View File

@@ -0,0 +1,17 @@
//-----------------------------------------------------------------
// This class shows how to extend QwtPlotItems. It displays a
// pie chart of user/total/idle cpu usage in percent.
//-----------------------------------------------------------------
#include <qwt_plot_item.h>
class CpuPieMarker: public QwtPlotItem
{
public:
CpuPieMarker();
virtual int rtti() const;
virtual void draw( QPainter *,
const QwtScaleMap &, const QwtScaleMap &, const QRectF & ) const;
};

View File

@@ -0,0 +1,254 @@
#include <qapplication.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qpainter.h>
#include <qwt_plot_layout.h>
#include <qwt_plot_curve.h>
#include <qwt_scale_draw.h>
#include <qwt_scale_widget.h>
#include <qwt_legend.h>
#include <qwt_legend_label.h>
#include <qwt_plot_canvas.h>
#include "cpupiemarker.h"
#include "cpuplot.h"
class TimeScaleDraw: public QwtScaleDraw
{
public:
TimeScaleDraw( const QTime &base ):
baseTime( base )
{
}
virtual QwtText label( double v ) const
{
QTime upTime = baseTime.addSecs( static_cast<int>( v ) );
return upTime.toString();
}
private:
QTime baseTime;
};
class Background: public QwtPlotItem
{
public:
Background()
{
setZ( 0.0 );
}
virtual int rtti() const
{
return QwtPlotItem::Rtti_PlotUserItem;
}
virtual void draw( QPainter *painter,
const QwtScaleMap &, const QwtScaleMap &yMap,
const QRectF &canvasRect ) const
{
QColor c( Qt::white );
QRectF r = canvasRect;
for ( int i = 100; i > 0; i -= 10 )
{
r.setBottom( yMap.transform( i - 10 ) );
r.setTop( yMap.transform( i ) );
painter->fillRect( r, c );
c = c.dark( 110 );
}
}
};
class CpuCurve: public QwtPlotCurve
{
public:
CpuCurve( const QString &title ):
QwtPlotCurve( title )
{
setRenderHint( QwtPlotItem::RenderAntialiased );
}
void setColor( const QColor &color )
{
QColor c = color;
c.setAlpha( 150 );
setPen( c );
setBrush( c );
}
};
CpuPlot::CpuPlot( QWidget *parent ):
QwtPlot( parent ),
dataCount( 0 )
{
setAutoReplot( false );
QwtPlotCanvas *canvas = new QwtPlotCanvas();
canvas->setBorderRadius( 10 );
setCanvas( canvas );
plotLayout()->setAlignCanvasToScales( true );
QwtLegend *legend = new QwtLegend;
legend->setDefaultItemMode( QwtLegendData::Checkable );
insertLegend( legend, QwtPlot::RightLegend );
setAxisTitle( QwtAxis::xBottom, " System Uptime [h:m:s]" );
setAxisScaleDraw( QwtAxis::xBottom,
new TimeScaleDraw( cpuStat.upTime() ) );
setAxisScale( QwtAxis::xBottom, 0, HISTORY );
setAxisLabelRotation( QwtAxis::xBottom, -50.0 );
setAxisLabelAlignment( QwtAxis::xBottom, Qt::AlignLeft | Qt::AlignBottom );
/*
In situations, when there is a label at the most right position of the
scale, additional space is needed to display the overlapping part
of the label would be taken by reducing the width of scale and canvas.
To avoid this "jumping canvas" effect, we add a permanent margin.
We don't need to do the same for the left border, because there
is enough space for the overlapping label below the left scale.
*/
QwtScaleWidget *scaleWidget = axisWidget( QwtAxis::xBottom );
const int fmh = QFontMetrics( scaleWidget->font() ).height();
scaleWidget->setMinBorderDist( 0, fmh / 2 );
setAxisTitle( QwtAxis::yLeft, "Cpu Usage [%]" );
setAxisScale( QwtAxis::yLeft, 0, 100 );
Background *bg = new Background();
bg->attach( this );
CpuPieMarker *pie = new CpuPieMarker();
pie->attach( this );
CpuCurve *curve;
curve = new CpuCurve( "System" );
curve->setColor( Qt::red );
curve->attach( this );
data[System].curve = curve;
curve = new CpuCurve( "User" );
curve->setColor( Qt::blue );
curve->setZ( curve->z() - 1 );
curve->attach( this );
data[User].curve = curve;
curve = new CpuCurve( "Total" );
curve->setColor( Qt::black );
curve->setZ( curve->z() - 2 );
curve->attach( this );
data[Total].curve = curve;
curve = new CpuCurve( "Idle" );
curve->setColor( Qt::darkCyan );
curve->setZ( curve->z() - 3 );
curve->attach( this );
data[Idle].curve = curve;
showCurve( data[System].curve, true );
showCurve( data[User].curve, true );
showCurve( data[Total].curve, false );
showCurve( data[Idle].curve, false );
for ( int i = 0; i < HISTORY; i++ )
timeData[HISTORY - 1 - i] = i;
( void )startTimer( 1000 ); // 1 second
connect( legend, SIGNAL( checked( const QVariant &, bool, int ) ),
SLOT( legendChecked( const QVariant &, bool ) ) );
}
void CpuPlot::timerEvent( QTimerEvent * )
{
for ( int i = dataCount; i > 0; i-- )
{
for ( int c = 0; c < NCpuData; c++ )
{
if ( i < HISTORY )
data[c].data[i] = data[c].data[i-1];
}
}
cpuStat.statistic( data[User].data[0], data[System].data[0] );
data[Total].data[0] = data[User].data[0] + data[System].data[0];
data[Idle].data[0] = 100.0 - data[Total].data[0];
if ( dataCount < HISTORY )
dataCount++;
for ( int j = 0; j < HISTORY; j++ )
timeData[j]++;
setAxisScale( QwtAxis::xBottom,
timeData[HISTORY - 1], timeData[0] );
for ( int c = 0; c < NCpuData; c++ )
{
data[c].curve->setRawSamples(
timeData, data[c].data, dataCount );
}
replot();
}
void CpuPlot::legendChecked( const QVariant &itemInfo, bool on )
{
QwtPlotItem *plotItem = infoToItem( itemInfo );
if ( plotItem )
showCurve( plotItem, on );
}
void CpuPlot::showCurve( QwtPlotItem *item, bool on )
{
item->setVisible( on );
QwtLegend *lgd = qobject_cast<QwtLegend *>( legend() );
QList<QWidget *> legendWidgets =
lgd->legendWidgets( itemToInfo( item ) );
if ( legendWidgets.size() == 1 )
{
QwtLegendLabel *legendLabel =
qobject_cast<QwtLegendLabel *>( legendWidgets[0] );
if ( legendLabel )
legendLabel->setChecked( on );
}
replot();
}
int main( int argc, char **argv )
{
QApplication a( argc, argv );
QWidget vBox;
vBox.setWindowTitle( "Cpu Plot" );
CpuPlot *plot = new CpuPlot( &vBox );
plot->setTitle( "History" );
const int margin = 5;
plot->setContentsMargins( margin, margin, margin, margin );
QString info( "Press the legend to en/disable a curve" );
QLabel *label = new QLabel( info, &vBox );
QVBoxLayout *layout = new QVBoxLayout( &vBox );
layout->addWidget( plot );
layout->addWidget( label );
vBox.resize( 600, 400 );
vBox.show();
return a.exec();
}

View File

@@ -0,0 +1,47 @@
#include <qwt_plot.h>
#include "cpustat.h"
#define HISTORY 60 // seconds
class QwtPlotCurve;
class CpuPlot : public QwtPlot
{
Q_OBJECT
public:
enum CpuData
{
User,
System,
Total,
Idle,
NCpuData
};
CpuPlot( QWidget * = 0 );
const QwtPlotCurve *cpuCurve( int id ) const
{
return data[id].curve;
}
protected:
void timerEvent( QTimerEvent *e );
private Q_SLOTS:
void legendChecked( const QVariant &, bool on );
private:
void showCurve( QwtPlotItem *, bool on );
struct
{
QwtPlotCurve *curve;
double data[HISTORY];
} data[NCpuData];
double timeData[HISTORY];
int dataCount;
CpuStat cpuStat;
};

View File

@@ -0,0 +1,22 @@
################################################################
# Qwt Widget Library
# Copyright (C) 1997 Josef Wilgen
# Copyright (C) 2002 Uwe Rathmann
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the Qwt License, Version 1.0
################################################################
include( $${PWD}/../examples.pri )
TARGET = cpuplot
HEADERS = \
cpuplot.h \
cpustat.h \
cpupiemarker.h
SOURCES = \
cpuplot.cpp \
cpustat.cpp \
cpupiemarker.cpp

View File

@@ -0,0 +1,220 @@
#include <qstringlist.h>
#include <qfile.h>
#include <qtextstream.h>
#include "cpustat.h"
CpuStat::CpuStat()
{
lookUp( procValues );
}
QTime CpuStat::upTime() const
{
QTime t( 0, 0, 0 );
for ( int i = 0; i < NValues; i++ )
t = t.addSecs( int( procValues[i] / 100 ) );
return t;
}
void CpuStat::statistic( double &user, double &system )
{
double values[NValues];
lookUp( values );
double userDelta = values[User] + values[Nice]
- procValues[User] - procValues[Nice];
double systemDelta = values[System] - procValues[System];
double totalDelta = 0;
for ( int i = 0; i < NValues; i++ )
totalDelta += values[i] - procValues[i];
user = userDelta / totalDelta * 100.0;
system = systemDelta / totalDelta * 100.0;
for ( int j = 0; j < NValues; j++ )
procValues[j] = values[j];
}
void CpuStat::lookUp( double values[NValues] ) const
{
QFile file( "/proc/stat" );
if ( !file.open( QIODevice::ReadOnly ) )
{
static double dummyValues[][NValues] =
{
{ 103726, 0, 23484, 819556 },
{ 103783, 0, 23489, 819604 },
{ 103798, 0, 23490, 819688 },
{ 103820, 0, 23490, 819766 },
{ 103840, 0, 23493, 819843 },
{ 103875, 0, 23499, 819902 },
{ 103917, 0, 23504, 819955 },
{ 103950, 0, 23508, 820018 },
{ 103987, 0, 23510, 820079 },
{ 104020, 0, 23513, 820143 },
{ 104058, 0, 23514, 820204 },
{ 104099, 0, 23520, 820257 },
{ 104121, 0, 23525, 820330 },
{ 104159, 0, 23530, 820387 },
{ 104176, 0, 23534, 820466 },
{ 104215, 0, 23538, 820523 },
{ 104245, 0, 23541, 820590 },
{ 104267, 0, 23545, 820664 },
{ 104311, 0, 23555, 820710 },
{ 104355, 0, 23565, 820756 },
{ 104367, 0, 23567, 820842 },
{ 104383, 0, 23572, 820921 },
{ 104396, 0, 23577, 821003 },
{ 104413, 0, 23579, 821084 },
{ 104446, 0, 23588, 821142 },
{ 104521, 0, 23594, 821161 },
{ 104611, 0, 23604, 821161 },
{ 104708, 0, 23607, 821161 },
{ 104804, 0, 23611, 821161 },
{ 104895, 0, 23620, 821161 },
{ 104993, 0, 23622, 821161 },
{ 105089, 0, 23626, 821161 },
{ 105185, 0, 23630, 821161 },
{ 105281, 0, 23634, 821161 },
{ 105379, 0, 23636, 821161 },
{ 105472, 0, 23643, 821161 },
{ 105569, 0, 23646, 821161 },
{ 105666, 0, 23649, 821161 },
{ 105763, 0, 23652, 821161 },
{ 105828, 0, 23661, 821187 },
{ 105904, 0, 23666, 821206 },
{ 105999, 0, 23671, 821206 },
{ 106094, 0, 23676, 821206 },
{ 106184, 0, 23686, 821206 },
{ 106273, 0, 23692, 821211 },
{ 106306, 0, 23700, 821270 },
{ 106341, 0, 23703, 821332 },
{ 106392, 0, 23709, 821375 },
{ 106423, 0, 23715, 821438 },
{ 106472, 0, 23721, 821483 },
{ 106531, 0, 23727, 821517 },
{ 106562, 0, 23732, 821582 },
{ 106597, 0, 23736, 821643 },
{ 106633, 0, 23737, 821706 },
{ 106666, 0, 23742, 821768 },
{ 106697, 0, 23744, 821835 },
{ 106730, 0, 23748, 821898 },
{ 106765, 0, 23751, 821960 },
{ 106799, 0, 23754, 822023 },
{ 106831, 0, 23758, 822087 },
{ 106862, 0, 23761, 822153 },
{ 106899, 0, 23763, 822214 },
{ 106932, 0, 23766, 822278 },
{ 106965, 0, 23768, 822343 },
{ 107009, 0, 23771, 822396 },
{ 107040, 0, 23775, 822461 },
{ 107092, 0, 23780, 822504 },
{ 107143, 0, 23787, 822546 },
{ 107200, 0, 23795, 822581 },
{ 107250, 0, 23803, 822623 },
{ 107277, 0, 23810, 822689 },
{ 107286, 0, 23810, 822780 },
{ 107313, 0, 23817, 822846 },
{ 107325, 0, 23818, 822933 },
{ 107332, 0, 23818, 823026 },
{ 107344, 0, 23821, 823111 },
{ 107357, 0, 23821, 823198 },
{ 107368, 0, 23823, 823284 },
{ 107375, 0, 23824, 823377 },
{ 107386, 0, 23825, 823465 },
{ 107396, 0, 23826, 823554 },
{ 107422, 0, 23830, 823624 },
{ 107434, 0, 23831, 823711 },
{ 107456, 0, 23835, 823785 },
{ 107468, 0, 23838, 823870 },
{ 107487, 0, 23840, 823949 },
{ 107515, 0, 23843, 824018 },
{ 107528, 0, 23846, 824102 },
{ 107535, 0, 23851, 824190 },
{ 107548, 0, 23853, 824275 },
{ 107562, 0, 23857, 824357 },
{ 107656, 0, 23863, 824357 },
{ 107751, 0, 23868, 824357 },
{ 107849, 0, 23870, 824357 },
{ 107944, 0, 23875, 824357 },
{ 108043, 0, 23876, 824357 },
{ 108137, 0, 23882, 824357 },
{ 108230, 0, 23889, 824357 },
{ 108317, 0, 23902, 824357 },
{ 108412, 0, 23907, 824357 },
{ 108511, 0, 23908, 824357 },
{ 108608, 0, 23911, 824357 },
{ 108704, 0, 23915, 824357 },
{ 108801, 0, 23918, 824357 },
{ 108891, 0, 23928, 824357 },
{ 108987, 0, 23932, 824357 },
{ 109072, 0, 23943, 824361 },
{ 109079, 0, 23943, 824454 },
{ 109086, 0, 23944, 824546 },
{ 109098, 0, 23950, 824628 },
{ 109108, 0, 23955, 824713 },
{ 109115, 0, 23957, 824804 },
{ 109122, 0, 23958, 824896 },
{ 109132, 0, 23959, 824985 },
{ 109142, 0, 23961, 825073 },
{ 109146, 0, 23962, 825168 },
{ 109153, 0, 23964, 825259 },
{ 109162, 0, 23966, 825348 },
{ 109168, 0, 23969, 825439 },
{ 109176, 0, 23971, 825529 },
{ 109185, 0, 23974, 825617 },
{ 109193, 0, 23977, 825706 },
{ 109198, 0, 23978, 825800 },
{ 109206, 0, 23978, 825892 },
{ 109212, 0, 23981, 825983 },
{ 109219, 0, 23981, 826076 },
{ 109225, 0, 23981, 826170 },
{ 109232, 0, 23984, 826260 },
{ 109242, 0, 23984, 826350 },
{ 109255, 0, 23986, 826435 },
{ 109268, 0, 23987, 826521 },
{ 109283, 0, 23990, 826603 },
{ 109288, 0, 23991, 826697 },
{ 109295, 0, 23993, 826788 },
{ 109308, 0, 23994, 826874 },
{ 109322, 0, 24009, 826945 },
{ 109328, 0, 24011, 827037 },
{ 109338, 0, 24012, 827126 },
{ 109347, 0, 24012, 827217 },
{ 109354, 0, 24017, 827305 },
{ 109367, 0, 24017, 827392 },
{ 109371, 0, 24019, 827486 },
};
static int counter = 0;
for ( int i = 0; i < NValues; i++ )
values[i] = dummyValues[counter][i];
counter = ( counter + 1 )
% ( sizeof( dummyValues ) / sizeof( dummyValues[0] ) );
}
else
{
QTextStream textStream( &file );
do
{
QString line = textStream.readLine();
line = line.trimmed();
if ( line.startsWith( "cpu " ) )
{
const QStringList valueList =
line.split( " ", QString::SkipEmptyParts );
if ( valueList.count() >= 5 )
{
for ( int i = 0; i < NValues; i++ )
values[i] = valueList[i+1].toDouble();
}
break;
}
}
while( !textStream.atEnd() );
}
}

View File

@@ -0,0 +1,23 @@
#include <qdatetime.h>
class CpuStat
{
public:
CpuStat();
void statistic( double &user, double &system );
QTime upTime() const;
enum Value
{
User,
Nice,
System,
Idle,
NValues
};
private:
void lookUp( double[NValues] ) const;
double procValues[NValues];
};

View File

@@ -0,0 +1,202 @@
#include <qwt_scale_map.h>
#include <qwt_plot_curve.h>
#include <qwt_symbol.h>
#include <qwt_math.h>
#include <qcolor.h>
#include <qpainter.h>
#include <qapplication.h>
#include <qframe.h>
//------------------------------------------------------------
// curvdemo1
//
// This example program features some of the different
// display styles of the QwtPlotCurve class
//------------------------------------------------------------
//
// Array Sizes
//
const int Size = 27;
const int CurvCnt = 6;
//
// Arrays holding the values
//
double xval[Size];
double yval[Size];
QwtScaleMap xMap;
QwtScaleMap yMap;
class MainWin : public QFrame
{
public:
MainWin();
protected:
virtual void paintEvent( QPaintEvent * );
void drawContents( QPainter *p );
private:
void shiftDown( QRect &rect, int offset ) const;
QwtPlotCurve d_curves[CurvCnt];
};
MainWin::MainWin()
{
int i;
xMap.setScaleInterval( -0.5, 10.5 );
yMap.setScaleInterval( -1.1, 1.1 );
//
// Frame style
//
setFrameStyle( QFrame::Box | QFrame::Raised );
setLineWidth( 2 );
setMidLineWidth( 3 );
//
// Calculate values
//
for( i = 0; i < Size; i++ )
{
xval[i] = double( i ) * 10.0 / double( Size - 1 );
yval[i] = qSin( xval[i] ) * qCos( 2.0 * xval[i] );
}
//
// define curve styles
//
i = 0;
d_curves[i].setSymbol( new QwtSymbol( QwtSymbol::Cross, Qt::NoBrush,
QPen( Qt::black ), QSize( 5, 5 ) ) );
d_curves[i].setPen( Qt::darkGreen );
d_curves[i].setStyle( QwtPlotCurve::Lines );
d_curves[i].setCurveAttribute( QwtPlotCurve::Fitted );
i++;
d_curves[i].setSymbol( new QwtSymbol( QwtSymbol::Ellipse, Qt::yellow,
QPen( Qt::blue ), QSize( 5, 5 ) ) );
d_curves[i].setPen( Qt::red );
d_curves[i].setStyle( QwtPlotCurve::Sticks );
i++;
d_curves[i].setPen( Qt::darkBlue );
d_curves[i].setStyle( QwtPlotCurve::Lines );
i++;
d_curves[i].setPen( Qt::darkBlue );
d_curves[i].setStyle( QwtPlotCurve::Lines );
d_curves[i].setRenderHint( QwtPlotItem::RenderAntialiased );
i++;
d_curves[i].setPen( Qt::darkCyan );
d_curves[i].setStyle( QwtPlotCurve::Steps );
i++;
d_curves[i].setSymbol( new QwtSymbol( QwtSymbol::XCross, Qt::NoBrush,
QPen( Qt::darkMagenta ), QSize( 5, 5 ) ) );
d_curves[i].setStyle( QwtPlotCurve::NoCurve );
i++;
//
// attach data
//
for( i = 0; i < CurvCnt; i++ )
d_curves[i].setRawSamples( xval, yval, Size );
}
void MainWin::shiftDown( QRect &rect, int offset ) const
{
rect.translate( 0, offset );
}
void MainWin::paintEvent( QPaintEvent *event )
{
QFrame::paintEvent( event );
QPainter painter( this );
painter.setClipRect( contentsRect() );
drawContents( &painter );
}
//
// REDRAW CONTENTS
//
void MainWin::drawContents( QPainter *painter )
{
int deltay, i;
QRect r = contentsRect();
deltay = r.height() / CurvCnt - 1;
r.setHeight( deltay );
//
// draw curves
//
for ( i = 0; i < CurvCnt; i++ )
{
xMap.setPaintInterval( r.left(), r.right() );
yMap.setPaintInterval( r.top(), r.bottom() );
painter->setRenderHint( QPainter::Antialiasing,
d_curves[i].testRenderHint( QwtPlotItem::RenderAntialiased ) );
d_curves[i].draw( painter, xMap, yMap, r );
shiftDown( r, deltay );
}
//
// draw titles
//
r = contentsRect(); // reset r
painter->setFont( QFont( "Helvetica", 8 ) );
const int alignment = Qt::AlignTop | Qt::AlignHCenter;
painter->setPen( Qt::black );
painter->drawText( 0, r.top(), r.width(), painter->fontMetrics().height(),
alignment, "Style: Line/Fitted, Symbol: Cross" );
shiftDown( r, deltay );
painter->drawText( 0, r.top(), r.width(), painter->fontMetrics().height(),
alignment, "Style: Sticks, Symbol: Ellipse" );
shiftDown( r, deltay );
painter->drawText( 0 , r.top(), r.width(), painter->fontMetrics().height(),
alignment, "Style: Lines, Symbol: None" );
shiftDown( r, deltay );
painter->drawText( 0 , r.top(), r.width(), painter->fontMetrics().height(),
alignment, "Style: Lines, Symbol: None, Antialiased" );
shiftDown( r, deltay );
painter->drawText( 0, r.top(), r.width(), painter->fontMetrics().height(),
alignment, "Style: Steps, Symbol: None" );
shiftDown( r, deltay );
painter->drawText( 0, r.top(), r.width(), painter->fontMetrics().height(),
alignment, "Style: NoCurve, Symbol: XCross" );
}
int main ( int argc, char **argv )
{
QApplication a( argc, argv );
MainWin w;
w.resize( 300, 600 );
w.show();
return a.exec();
}

View File

@@ -0,0 +1,15 @@
################################################################
# Qwt Widget Library
# Copyright (C) 1997 Josef Wilgen
# Copyright (C) 2002 Uwe Rathmann
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the Qwt License, Version 1.0
################################################################
include( $${PWD}/../examples.pri )
TARGET = curvdemo1
SOURCES = \
curvdemo1.cpp

View File

@@ -0,0 +1,127 @@
#include "attitude_indicator.h"
#include <qwt_point_polar.h>
#include <qwt_round_scale_draw.h>
#include <qevent.h>
#include <qpainter.h>
#include <qpolygon.h>
AttitudeIndicatorNeedle::AttitudeIndicatorNeedle( const QColor &color )
{
QPalette palette;
palette.setColor( QPalette::Text, color );
setPalette( palette );
}
void AttitudeIndicatorNeedle::drawNeedle( QPainter *painter,
double length, QPalette::ColorGroup colorGroup ) const
{
double triangleSize = length * 0.1;
double pos = length - 2.0;
QPainterPath path;
path.moveTo( pos, 0 );
path.lineTo( pos - 2 * triangleSize, triangleSize );
path.lineTo( pos - 2 * triangleSize, -triangleSize );
path.closeSubpath();
painter->setBrush( palette().brush( colorGroup, QPalette::Text ) );
painter->drawPath( path );
double l = length - 2;
painter->setPen( QPen( palette().color( colorGroup, QPalette::Text ), 3 ) );
painter->drawLine( QPointF( 0.0, -l ), QPointF( 0.0, l ) );
}
AttitudeIndicator::AttitudeIndicator(
QWidget *parent ):
QwtDial( parent ),
d_gradient( 0.0 )
{
QwtRoundScaleDraw *scaleDraw = new QwtRoundScaleDraw();
scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false );
scaleDraw->enableComponent( QwtAbstractScaleDraw::Labels, false );
setScaleDraw( scaleDraw );
setMode( RotateScale );
setWrapping( true );
setOrigin( 270.0 );
setScaleMaxMinor( 0 );
setScaleStepSize( 30.0 );
setScale( 0.0, 360.0 );
const QColor color = palette().color( QPalette::Text );
setNeedle( new AttitudeIndicatorNeedle( color ) );
}
void AttitudeIndicator::setGradient( double gradient )
{
if ( gradient < -1.0 )
gradient = -1.0;
else if ( gradient > 1.0 )
gradient = 1.0;
if ( d_gradient != gradient )
{
d_gradient = gradient;
update();
}
}
void AttitudeIndicator::drawScale( QPainter *painter,
const QPointF &center, double radius ) const
{
const double offset = 4.0;
const QPointF p0 = qwtPolar2Pos( center, offset, 1.5 * M_PI );
const double w = innerRect().width();
QPainterPath path;
path.moveTo( qwtPolar2Pos( p0, w, 0.0 ) );
path.lineTo( qwtPolar2Pos( path.currentPosition(), 2 * w, M_PI ) );
path.lineTo( qwtPolar2Pos( path.currentPosition(), w, 0.5 * M_PI ) );
path.lineTo( qwtPolar2Pos( path.currentPosition(), w, 0.0 ) );
painter->save();
painter->setClipPath( path ); // swallow 180 - 360 degrees
QwtDial::drawScale( painter, center, radius );
painter->restore();
}
void AttitudeIndicator::drawScaleContents( QPainter *painter,
const QPointF &, double ) const
{
int dir = 360 - qRound( origin() - value() ); // counter clockwise
int arc = 90 + qRound( gradient() * 90 );
const QColor skyColor( 38, 151, 221 );
painter->save();
painter->setBrush( skyColor );
painter->drawChord( scaleInnerRect(),
( dir - arc ) * 16, 2 * arc * 16 );
painter->restore();
}
void AttitudeIndicator::keyPressEvent( QKeyEvent *event )
{
switch( event->key() )
{
case Qt::Key_Plus:
{
setGradient( gradient() + 0.05 );
break;
}
case Qt::Key_Minus:
{
setGradient( gradient() - 0.05 );
break;
}
default:
QwtDial::keyPressEvent( event );
}
}

View File

@@ -0,0 +1,39 @@
#include <qwt_dial.h>
#include <qwt_dial_needle.h>
class AttitudeIndicatorNeedle: public QwtDialNeedle
{
public:
AttitudeIndicatorNeedle( const QColor & );
protected:
virtual void drawNeedle( QPainter *,
double length, QPalette::ColorGroup ) const;
};
class AttitudeIndicator: public QwtDial
{
Q_OBJECT
public:
AttitudeIndicator( QWidget *parent = NULL );
double angle() const { return value(); }
double gradient() const { return d_gradient; }
public Q_SLOTS:
void setGradient( double );
void setAngle( double angle ) { setValue( angle ); }
protected:
virtual void keyPressEvent( QKeyEvent * );
virtual void drawScale( QPainter *,
const QPointF &center, double radius ) const;
virtual void drawScaleContents( QPainter *painter,
const QPointF &center, double radius ) const;
private:
double d_gradient;
};

View File

@@ -0,0 +1,186 @@
#include <qlayout.h>
#include <qtimer.h>
#include <qwt_analog_clock.h>
#include <qwt_round_scale_draw.h>
#include "attitude_indicator.h"
#include "speedo_meter.h"
#include "cockpit_grid.h"
CockpitGrid::CockpitGrid( QWidget *parent ):
QFrame( parent )
{
setAutoFillBackground( true );
setPalette( colorTheme( QColor( Qt::darkGray ).dark( 150 ) ) );
QGridLayout *layout = new QGridLayout( this );
layout->setSpacing( 5 );
layout->setMargin( 0 );
int i;
for ( i = 0; i < 3; i++ )
{
QwtDial *dial = createDial( i );
layout->addWidget( dial, 0, i );
}
for ( i = 0; i < layout->columnCount(); i++ )
layout->setColumnStretch( i, 1 );
}
QwtDial *CockpitGrid::createDial( int pos )
{
QwtDial *dial = NULL;
switch( pos )
{
case 0:
{
d_clock = new QwtAnalogClock( this );
#if 0
// disable minor ticks
d_clock->scaleDraw()->setTickLength( QwtScaleDiv::MinorTick, 0 );
#endif
const QColor knobColor = QColor( Qt::gray ).light( 130 );
for ( int i = 0; i < QwtAnalogClock::NHands; i++ )
{
QColor handColor = QColor( Qt::gray ).light( 150 );
int width = 8;
if ( i == QwtAnalogClock::SecondHand )
{
handColor = Qt::gray;
width = 5;
}
QwtDialSimpleNeedle *hand = new QwtDialSimpleNeedle(
QwtDialSimpleNeedle::Arrow, true, handColor, knobColor );
hand->setWidth( width );
d_clock->setHand( static_cast<QwtAnalogClock::Hand>( i ), hand );
}
QTimer *timer = new QTimer( d_clock );
timer->connect( timer, SIGNAL( timeout() ),
d_clock, SLOT( setCurrentTime() ) );
timer->start( 1000 );
dial = d_clock;
break;
}
case 1:
{
d_speedo = new SpeedoMeter( this );
d_speedo->setScaleStepSize( 20.0 );
d_speedo->setScale( 0.0, 240.0 );
d_speedo->scaleDraw()->setPenWidth( 2 );
QTimer *timer = new QTimer( d_speedo );
timer->connect( timer, SIGNAL( timeout() ),
this, SLOT( changeSpeed() ) );
timer->start( 50 );
dial = d_speedo;
break;
}
case 2:
{
d_ai = new AttitudeIndicator( this );
d_ai->scaleDraw()->setPenWidth( 3 );
QTimer *gradientTimer = new QTimer( d_ai );
gradientTimer->connect( gradientTimer, SIGNAL( timeout() ),
this, SLOT( changeGradient() ) );
gradientTimer->start( 100 );
QTimer *angleTimer = new QTimer( d_ai );
angleTimer->connect( angleTimer, SIGNAL( timeout() ),
this, SLOT( changeAngle() ) );
angleTimer->start( 100 );
dial = d_ai;
break;
}
}
if ( dial )
{
dial->setReadOnly( true );
dial->setLineWidth( 4 );
dial->setFrameShadow( QwtDial::Sunken );
}
return dial;
}
QPalette CockpitGrid::colorTheme( const QColor &base ) const
{
QPalette palette;
palette.setColor( QPalette::Base, base );
palette.setColor( QPalette::Window, base.dark( 150 ) );
palette.setColor( QPalette::Mid, base.dark( 110 ) );
palette.setColor( QPalette::Light, base.light( 170 ) );
palette.setColor( QPalette::Dark, base.dark( 170 ) );
palette.setColor( QPalette::Text, base.dark( 200 ).light( 800 ) );
palette.setColor( QPalette::WindowText, base.dark( 200 ) );
return palette;
}
void CockpitGrid::changeSpeed()
{
static double offset = 0.8;
double speed = d_speedo->value();
if ( ( speed < 7.0 && offset < 0.0 ) ||
( speed > 203.0 && offset > 0.0 ) )
{
offset = -offset;
}
static int counter = 0;
switch( counter++ % 12 )
{
case 0:
case 2:
case 7:
case 8:
break;
default:
d_speedo->setValue( speed + offset );
}
}
void CockpitGrid::changeAngle()
{
static double offset = 0.05;
double angle = d_ai->angle();
if ( angle > 180.0 )
angle -= 360.0;
if ( ( angle < -5.0 && offset < 0.0 ) ||
( angle > 5.0 && offset > 0.0 ) )
{
offset = -offset;
}
d_ai->setAngle( angle + offset );
}
void CockpitGrid::changeGradient()
{
static double offset = 0.005;
double gradient = d_ai->gradient();
if ( ( gradient < -0.05 && offset < 0.0 ) ||
( gradient > 0.05 && offset > 0.0 ) )
{
offset = -offset;
}
d_ai->setGradient( gradient + offset );
}

View File

@@ -0,0 +1,28 @@
#include <qframe.h>
#include <qpalette.h>
class QwtDial;
class QwtAnalogClock;
class SpeedoMeter;
class AttitudeIndicator;
class CockpitGrid: public QFrame
{
Q_OBJECT
public:
CockpitGrid( QWidget *parent = NULL );
private Q_SLOTS:
void changeSpeed();
void changeGradient();
void changeAngle();
private:
QPalette colorTheme( const QColor & ) const;
QwtDial *createDial( int pos );
QwtAnalogClock *d_clock;
SpeedoMeter *d_speedo;
AttitudeIndicator *d_ai;
};

View File

@@ -0,0 +1,226 @@
#include <qlayout.h>
#include <qwt_compass.h>
#include <qwt_compass_rose.h>
#include <qwt_dial_needle.h>
#include "compass_grid.h"
CompassGrid::CompassGrid( QWidget *parent ):
QFrame( parent )
{
QPalette p = palette();
p.setColor( backgroundRole(), Qt::gray );
setPalette( p );
setAutoFillBackground( true );
QGridLayout *layout = new QGridLayout( this );
layout->setSpacing( 5 );
layout->setMargin( 0 );
int i;
for ( i = 0; i < 6; i++ )
{
QwtCompass *compass = createCompass( i );
layout->addWidget( compass, i / 3, i % 3 );
}
for ( i = 0; i < layout->columnCount(); i++ )
layout->setColumnStretch( i, 1 );
}
QwtCompass *CompassGrid::createCompass( int pos )
{
int c;
QPalette palette0;
for ( c = 0; c < QPalette::NColorRoles; c++ )
{
const QPalette::ColorRole colorRole =
static_cast<QPalette::ColorRole>( c );
palette0.setColor( colorRole, QColor() );
}
palette0.setColor( QPalette::Base,
palette().color( backgroundRole() ).light( 120 ) );
palette0.setColor( QPalette::WindowText,
palette0.color( QPalette::Base ) );
QwtCompass *compass = new QwtCompass( this );
compass->setLineWidth( 4 );
compass->setFrameShadow(
pos <= 2 ? QwtCompass::Sunken : QwtCompass::Raised );
switch( pos )
{
case 0:
{
/*
A compass with a rose and no needle. Scale and rose are
rotating.
*/
compass->setMode( QwtCompass::RotateScale );
QwtSimpleCompassRose *rose = new QwtSimpleCompassRose( 16, 2 );
rose->setWidth( 0.15 );
compass->setRose( rose );
break;
}
case 1:
{
/*
A windrose, with a scale indicating the main directions only
*/
QMap<double, QString> map;
map.insert( 0.0, "N" );
map.insert( 90.0, "E" );
map.insert( 180.0, "S" );
map.insert( 270.0, "W" );
compass->setScaleDraw( new QwtCompassScaleDraw( map ) );
QwtSimpleCompassRose *rose = new QwtSimpleCompassRose( 4, 1 );
compass->setRose( rose );
compass->setNeedle(
new QwtCompassWindArrow( QwtCompassWindArrow::Style2 ) );
compass->setValue( 60.0 );
break;
}
case 2:
{
/*
A compass with a rotating needle in darkBlue. Shows
a ticks for each degree.
*/
palette0.setColor( QPalette::Base, Qt::darkBlue );
palette0.setColor( QPalette::WindowText,
QColor( Qt::darkBlue ).dark( 120 ) );
palette0.setColor( QPalette::Text, Qt::white );
QwtCompassScaleDraw *scaleDraw = new QwtCompassScaleDraw();
scaleDraw->enableComponent( QwtAbstractScaleDraw::Ticks, true );
scaleDraw->enableComponent( QwtAbstractScaleDraw::Labels, true );
scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false );
scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 1 );
scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 1 );
scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 3 );
compass->setScaleDraw( scaleDraw );
compass->setScaleMaxMajor( 36 );
compass->setScaleMaxMinor( 5 );
compass->setNeedle(
new QwtCompassMagnetNeedle( QwtCompassMagnetNeedle::ThinStyle ) );
compass->setValue( 220.0 );
break;
}
case 3:
{
/*
A compass without a frame, showing numbers as tick labels.
The origin is at 220.0
*/
palette0.setColor( QPalette::Base,
palette().color( backgroundRole() ) );
palette0.setColor( QPalette::WindowText, Qt::blue );
compass->setLineWidth( 0 );
QMap<double, QString> map;
for ( double d = 0.0; d < 360.0; d += 60.0 )
{
QString label;
label.sprintf( "%.0f", d );
map.insert( d, label );
}
QwtCompassScaleDraw *scaleDraw =
new QwtCompassScaleDraw( map );
scaleDraw->enableComponent( QwtAbstractScaleDraw::Ticks, true );
scaleDraw->enableComponent( QwtAbstractScaleDraw::Labels, true );
scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, true );
scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 0 );
scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 0 );
scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 3 );
compass->setScaleDraw( scaleDraw );
compass->setScaleMaxMajor( 36 );
compass->setScaleMaxMinor( 5 );
compass->setNeedle( new QwtDialSimpleNeedle( QwtDialSimpleNeedle::Ray,
true, Qt::white ) );
compass->setOrigin( 220.0 );
compass->setValue( 20.0 );
break;
}
case 4:
{
/*
A compass showing another needle
*/
QwtCompassScaleDraw *scaleDraw = new QwtCompassScaleDraw();
scaleDraw->enableComponent( QwtAbstractScaleDraw::Ticks, true );
scaleDraw->enableComponent( QwtAbstractScaleDraw::Labels, true );
scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false );
scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 0 );
scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 0 );
scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 3 );
compass->setScaleDraw( scaleDraw );
compass->setNeedle( new QwtCompassMagnetNeedle(
QwtCompassMagnetNeedle::TriangleStyle, Qt::white, Qt::red ) );
compass->setValue( 220.0 );
break;
}
case 5:
{
/*
A compass with a yellow on black ray
*/
palette0.setColor( QPalette::WindowText, Qt::black );
compass->setNeedle( new QwtDialSimpleNeedle( QwtDialSimpleNeedle::Ray,
false, Qt::yellow ) );
compass->setValue( 315.0 );
break;
}
}
QPalette newPalette = compass->palette();
for ( c = 0; c < QPalette::NColorRoles; c++ )
{
const QPalette::ColorRole colorRole =
static_cast<QPalette::ColorRole>( c );
if ( palette0.color( colorRole ).isValid() )
newPalette.setColor( colorRole, palette0.color( colorRole ) );
}
for ( int i = 0; i < QPalette::NColorGroups; i++ )
{
const QPalette::ColorGroup colorGroup =
static_cast<QPalette::ColorGroup>( i );
const QColor light =
newPalette.color( colorGroup, QPalette::Base ).light( 170 );
const QColor dark = newPalette.color( colorGroup, QPalette::Base ).dark( 170 );
const QColor mid = compass->frameShadow() == QwtDial::Raised
? newPalette.color( colorGroup, QPalette::Base ).dark( 110 )
: newPalette.color( colorGroup, QPalette::Base ).light( 110 );
newPalette.setColor( colorGroup, QPalette::Dark, dark );
newPalette.setColor( colorGroup, QPalette::Mid, mid );
newPalette.setColor( colorGroup, QPalette::Light, light );
}
compass->setPalette( newPalette );
return compass;
}

View File

@@ -0,0 +1,11 @@
#include <qframe.h>
class QwtCompass;
class CompassGrid: public QFrame
{
public:
CompassGrid( QWidget *parent = NULL );
private:
QwtCompass *createCompass( int pos );
};

View File

@@ -0,0 +1,24 @@
#include <qapplication.h>
#include <qtabwidget.h>
#include "compass_grid.h"
#include "cockpit_grid.h"
//-----------------------------------------------------------------
//
// dials.cpp -- A demo program featuring QwtDial and friends
//
//-----------------------------------------------------------------
int main ( int argc, char **argv )
{
QApplication a( argc, argv );
QTabWidget tabWidget;
tabWidget.addTab( new CompassGrid, "Compass" );
tabWidget.addTab( new CockpitGrid, "Cockpit" );
tabWidget.show();
return a.exec();
}

View File

@@ -0,0 +1,26 @@
################################################################
# Qwt Widget Library
# Copyright (C) 1997 Josef Wilgen
# Copyright (C) 2002 Uwe Rathmann
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the Qwt License, Version 1.0
################################################################
include( $${PWD}/../examples.pri )
TARGET = dials
HEADERS = \
attitude_indicator.h \
speedo_meter.h \
cockpit_grid.h \
compass_grid.h
SOURCES = \
attitude_indicator.cpp \
speedo_meter.cpp \
cockpit_grid.cpp \
compass_grid.cpp \
dials.cpp

View File

@@ -0,0 +1,52 @@
#include <qpainter.h>
#include <qwt_dial_needle.h>
#include <qwt_round_scale_draw.h>
#include "speedo_meter.h"
SpeedoMeter::SpeedoMeter( QWidget *parent ):
QwtDial( parent ),
d_label( "km/h" )
{
QwtRoundScaleDraw *scaleDraw = new QwtRoundScaleDraw();
scaleDraw->setSpacing( 8 );
scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false );
scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 0 );
scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 4 );
scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 8 );
setScaleDraw( scaleDraw );
setWrapping( false );
setReadOnly( true );
setOrigin( 135.0 );
setScaleArc( 0.0, 270.0 );
QwtDialSimpleNeedle *needle = new QwtDialSimpleNeedle(
QwtDialSimpleNeedle::Arrow, true, Qt::red,
QColor( Qt::gray ).light( 130 ) );
setNeedle( needle );
}
void SpeedoMeter::setLabel( const QString &label )
{
d_label = label;
update();
}
QString SpeedoMeter::label() const
{
return d_label;
}
void SpeedoMeter::drawScaleContents( QPainter *painter,
const QPointF &center, double radius ) const
{
QRectF rect( 0.0, 0.0, 2.0 * radius, 2.0 * radius - 10.0 );
rect.moveCenter( center );
const QColor color = palette().color( QPalette::Text );
painter->setPen( color );
const int flags = Qt::AlignBottom | Qt::AlignHCenter;
painter->drawText( rect, flags, d_label );
}

View File

@@ -0,0 +1,18 @@
#include <qstring.h>
#include <qwt_dial.h>
class SpeedoMeter: public QwtDial
{
public:
SpeedoMeter( QWidget *parent = NULL );
void setLabel( const QString & );
QString label() const;
protected:
virtual void drawScaleContents( QPainter *painter,
const QPointF &center, double radius ) const;
private:
QString d_label;
};

Some files were not shown because too many files have changed in this diff Show More