Doc: Updated content for Drill Down example
QtWidgets/Drill Down example uses images and information about Nokia's old office locations as content. This change updates the example to use concepts related to Qt instead. In addition, - Documentation, screenshot updated accordingly - Corrected aspect ratio when scaling image items in the scene - Added a gray background with a slight gradient - Removed Symbian-specific code remnant Task-number: QTBUG-31075 Change-Id: Id8abfbf7f4033f74172477570f8f28390854101c Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
@ -78,55 +78,38 @@ static bool createConnection()
|
|||||||
query.exec("insert into person values(104, 'Roberto', 'Robitaille')");
|
query.exec("insert into person values(104, 'Roberto', 'Robitaille')");
|
||||||
query.exec("insert into person values(105, 'Maria', 'Papadopoulos')");
|
query.exec("insert into person values(105, 'Maria', 'Papadopoulos')");
|
||||||
|
|
||||||
query.exec("create table offices (id int primary key,"
|
query.exec("create table items (id int primary key,"
|
||||||
"imagefile int,"
|
"imagefile int,"
|
||||||
"location varchar(20),"
|
"itemtype varchar(20),"
|
||||||
"country varchar(20),"
|
|
||||||
"description varchar(100))");
|
"description varchar(100))");
|
||||||
query.exec("insert into offices "
|
query.exec("insert into items "
|
||||||
"values(0, 0, 'Oslo', 'Norway',"
|
"values(0, 0, 'Qt',"
|
||||||
"'Oslo is home to more than 500 000 citizens and has a "
|
"'Qt is a full development framework with tools designed to "
|
||||||
"lot to offer.It has been called \"The city with the big "
|
"streamline the creation of stunning applications and "
|
||||||
"heart\" and this is a nickname we are happy to live up to.')");
|
"amazing user interfaces for desktop, embedded and mobile "
|
||||||
query.exec("insert into offices "
|
"platforms.')");
|
||||||
"values(1, 1, 'Brisbane', 'Australia',"
|
query.exec("insert into items "
|
||||||
"'Brisbane is the capital of Queensland, the Sunshine State, "
|
"values(1, 1, 'Qt Quick',"
|
||||||
"where it is beautiful one day, perfect the next. "
|
"'Qt Quick is a collection of techniques designed to help "
|
||||||
"Brisbane is Australia''s 3rd largest city, being home "
|
"developers create intuitive, modern-looking, and fluid "
|
||||||
"to almost 2 million people.')");
|
"user interfaces using a CSS & JavaScript like language.')");
|
||||||
query.exec("insert into offices "
|
query.exec("insert into items "
|
||||||
"values(2, 2, 'Redwood City', 'US',"
|
"values(2, 2, 'Qt Creator',"
|
||||||
"'You find Redwood City in the heart of the Bay Area "
|
"'Qt Creator is a powerful cross-platform integrated "
|
||||||
"just north of Silicon Valley. The largest nearby city is "
|
"development environment (IDE), including UI design tools "
|
||||||
"San Jose which is the third largest city in California "
|
"and on-device debugging.')");
|
||||||
"and the 10th largest in the US.')");
|
query.exec("insert into items "
|
||||||
query.exec("insert into offices "
|
"values(3, 3, 'Qt Project',"
|
||||||
"values(3, 3, 'Berlin', 'Germany',"
|
"'The Qt Project governs the open source development of Qt, "
|
||||||
"'Berlin, the capital of Germany is dynamic, cosmopolitan "
|
"allowing anyone wanting to contribute to join the effort "
|
||||||
"and creative, allowing for every kind of lifestyle. "
|
"through a meritocratic structure of approvers and "
|
||||||
"East meets West in the metropolis at the heart of a "
|
"maintainers.')");
|
||||||
"changing Europe.')");
|
|
||||||
query.exec("insert into offices "
|
|
||||||
"values(4, 4, 'Munich', 'Germany',"
|
|
||||||
"'Several technology companies are represented in Munich, "
|
|
||||||
"and the city is often called the \"Bavarian Silicon Valley\". "
|
|
||||||
"The exciting city is also filled with culture, "
|
|
||||||
"art and music. ')");
|
|
||||||
query.exec("insert into offices "
|
|
||||||
"values(5, 5, 'Beijing', 'China',"
|
|
||||||
"'Beijing as a capital city has more than 3000 years of "
|
|
||||||
"history. Today the city counts 12 million citizens, and "
|
|
||||||
"is the political, economic and cultural centre of China.')");
|
|
||||||
|
|
||||||
query.exec("create table images (locationid int, file varchar(20))");
|
|
||||||
query.exec("insert into images values(0, 'images/oslo.png')");
|
|
||||||
query.exec("insert into images values(1, 'images/brisbane.png')");
|
|
||||||
query.exec("insert into images values(2, 'images/redwood.png')");
|
|
||||||
query.exec("insert into images values(3, 'images/berlin.png')");
|
|
||||||
query.exec("insert into images values(4, 'images/munich.png')");
|
|
||||||
query.exec("insert into images values(5, 'images/beijing.png')");
|
|
||||||
|
|
||||||
|
|
||||||
|
query.exec("create table images (itemid int, file varchar(20))");
|
||||||
|
query.exec("insert into images values(0, 'images/qt-logo.png')");
|
||||||
|
query.exec("insert into images values(1, 'images/qt-quick.png')");
|
||||||
|
query.exec("insert into images values(2, 'images/qt-creator.png')");
|
||||||
|
query.exec("insert into images values(3, 'images/qt-project.png')");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 52 KiB |
@ -37,20 +37,19 @@
|
|||||||
\image drilldown-example.png Screenshot of the Drill Down Example
|
\image drilldown-example.png Screenshot of the Drill Down Example
|
||||||
|
|
||||||
When running the example application, a user can retrieve
|
When running the example application, a user can retrieve
|
||||||
information about each of Nokia's Qt offices by clicking the
|
information about each item by clicking the corresponding image.
|
||||||
corresponding image. The application pops up an information window
|
The application pops up an information window displaying the data,
|
||||||
displaying the data, and allows the users to alter the location
|
and allows the users to alter the description as well as the image.
|
||||||
description as well as the image. The main view will be updated
|
The main view will be updated when the users submit their changes.
|
||||||
when the users submit their changes.
|
|
||||||
|
|
||||||
The example consists of three classes:
|
The example consists of three classes:
|
||||||
|
|
||||||
\list
|
\list
|
||||||
\li \c ImageItem is a custom graphics item class used to
|
\li \c ImageItem is a custom graphics item class used to
|
||||||
display the office images.
|
display the images.
|
||||||
|
|
||||||
\li \c View is the main application widget allowing the user to
|
\li \c View is the main application widget allowing the user to
|
||||||
browse through the various locations.
|
browse through the various items.
|
||||||
|
|
||||||
\li \c InformationWindow displays the requested information,
|
\li \c InformationWindow displays the requested information,
|
||||||
allowing the users to alter it and submit their changes to the
|
allowing the users to alter it and submit their changes to the
|
||||||
@ -70,7 +69,7 @@
|
|||||||
\snippet drilldown/informationwindow.h 0
|
\snippet drilldown/informationwindow.h 0
|
||||||
|
|
||||||
When we create an information window, we pass the associated
|
When we create an information window, we pass the associated
|
||||||
location ID, a parent, and a pointer to the database, to the
|
item ID, a parent, and a pointer to the database, to the
|
||||||
constructor. We will use the database pointer to populate our
|
constructor. We will use the database pointer to populate our
|
||||||
window with data, while passing the parent parameter on to the
|
window with data, while passing the parent parameter on to the
|
||||||
base class. The ID is stored for future reference.
|
base class. The ID is stored for future reference.
|
||||||
@ -84,7 +83,7 @@
|
|||||||
|
|
||||||
\snippet drilldown/informationwindow.h 1
|
\snippet drilldown/informationwindow.h 1
|
||||||
|
|
||||||
Since we allow the users to alter some of the location data, we
|
Since we allow the users to alter some of the data, we
|
||||||
must provide functionality for reverting and submitting their
|
must provide functionality for reverting and submitting their
|
||||||
changes. The \c enableButtons() slot is provided for convenience
|
changes. The \c enableButtons() slot is provided for convenience
|
||||||
to enable and disable the various buttons when required.
|
to enable and disable the various buttons when required.
|
||||||
@ -93,15 +92,15 @@
|
|||||||
|
|
||||||
The \c createButtons() function is also a convenience function,
|
The \c createButtons() function is also a convenience function,
|
||||||
provided to simplify the constructor. As mentioned above we store
|
provided to simplify the constructor. As mentioned above we store
|
||||||
the location ID for future reference. We also store the name of
|
the item ID for future reference. We also store the name of
|
||||||
the currently displayed image file to be able to determine when to
|
the currently displayed image file to be able to determine when to
|
||||||
emit the \c imageChanged() signal.
|
emit the \c imageChanged() signal.
|
||||||
|
|
||||||
The information window uses the QLabel class to display the office
|
The information window uses the QLabel class to display the name of
|
||||||
location and the country. The associated image file is displayed
|
an item. The associated image file is displayed using a QComboBox
|
||||||
using a QComboBox instance while the description is displayed using
|
instance while the description is displayed using QTextEdit. In
|
||||||
QTextEdit. In addition, the window has three buttons to control
|
addition, the window has three buttons to control the data flow and
|
||||||
the data flow and whether the window is shown or not.
|
whether the window is shown or not.
|
||||||
|
|
||||||
Finally, we declare a \e mapper. The QDataWidgetMapper class
|
Finally, we declare a \e mapper. The QDataWidgetMapper class
|
||||||
provides mapping between a section of a data model to widgets. We
|
provides mapping between a section of a data model to widgets. We
|
||||||
@ -110,7 +109,7 @@
|
|||||||
|
|
||||||
\section1 InformationWindow Class Implementation
|
\section1 InformationWindow Class Implementation
|
||||||
|
|
||||||
The constructor takes three arguments: a location ID, a database
|
The constructor takes three arguments: an item ID, a database
|
||||||
pointer and a parent widget. The database pointer is actually a
|
pointer and a parent widget. The database pointer is actually a
|
||||||
pointer to a QSqlRelationalTableModel object providing an editable
|
pointer to a QSqlRelationalTableModel object providing an editable
|
||||||
data model (with foreign key support) for our database table.
|
data model (with foreign key support) for our database table.
|
||||||
@ -125,8 +124,8 @@
|
|||||||
|
|
||||||
\snippet drilldown/informationwindow.cpp 2
|
\snippet drilldown/informationwindow.cpp 2
|
||||||
|
|
||||||
In this example, the information about the offices are stored in a
|
In this example, information about the items are stored in a
|
||||||
database table called "offices". When creating the model,
|
database table called "items". When creating the model,
|
||||||
we will use a foreign key to establish a relation between this
|
we will use a foreign key to establish a relation between this
|
||||||
table and a second data base table, "images", containing the names
|
table and a second data base table, "images", containing the names
|
||||||
of the available image files. We will get back to how this is done
|
of the available image files. We will get back to how this is done
|
||||||
@ -140,7 +139,7 @@
|
|||||||
the foreign key (in this case the "imagefile" column number) as
|
the foreign key (in this case the "imagefile" column number) as
|
||||||
argument. We use QComboBox's \l {QComboBox::}{setModel()} function
|
argument. We use QComboBox's \l {QComboBox::}{setModel()} function
|
||||||
to make the combobox use the "images" model. And, since this model
|
to make the combobox use the "images" model. And, since this model
|
||||||
has two columns ("locationid" and "file"), we also specify which
|
has two columns ("itemid" and "file"), we also specify which
|
||||||
column we want to be visible using the QComboBox::setModelColumn()
|
column we want to be visible using the QComboBox::setModelColumn()
|
||||||
function.
|
function.
|
||||||
|
|
||||||
@ -156,7 +155,7 @@
|
|||||||
section is a column in the model, otherwise it is a row. We call
|
section is a column in the model, otherwise it is a row. We call
|
||||||
the \l {QDataWidgetMapper::}{setCurrentIndex()} function to
|
the \l {QDataWidgetMapper::}{setCurrentIndex()} function to
|
||||||
initialize the widgets with the data associated with the given
|
initialize the widgets with the data associated with the given
|
||||||
location ID. Every time the current index changes, all the widgets
|
item ID. Every time the current index changes, all the widgets
|
||||||
are updated with the contents from the model.
|
are updated with the contents from the model.
|
||||||
|
|
||||||
We also set the mapper's submit policy to
|
We also set the mapper's submit policy to
|
||||||
@ -168,14 +167,14 @@
|
|||||||
view should use for its items. The QSqlRelationalDelegate class
|
view should use for its items. The QSqlRelationalDelegate class
|
||||||
represents a delegate that unlike the default delegate, enables
|
represents a delegate that unlike the default delegate, enables
|
||||||
combobox functionality for fields that are foreign keys into other
|
combobox functionality for fields that are foreign keys into other
|
||||||
tables (like "imagefile" in our "trolltechoffices" table).
|
tables (like "imagefile" in our "items" table).
|
||||||
|
|
||||||
\snippet drilldown/informationwindow.cpp 4
|
\snippet drilldown/informationwindow.cpp 4
|
||||||
|
|
||||||
Finally, we connect the "something's changed" signals in the
|
Finally, we connect the "something's changed" signals in the
|
||||||
editors to our custom \c enableButtons() slot, enabling the users
|
editors to our custom \c enableButtons() slot, enabling the users
|
||||||
to either submit or revert their changes. We add all the widgets
|
to either submit or revert their changes. We add all the widgets
|
||||||
into a layout, store the location ID and the name of the displayed
|
into a layout, store the item ID and the name of the displayed
|
||||||
image file for future reference, and set the window title and
|
image file for future reference, and set the window title and
|
||||||
initial size.
|
initial size.
|
||||||
|
|
||||||
@ -189,7 +188,7 @@
|
|||||||
application exits (i.e., if the user closes the information
|
application exits (i.e., if the user closes the information
|
||||||
window, it is only hidden). For this reason we do not want to
|
window, it is only hidden). For this reason we do not want to
|
||||||
create more than one \c InformationWindow object for each
|
create more than one \c InformationWindow object for each
|
||||||
location, and we provide the public \c id() function to be able to
|
item, and we provide the public \c id() function to be able to
|
||||||
determine whether a window already exists for a given location
|
determine whether a window already exists for a given location
|
||||||
when the user requests information about it.
|
when the user requests information about it.
|
||||||
|
|
||||||
@ -256,16 +255,15 @@
|
|||||||
{QDialogButtonBox::ButtonRole}{reject} role indicates that
|
{QDialogButtonBox::ButtonRole}{reject} role indicates that
|
||||||
clicking the button causes the dialog to be rejected. On the other
|
clicking the button causes the dialog to be rejected. On the other
|
||||||
hand, since we only hide the information window, any changes that
|
hand, since we only hide the information window, any changes that
|
||||||
the user has made wil be preserved until the user expliclity
|
the user has made will be preserved until the user explicitly
|
||||||
revert or submit them.
|
reverts or submits them.
|
||||||
|
|
||||||
\snippet drilldown/informationwindow.cpp 10
|
\snippet drilldown/informationwindow.cpp 10
|
||||||
|
|
||||||
The \c enableButtons() slot is called to enable the buttons
|
The \c enableButtons() slot is called to enable the buttons
|
||||||
whenever the user changes the presented data. Likewise, when the
|
whenever the user changes the presented data. Likewise, when the
|
||||||
data the user choose to submit the changes, the buttons are
|
user chooses to submit the changes, the buttons are disabled to
|
||||||
disabled to indicate that the current data is stored in the
|
indicate that the current data is stored in the database.
|
||||||
database.
|
|
||||||
|
|
||||||
This completes the \c InformationWindow class. Let's take a look
|
This completes the \c InformationWindow class. Let's take a look
|
||||||
at how we have used it in our example application.
|
at how we have used it in our example application.
|
||||||
@ -280,19 +278,17 @@
|
|||||||
\snippet drilldown/view.h 1
|
\snippet drilldown/view.h 1
|
||||||
|
|
||||||
The QGraphicsView class is part of the \l {Graphics View
|
The QGraphicsView class is part of the \l {Graphics View
|
||||||
Framework} which we will use to display the images of Nokia's
|
Framework} which we will use to display the images. To be able to
|
||||||
Qt offices. To be able to respond to user interaction;
|
respond to user interaction by displaying the appropriate
|
||||||
i.e., showing the
|
information window when the image is clicked, we reimplement
|
||||||
appropriate information window whenever the user clicks one of the
|
QGraphicsView's \l{QGraphicsView::}{mouseReleaseEvent()} function.
|
||||||
office images, we reimplement QGraphicsView's \l
|
|
||||||
{QGraphicsView::}{mouseReleaseEvent()} function.
|
|
||||||
|
|
||||||
Note that the constructor expects the names of two database
|
Note that the constructor expects the names of two database
|
||||||
tables: One containing the detailed information about the offices,
|
tables: One containing the detailed information about the items,
|
||||||
and another containing the names of the available image files. We
|
and another containing the names of the available image files. We
|
||||||
also provide a private \c updateImage() slot to catch \c
|
also provide a private \c updateImage() slot to catch \c
|
||||||
{InformationWindow}'s \c imageChanged() signal that is emitted
|
{InformationWindow}'s \c imageChanged() signal that is emitted
|
||||||
whenever the user changes a location's image.
|
whenever the user changes an image associated with the item.
|
||||||
|
|
||||||
\snippet drilldown/view.h 2
|
\snippet drilldown/view.h 2
|
||||||
|
|
||||||
@ -303,20 +299,20 @@
|
|||||||
The \c findWindow() function, on the other hand, is frequently
|
The \c findWindow() function, on the other hand, is frequently
|
||||||
used. It is called from the \c showInformation() function to
|
used. It is called from the \c showInformation() function to
|
||||||
detemine whether a window is already created for the given
|
detemine whether a window is already created for the given
|
||||||
location (whenever we create an \c InformationWindow object, we
|
item (whenever we create an \c InformationWindow object, we
|
||||||
store a reference to it in the \c informationWindows list). The
|
store a reference to it in the \c informationWindows list). The
|
||||||
latter function is in turn called from our custom \c
|
latter function is in turn called from our custom \c
|
||||||
mouseReleaseEvent() implementation.
|
mouseReleaseEvent() implementation.
|
||||||
|
|
||||||
\snippet drilldown/view.h 3
|
\snippet drilldown/view.h 3
|
||||||
|
|
||||||
Finally we declare a QSqlRelationalTableModel pointer. As
|
Finally, we declare a QSqlRelationalTableModel pointer. As
|
||||||
previously mentioned, the QSqlRelationalTableModel class provides
|
previously mentioned, the QSqlRelationalTableModel class provides
|
||||||
an editable data model with foreign key support. There are a
|
an editable data model with foreign key support. There are a
|
||||||
couple of things you should keep in mind when using the
|
couple of things you should keep in mind when using the
|
||||||
QSqlRelationalTableModel class: The table must have a primary key
|
QSqlRelationalTableModel class: The table must have a primary key
|
||||||
declared and this key cannot contain a relation to another table,
|
declared and this key cannot contain a relation to another table,
|
||||||
i.e., it cannot be a foreign key. Note also that if a relational
|
that is, it cannot be a foreign key. Also note that if a relational
|
||||||
table contains keys that refer to non-existent rows in the
|
table contains keys that refer to non-existent rows in the
|
||||||
referenced table, the rows containing the invalid keys will not be
|
referenced table, the rows containing the invalid keys will not be
|
||||||
exposed through the model. It is the user's or the database's
|
exposed through the model. It is the user's or the database's
|
||||||
@ -327,11 +323,11 @@
|
|||||||
Although the constructor requests the names of both the table
|
Although the constructor requests the names of both the table
|
||||||
containing office details as well as the table containing the
|
containing office details as well as the table containing the
|
||||||
names of the available image files, we only have to create a
|
names of the available image files, we only have to create a
|
||||||
QSqlRelationalTableModel object for the office table:
|
QSqlRelationalTableModel object for the "items" table:
|
||||||
|
|
||||||
\snippet drilldown/view.cpp 0
|
\snippet drilldown/view.cpp 0
|
||||||
|
|
||||||
The reason is that once we have a model with the office details,
|
The reason is that once we have a model with the item details,
|
||||||
we can create a relation to the available image files using
|
we can create a relation to the available image files using
|
||||||
QSqlRelationalTableModel's \l
|
QSqlRelationalTableModel's \l
|
||||||
{QSqlRelationalTableModel::}{setRelation()} function. This
|
{QSqlRelationalTableModel::}{setRelation()} function. This
|
||||||
@ -348,20 +344,19 @@
|
|||||||
\snippet drilldown/view.cpp 1
|
\snippet drilldown/view.cpp 1
|
||||||
|
|
||||||
Then we create the contents of our view, i.e., the scene and its
|
Then we create the contents of our view, i.e., the scene and its
|
||||||
items. The location labels are regular QGraphicsTextItem objects,
|
items. The labels are regular QGraphicsTextItem objects, whereas
|
||||||
and the "Qt" logo is represented by a QGraphicsPixmapItem
|
the images are instances of the \c ImageItem class, derived from
|
||||||
object. The images, on the other hand, are instances of the \c
|
QGraphicsPixmapItem. We will get back to this shortly when reviewing
|
||||||
ImageItem class (derived from QGraphicsPixmapItem). We will get
|
the \c addItems() function.
|
||||||
back to this shortly when reviewing the \c addItems() function.
|
|
||||||
|
|
||||||
Finally, we set the main application widget's size constraints and
|
Finally, we set the main application widget's size constraints and
|
||||||
window title.
|
window title.
|
||||||
|
|
||||||
\snippet drilldown/view.cpp 3
|
\snippet drilldown/view.cpp 3
|
||||||
|
|
||||||
The \c addItems() function is called only once, i.e., when
|
The \c addItems() function is called only once when creating the main
|
||||||
creating the main application window. For each row in the database
|
application window. For each row in the database table, we first
|
||||||
table, we first extract the corresponding record using the model's
|
extract the corresponding record using the model's
|
||||||
\l {QSqlRelationalTableModel::}{record()} function. The QSqlRecord
|
\l {QSqlRelationalTableModel::}{record()} function. The QSqlRecord
|
||||||
class encapsulates both the functionality and characteristics of a
|
class encapsulates both the functionality and characteristics of a
|
||||||
database record, and supports adding and removing fields as well
|
database record, and supports adding and removing fields as well
|
||||||
@ -394,7 +389,7 @@
|
|||||||
\snippet drilldown/view.cpp 6
|
\snippet drilldown/view.cpp 6
|
||||||
|
|
||||||
The \c showInformation() function is given an \c ImageItem object
|
The \c showInformation() function is given an \c ImageItem object
|
||||||
as argument, and starts off by extracting the item's location
|
as argument, and starts off by extracting the item's item
|
||||||
ID. Then it determines if there already is created an information
|
ID. Then it determines if there already is created an information
|
||||||
window for this location. If it is, and the window is visible, it
|
window for this location. If it is, and the window is visible, it
|
||||||
ensures that the window is raised to the top of the widget stack
|
ensures that the window is raised to the top of the widget stack
|
||||||
@ -402,7 +397,7 @@
|
|||||||
{QWidget::}{show()} slot gives the same result.
|
{QWidget::}{show()} slot gives the same result.
|
||||||
|
|
||||||
If no window for the given location exists, we create one by
|
If no window for the given location exists, we create one by
|
||||||
passing the location ID, a pointer to the model, and our view as a
|
passing the item ID, a pointer to the model, and our view as a
|
||||||
parent, to the \c InformationWindow constructor. Note that we
|
parent, to the \c InformationWindow constructor. Note that we
|
||||||
connect the information window's \c imageChanged() signal to \e
|
connect the information window's \c imageChanged() signal to \e
|
||||||
this widget's \c updateImage() slot, before we give it a suitable
|
this widget's \c updateImage() slot, before we give it a suitable
|
||||||
@ -410,16 +405,16 @@
|
|||||||
|
|
||||||
\snippet drilldown/view.cpp 7
|
\snippet drilldown/view.cpp 7
|
||||||
|
|
||||||
The \c updateImage() slot takes a location ID and the name of an
|
The \c updateImage() slot takes an item ID and the name of an
|
||||||
image files as arguments. It filters out the image items, and
|
image file as arguments. It filters out the image items, and
|
||||||
updates the one that correspond to the given location ID, with the
|
updates the one that correspond to the given item ID, with the
|
||||||
provided image file.
|
provided image file.
|
||||||
|
|
||||||
\snippet drilldown/view.cpp 8
|
\snippet drilldown/view.cpp 8
|
||||||
|
|
||||||
The \c findWindow() function simply searches through the list of
|
The \c findWindow() function simply searches through the list of
|
||||||
existing windows, returning a pointer to the window that matches
|
existing windows, returning a pointer to the window that matches
|
||||||
the given location ID, or 0 if the window doesn't exists.
|
the given item ID, or 0 if the window doesn't exists.
|
||||||
|
|
||||||
Finally, let's take a quick look at our custom \c ImageItem class:
|
Finally, let's take a quick look at our custom \c ImageItem class:
|
||||||
|
|
||||||
@ -442,7 +437,7 @@
|
|||||||
returning back to its original size when the cursor leaves its
|
returning back to its original size when the cursor leaves its
|
||||||
borders.
|
borders.
|
||||||
|
|
||||||
Finally, we store the location ID that this particular record is
|
Finally, we store the item ID that this particular record is
|
||||||
associated with as well as a z-value. In the \l {Graphics View
|
associated with as well as a z-value. In the \l {Graphics View
|
||||||
Framework}, an item's z-value determines its position in the item
|
Framework}, an item's z-value determines its position in the item
|
||||||
stack. An item of high z-value will be drawn on top of an item
|
stack. An item of high z-value will be drawn on top of an item
|
||||||
@ -460,8 +455,8 @@
|
|||||||
\snippet drilldown/imageitem.cpp 0
|
\snippet drilldown/imageitem.cpp 0
|
||||||
|
|
||||||
Then we store the ID for future reference, and ensure that our
|
Then we store the ID for future reference, and ensure that our
|
||||||
item will accept hover events. Hover events are delivered when
|
image item will accept hover events. Hover events are delivered
|
||||||
there is no current mouse grabber item. They are sent when the
|
when there is no current mouse grabber item. They are sent when the
|
||||||
mouse cursor enters an item, when it moves around inside the item,
|
mouse cursor enters an item, when it moves around inside the item,
|
||||||
and when the cursor leaves an item. As we mentioned earlier, none
|
and when the cursor leaves an item. As we mentioned earlier, none
|
||||||
of the \l {Graphics View Framework}'s items accept hover
|
of the \l {Graphics View Framework}'s items accept hover
|
||||||
@ -487,7 +482,7 @@
|
|||||||
\codeline
|
\codeline
|
||||||
\snippet drilldown/imageitem.cpp 2
|
\snippet drilldown/imageitem.cpp 2
|
||||||
|
|
||||||
Whenever the mouse cursor enters or leave the image item, the
|
Whenever the mouse cursor enters or leaves the image item, the
|
||||||
corresponding event handlers are triggered: We first set the time
|
corresponding event handlers are triggered: We first set the time
|
||||||
line's direction, making the item expand or shrink,
|
line's direction, making the item expand or shrink,
|
||||||
respectively. Then we alter the item's z-value if it is not already
|
respectively. Then we alter the item's z-value if it is not already
|
||||||
@ -532,6 +527,6 @@
|
|||||||
size regardless of the size of the source image. The \c id()
|
size regardless of the size of the source image. The \c id()
|
||||||
function is trivial, and is simply provided to be able to identify
|
function is trivial, and is simply provided to be able to identify
|
||||||
the item. In the \c updateItemPosition() slot we call the
|
the item. In the \c updateItemPosition() slot we call the
|
||||||
QGraphicsItem::setZValue() function, setting the elevation (i.e.,
|
QGraphicsItem::setZValue() function, setting the elevation of the
|
||||||
the position) of the item.
|
item.
|
||||||
*/
|
*/
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
<!DOCTYPE RCC><RCC version="1.0">
|
<RCC>
|
||||||
<qresource>
|
<qresource prefix="/">
|
||||||
<file>images/oslo.png</file>
|
<file>images/qt-logo.png</file>
|
||||||
<file>images/brisbane.png</file>
|
<file>images/qt-quick.png</file>
|
||||||
<file>images/redwood.png</file>
|
<file>images/qt-creator.png</file>
|
||||||
<file>images/berlin.png</file>
|
<file>images/qt-project.png</file>
|
||||||
<file>images/munich.png</file>
|
</qresource>
|
||||||
<file>images/beijing.png</file>
|
|
||||||
<file>logo.png</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -100,7 +100,7 @@ void ImageItem::setFrame(int frame)
|
|||||||
void ImageItem::adjust()
|
void ImageItem::adjust()
|
||||||
{
|
{
|
||||||
QMatrix matrix;
|
QMatrix matrix;
|
||||||
matrix.scale(150/ boundingRect().width(), 120/ boundingRect().height());
|
matrix.scale(120/ boundingRect().width(), 120/ boundingRect().height());
|
||||||
setMatrix(matrix);
|
setMatrix(matrix);
|
||||||
}
|
}
|
||||||
//! [4]
|
//! [4]
|
||||||
|
Before Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 41 KiB |
BIN
examples/sql/drilldown/images/qt-creator.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
examples/sql/drilldown/images/qt-logo.png
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
examples/sql/drilldown/images/qt-project.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
examples/sql/drilldown/images/qt-quick.png
Normal file
After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 38 KiB |
@ -41,38 +41,35 @@
|
|||||||
#include "informationwindow.h"
|
#include "informationwindow.h"
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
InformationWindow::InformationWindow(int id, QSqlRelationalTableModel *offices,
|
InformationWindow::InformationWindow(int id, QSqlRelationalTableModel *items,
|
||||||
QWidget *parent)
|
QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
{
|
{
|
||||||
//! [0] //! [1]
|
//! [0] //! [1]
|
||||||
QLabel *locationLabel = new QLabel(tr("Location: "));
|
QLabel *itemLabel = new QLabel(tr("Item: "));
|
||||||
QLabel *countryLabel = new QLabel(tr("Country: "));
|
|
||||||
QLabel *descriptionLabel = new QLabel(tr("Description: "));
|
QLabel *descriptionLabel = new QLabel(tr("Description: "));
|
||||||
QLabel *imageFileLabel = new QLabel(tr("Image file: "));
|
QLabel *imageFileLabel = new QLabel(tr("Image file: "));
|
||||||
|
|
||||||
createButtons();
|
createButtons();
|
||||||
|
|
||||||
locationText = new QLabel;
|
itemText = new QLabel;
|
||||||
countryText = new QLabel;
|
|
||||||
descriptionEditor = new QTextEdit;
|
descriptionEditor = new QTextEdit;
|
||||||
//! [1]
|
//! [1]
|
||||||
|
|
||||||
//! [2]
|
//! [2]
|
||||||
imageFileEditor = new QComboBox;
|
imageFileEditor = new QComboBox;
|
||||||
imageFileEditor->setModel(offices->relationModel(1));
|
imageFileEditor->setModel(items->relationModel(1));
|
||||||
imageFileEditor->setModelColumn(offices->relationModel(1)->fieldIndex("file"));
|
imageFileEditor->setModelColumn(items->relationModel(1)->fieldIndex("file"));
|
||||||
//! [2]
|
//! [2]
|
||||||
|
|
||||||
//! [3]
|
//! [3]
|
||||||
mapper = new QDataWidgetMapper(this);
|
mapper = new QDataWidgetMapper(this);
|
||||||
mapper->setModel(offices);
|
mapper->setModel(items);
|
||||||
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
|
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
|
||||||
mapper->setItemDelegate(new QSqlRelationalDelegate(mapper));
|
mapper->setItemDelegate(new QSqlRelationalDelegate(mapper));
|
||||||
mapper->addMapping(imageFileEditor, 1);
|
mapper->addMapping(imageFileEditor, 1);
|
||||||
mapper->addMapping(locationText, 2, "text");
|
mapper->addMapping(itemText, 2, "text");
|
||||||
mapper->addMapping(countryText, 3, "text");
|
mapper->addMapping(descriptionEditor, 3);
|
||||||
mapper->addMapping(descriptionEditor, 4);
|
|
||||||
mapper->setCurrentIndex(id);
|
mapper->setCurrentIndex(id);
|
||||||
//! [3]
|
//! [3]
|
||||||
|
|
||||||
@ -83,8 +80,7 @@ InformationWindow::InformationWindow(int id, QSqlRelationalTableModel *offices,
|
|||||||
this, SLOT(enableButtons()));
|
this, SLOT(enableButtons()));
|
||||||
|
|
||||||
QFormLayout *formLayout = new QFormLayout;
|
QFormLayout *formLayout = new QFormLayout;
|
||||||
formLayout->addRow(locationLabel, locationText);
|
formLayout->addRow(itemLabel, itemText);
|
||||||
formLayout->addRow(countryLabel, countryText);
|
|
||||||
formLayout->addRow(imageFileLabel, imageFileEditor);
|
formLayout->addRow(imageFileLabel, imageFileEditor);
|
||||||
formLayout->addRow(descriptionLabel, descriptionEditor);
|
formLayout->addRow(descriptionLabel, descriptionEditor);
|
||||||
|
|
||||||
@ -93,23 +89,19 @@ InformationWindow::InformationWindow(int id, QSqlRelationalTableModel *offices,
|
|||||||
layout->addWidget(buttonBox);
|
layout->addWidget(buttonBox);
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
locationId = id;
|
itemId = id;
|
||||||
displayedImage = imageFileEditor->currentText();
|
displayedImage = imageFileEditor->currentText();
|
||||||
|
|
||||||
// Commented the following line. Now the window will look like dialog and the Qt will place the QDialogBox buttons to menu area in Symbian.
|
setWindowFlags(Qt::Window);
|
||||||
// Too bad that the revert button is missing, Should the Qt place the buttons under Option menu in the menu area?!
|
|
||||||
// If the Qt::Window flag was used, the background of window is white in symbian and the QLabels can't be regognized from the background.
|
|
||||||
|
|
||||||
//setWindowFlags(Qt::Window);
|
|
||||||
enableButtons(false);
|
enableButtons(false);
|
||||||
setWindowTitle(tr("Office: %1").arg(locationText->text()));
|
setWindowTitle(itemText->text());
|
||||||
}
|
}
|
||||||
//! [4]
|
//! [4]
|
||||||
|
|
||||||
//! [5]
|
//! [5]
|
||||||
int InformationWindow::id()
|
int InformationWindow::id()
|
||||||
{
|
{
|
||||||
return locationId;
|
return itemId;
|
||||||
}
|
}
|
||||||
//! [5]
|
//! [5]
|
||||||
|
|
||||||
@ -128,11 +120,11 @@ void InformationWindow::submit()
|
|||||||
|
|
||||||
if (displayedImage != newImage) {
|
if (displayedImage != newImage) {
|
||||||
displayedImage = newImage;
|
displayedImage = newImage;
|
||||||
emit imageChanged(locationId, newImage);
|
emit imageChanged(itemId, newImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
mapper->submit();
|
mapper->submit();
|
||||||
mapper->setCurrentIndex(locationId);
|
mapper->setCurrentIndex(itemId);
|
||||||
|
|
||||||
enableButtons(false);
|
enableButtons(false);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ class InformationWindow : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InformationWindow(int id, QSqlRelationalTableModel *offices,
|
InformationWindow(int id, QSqlRelationalTableModel *items,
|
||||||
QWidget *parent = 0);
|
QWidget *parent = 0);
|
||||||
|
|
||||||
int id();
|
int id();
|
||||||
@ -70,12 +70,11 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void createButtons();
|
void createButtons();
|
||||||
|
|
||||||
int locationId;
|
int itemId;
|
||||||
QString displayedImage;
|
QString displayedImage;
|
||||||
|
|
||||||
QComboBox *imageFileEditor;
|
QComboBox *imageFileEditor;
|
||||||
QLabel *locationText;
|
QLabel *itemText;
|
||||||
QLabel *countryText;
|
|
||||||
QTextEdit *descriptionEditor;
|
QTextEdit *descriptionEditor;
|
||||||
|
|
||||||
QPushButton *closeButton;
|
QPushButton *closeButton;
|
||||||
|
Before Width: | Height: | Size: 13 KiB |
@ -52,7 +52,7 @@ int main(int argc, char *argv[])
|
|||||||
if (!createConnection())
|
if (!createConnection())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
View view("offices", "images");
|
View view("items", "images");
|
||||||
view.show();
|
view.show();
|
||||||
#ifdef QT_KEYPAD_NAVIGATION
|
#ifdef QT_KEYPAD_NAVIGATION
|
||||||
QApplication::setNavigationMode(Qt::NavigationModeCursorAuto);
|
QApplication::setNavigationMode(Qt::NavigationModeCursorAuto);
|
||||||
|
@ -43,61 +43,62 @@
|
|||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
View::View(const QString &offices, const QString &images, QWidget *parent)
|
View::View(const QString &items, const QString &images, QWidget *parent)
|
||||||
: QGraphicsView(parent)
|
: QGraphicsView(parent)
|
||||||
{
|
{
|
||||||
officeTable = new QSqlRelationalTableModel(this);
|
itemTable = new QSqlRelationalTableModel(this);
|
||||||
officeTable->setTable(offices);
|
itemTable->setTable(items);
|
||||||
officeTable->setRelation(1, QSqlRelation(images, "locationid", "file"));
|
itemTable->setRelation(1, QSqlRelation(images, "itemid", "file"));
|
||||||
officeTable->select();
|
itemTable->select();
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
//! [1]
|
//! [1]
|
||||||
scene = new QGraphicsScene(this);
|
scene = new QGraphicsScene(this);
|
||||||
scene->setSceneRect(0, 0, 465, 615);
|
scene->setSceneRect(0, 0, 465, 365);
|
||||||
setScene(scene);
|
setScene(scene);
|
||||||
|
|
||||||
addItems();
|
addItems();
|
||||||
|
|
||||||
QGraphicsPixmapItem *logo = scene->addPixmap(QPixmap(":/logo.png"));
|
setMinimumSize(470, 370);
|
||||||
logo->setPos(30, 515);
|
setMaximumSize(470, 370);
|
||||||
|
|
||||||
setMinimumSize(470, 620);
|
QLinearGradient gradient(QPointF(0, 0), QPointF(0, 370));
|
||||||
setMaximumSize(470, 620);
|
gradient.setColorAt(0, QColor("#868482"));
|
||||||
|
gradient.setColorAt(1, QColor("#5d5b59"));
|
||||||
setWindowTitle(tr("Offices World Wide"));
|
setBackgroundBrush(gradient);
|
||||||
}
|
}
|
||||||
//! [1]
|
//! [1]
|
||||||
|
|
||||||
//! [3]
|
//! [3]
|
||||||
void View::addItems()
|
void View::addItems()
|
||||||
{
|
{
|
||||||
int officeCount = officeTable->rowCount();
|
int itemCount = itemTable->rowCount();
|
||||||
|
|
||||||
int imageOffset = 150;
|
int imageOffset = 150;
|
||||||
int leftMargin = 70;
|
int leftMargin = 70;
|
||||||
int topMargin = 40;
|
int topMargin = 40;
|
||||||
|
|
||||||
for (int i = 0; i < officeCount; i++) {
|
for (int i = 0; i < itemCount; i++) {
|
||||||
ImageItem *image;
|
ImageItem *image;
|
||||||
QGraphicsTextItem *label;
|
QGraphicsTextItem *label;
|
||||||
QSqlRecord record = officeTable->record(i);
|
QSqlRecord record = itemTable->record(i);
|
||||||
|
|
||||||
int id = record.value("id").toInt();
|
int id = record.value("id").toInt();
|
||||||
QString file = record.value("file").toString();
|
QString file = record.value("file").toString();
|
||||||
QString location = record.value("location").toString();
|
QString item = record.value("itemtype").toString();
|
||||||
|
|
||||||
int columnOffset = ((i / 3) * 37);
|
int columnOffset = ((i % 2) * 37);
|
||||||
int x = ((i / 3) * imageOffset) + leftMargin + columnOffset;
|
int x = ((i % 2) * imageOffset) + leftMargin + columnOffset;
|
||||||
int y = ((i % 3) * imageOffset) + topMargin;
|
int y = ((i / 2) * imageOffset) + topMargin;
|
||||||
|
|
||||||
image = new ImageItem(id, QPixmap(":/" + file));
|
image = new ImageItem(id, QPixmap(":/" + file));
|
||||||
image->setData(0, i);
|
image->setData(0, i);
|
||||||
image->setPos(x, y);
|
image->setPos(x, y);
|
||||||
scene->addItem(image);
|
scene->addItem(image);
|
||||||
|
|
||||||
label = scene->addText(location);
|
label = scene->addText(item);
|
||||||
QPointF labelOffset((150 - label->boundingRect().width()) / 2, 120.0);
|
label->setDefaultTextColor(QColor("#d7d6d5"));
|
||||||
|
QPointF labelOffset((120 - label->boundingRect().width()) / 2, 120.0);
|
||||||
label->setPos(QPointF(x, y) + labelOffset);
|
label->setPos(QPointF(x, y) + labelOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,7 +119,7 @@ void View::mouseReleaseEvent(QMouseEvent *event)
|
|||||||
void View::showInformation(ImageItem *image)
|
void View::showInformation(ImageItem *image)
|
||||||
{
|
{
|
||||||
int id = image->id();
|
int id = image->id();
|
||||||
if (id < 0 || id >= officeTable->rowCount())
|
if (id < 0 || id >= itemTable->rowCount())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
InformationWindow *window = findWindow(id);
|
InformationWindow *window = findWindow(id);
|
||||||
@ -129,7 +130,7 @@ void View::showInformation(ImageItem *image)
|
|||||||
window->show();
|
window->show();
|
||||||
} else {
|
} else {
|
||||||
InformationWindow *window;
|
InformationWindow *window;
|
||||||
window = new InformationWindow(id, officeTable, this);
|
window = new InformationWindow(id, itemTable, this);
|
||||||
|
|
||||||
connect(window, SIGNAL(imageChanged(int,QString)),
|
connect(window, SIGNAL(imageChanged(int,QString)),
|
||||||
this, SLOT(updateImage(int,QString)));
|
this, SLOT(updateImage(int,QString)));
|
||||||
|
@ -53,7 +53,7 @@ class View : public QGraphicsView
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
View(const QString &offices, const QString &images, QWidget *parent = 0);
|
View(const QString &items, const QString &images, QWidget *parent = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mouseReleaseEvent(QMouseEvent *event);
|
void mouseReleaseEvent(QMouseEvent *event);
|
||||||
@ -73,7 +73,7 @@ private:
|
|||||||
QGraphicsScene *scene;
|
QGraphicsScene *scene;
|
||||||
QList<InformationWindow *> informationWindows;
|
QList<InformationWindow *> informationWindows;
|
||||||
//! [2] //! [3]
|
//! [2] //! [3]
|
||||||
QSqlRelationalTableModel *officeTable;
|
QSqlRelationalTableModel *itemTable;
|
||||||
};
|
};
|
||||||
//! [3]
|
//! [3]
|
||||||
|
|
||||||
|