- Release plans recap for the road to QGIS 1.0
- New version of eVis
- Contour Lines in Qgis
- QGIS and Google Summer of Code
- Quantum GIS Graduates OSGeo Incubation
- Paolo Cavallini Named to QGIS Project Steering Committee
- Nominations for QGIS PSC Open
- Capturing map coordinates in a stand alone app...
- Tutorial 7 - Creating spatial datasets with the QGIS API
- Html Image Plugin 0.2
Tutorial 2: Using MapTools with the QGIS Canvas API
Earlier this week I wrote up a simple tutorial showing the useage of the QgsMapCanvas api to create a simple application that loads a shapefile and displays the points in it. But what good is map that you can't interact with? Enter QgsMapTool - the base class for all tools that need to interact with the canvas.

Today I will extend the last tutorial by making it a QMainWindow application with a menu, toolbar and canvas area. The purpose of the tutorial is to provide a demonstrator project, so I wont promise to write the most elegant or robust C++ code. The project will provide 4 toolbar icons for
- loading a map layer (layer name is hard coded in the application
- zooming in
- zooming out
- panning
The entire project can be checked out form the QGIS Subversion repository using the following command:
svn co https://svn.qgis.org/repos/qgis/trunk/code_examples/2_basic_main_window
In the working directory for the tutorial code you will find a number of files including c++ sources, icons and a simple data file under data. There is also the .ui file for the main window.
Note: You will need to edit the .pro file in the above svn directory to match your system.
Since much of the code is the same as the previous tutorial, I will focus on the MapTool specifics - the rest of the implementation details can be investigated by checking out the project form SVN. A QgsMapTool is a class that interacts with the MapCanvas using the mouse pointer. QGIS has a number of QgsMapTools implemented, and you can subclass QgsMapTool to create your own. In mainwindow.cpp you will see I include the headers for the QgsMapTools near the start of the file:
30 //
31 // QGIS Map tools
32 //
33 #include "qgsmaptoolpan.h"
34 #include "qgsmaptoolzoom.h"
35 //
36 // These are the other headers for available map tools (not used in this example)
37 //
38 //#include "qgsmaptoolcapture.h"
39 //#include "qgsmaptoolidentify.h"
40 //#include "qgsmaptoolselect.h"
41 //#include "qgsmaptoolvertexedit.h"
42 //#include "qgsmeasure.h"
As you can see, I am only using two types of MapTool subclasses for this tutorial, but there are more available in the QGIS library. Hooking up our MapTools to the canvas is very easy using the normal Qt4 signal/slot mechanism:
78 //create the action behaviours
79 connect(mActionPan, SIGNAL(triggered()), this, SLOT(panMode()));
80 connect(mActionZoomIn, SIGNAL(triggered()), this, SLOT(zoomInMode()));
81 connect(mActionZoomOut, SIGNAL(triggered()), this, SLOT(zoomOutMode()));
82 connect(mActionAddLayer, SIGNAL(triggered()), this, SLOT(addLayer()));
Next we make a small toolbar to hold our toolbuttons. Note that the mpAction* actions were created in designer.
84 //create a little toolbar
85 mpMapToolBar = addToolBar(tr("File"));
86 mpMapToolBar->addAction(mpActionAddLayer);
87 mpMapToolBar->addAction(mpActionZoomIn);
88 mpMapToolBar->addAction(mpActionZoomOut);
89 mpMapToolBar->addAction(mpActionPan);
Thats really pretty straightforward Qt stuff too. Now we create our three map tools:
91 //create the maptools
92 mpPanTool = new QgsMapToolPan(mpMapCanvas);
93 mpPanTool->setAction(mpActionPan);
94 mpZoomInTool = new QgsMapToolZoom(mpMapCanvas, FALSE); // false = in
95 mpZoomInTool->setAction(mpActionZoomIn);
96 mpZoomOutTool = new QgsMapToolZoom(mpMapCanvas, TRUE ); //true = out
97 mpZoomOutTool->setAction(mpActionZoomOut);
Again nothing here is very complicated - we are creating tool instances, each of which is associated with the same mapcanvas, and a different QAction. When the user selects one of the toolbar icons, the active MapTool for the canvas is set. For example when the pan icon is clicked, we do this:
110 void MainWindow::panMode()
111 {
112 mpMapCanvas->setMapTool(mpPanTool);
113
114 }
Conclusion
As you can see extending our previous example into something more functional using MapTools is really easy and only requires a few lines of code for each MapTool you want to provide. I should take a moment here to give Martin Dobias a big thank you for the new and improved MapCanvas (with MapTools) API that is part of the upcoming QGIS 0.8 release! I have various ideas for future tutorials including:
- how to make your own Qt4 designer mapping widget using libqgis and an extended version of this tutorial
- how to create your own MapTool subclass
- how to make a plugin that implements its own MapTools
If you have any strong urge to see a tutorial for one of the above (or something completely different), drop a note in the comments below and Ill see what I can do!
technorati tags:QgsMapCanvas, MapTool, c++, subversion, tutorial
| Attachment | Size |
|---|---|
| mapcanvas_tut2.jpg | 22.72 KB |
- Tim Sutton's blog
- Add new comment
- 8222 reads

Getting Tutorial Code Working with 0.9.1
Hi Tim,
Iv downloaded your tutorial and am trying to get it working with the latest version of QGIS (0.9.1).
Im using OpenSuse 10.3 and have installed the latest version of QGIS with an rpm install.
Now when trying to compile i have been getting the following error:
In file included from main.cpp:19:
/usr/include/qgis/qgsapplication.h:21: error: function definition does not declare parameters
I have used your .pro file which i have edited and included at the bottom of the post.
for the QGISSRCDIR path i have downloaded the QGIS 0.9.1 tarbal, but including this did not help.
Any help will be really appreciated.
thanks in advance
nlev.
/*******************************************************************************************/
TEMPLATE = app
TARGET = qgis_test
QT = qt3support sql opengl network svg gui core xml
LANGUAGE= C++
linux-g++{
QGISDIR=/usr
QGISLIBDIR=$${QGISDIR}/lib
QGISSRCDIR=/home/user/Desktop/qgis_0.9.1/qgis_0.9.1/src
QGISPLUGINDIR=$${QGISLIBDIR}/qgis
DEFINES += QGISPLUGINDIR=$${QGISPLUGINDIR}
LIBS = -L$${QGISLIBDIR} -lqgis_core -lproj -lqgis_gui
}
INCLUDEPATH = $${QGISDIR}/include/qgis \
$${QGISSRCDIR}/core \
$${QGISSRCDIR}/gui \
$${QGISSRCDIR}/plugins \
$${QGISSRCDIR}/providers \
$${QGISSRCDIR}/raster \
$${QGISSRCDIR}/ui
CONFIG += qt gui exceptions stl warn_on debug thread
#RESOURCES += resources.qrc
FORMS += mainwindowbase.ui
HEADERS += mainwindow.h
SOURCES += main.cpp \
mainwindow.cpp
/******************************************************************************/
Update .pro file
Just to answer my own question:
you need to include the following to the .pro file definitions:
DEFINES += QGISPLUGINDIR=$${QGISPLUGINDIR} CORE_EXPORT= GUI_EXPORT=
the CORE_EXPORT is used with windows and left blank with linux in the QGIS CCMake file.
therefore it is just required to be declared and left a null for linux compilations
HOW TO COMPILE QGIS FROM SOURCE CODE FOR WINDOWS
HOW TO COMPILE QGIS FROM SOURCE CODE FOR WINDOWS?
after installation,am nt able to find the src folder from where i hv to run the perl script to add extra plugins...solution???
cn i copy src folder from qgis source code to installed qgis folder..will it work???
plugin building problem
hi,
I hv tried creating new plugin to qgis by follwing steps
1.downloaded qgis 0.8 setup.exe
2.installed qgis
3.run plugin_bulder.pl script
4.created it...but to build it i should run autogen.sh,configure,make
5.before that there must be qgis.m4 in share\aclocal directory as mentioned in tutorial...I DONT HAVE SUCH FILE(QGIS.M4).IS IT BECOZ OF THAT AM NT ABLE TO RUN AUTOGEN.SH...???????
should i download it seperately
my plaform is windows XP..any probs becoz of that?
Beginner - Can't get this code working in Ubuntu Dapper
MUST WORK. I have QGIS 0.7.4 installed and I've added its source file directories (core, gui etc.) to /usr/include/qgis. I changed the project file (2_basic_main_window.pro): QGISDIR=/usr, QGISSRCDIR=/usr/include/qgis and QGISLIBDIR=$${QGISDIR}/lib. I have both qt3 and *qt4 installed.
I installed QGIS0.8 and libqgis0.8_dev0. Now I get many undefined references for libqgis_gui.a. How can I fix this? Which version of QGIS is used for above code?
Any comments will be much appreciated. I really need to get this working soon.
Needs QGIS 0.8
Hi
I'm sorry I should have made it clear that the examples are written for the 0.8 (preview) release so ignore the 0.7.4 stuff on your system.
QGISDIR=[path to installed qgis - should be 0.8 installation path]
QGISLIBDIR=$${QGISDIR}/lib
QGISSRCDIR=[path to qgis/src directory - as checked out from SVN]
Currently you need the full QGIS sources as all the necessary headers arent included in the qgis_dev package.
I havent tested the example with the package based install of 0.8. I suggest installing qgis0.8 from source until such time as its tested and proven to work with the packages. I need to get Steve to work out how to get all the headers included in the dev package first too..
Hope that helps - write back if you have more questions...
Regards
Tim
QGIS Beginner - Can't get this code working in Ubuntu Dapper
Thanks for great tutorial!
I followed the exact steps for Building QGIS [0.7.4] on Ubuntu Step by Step [but replacing Qt3 with Qt4] and installed QGIS 0.8 from svn trunk/qgis tarball.
Now it works:-)
Glad you got it working
Hi
Sorry I didnt get back to your earlier query - I was busy reinstalling my machine...I'm glad you have it working now. Note I updated the step by step notes on the wiki with Dapper specific info.
Regards
Tim