Marble/MarbleSignalsSlots: Difference between revisions

    From KDE TechBase
    No edit summary
     
    (18 intermediate revisions by 7 users not shown)
    Line 1: Line 1:
    {{Template:I18n/Language Navigation Bar|Editing Projects/Marble/MarbleCPlusPlus}}
     
    {{TutorialBrowser|
    {{TutorialBrowser|


    Line 6: Line 6:
    name=Basic interaction with MarbleWidget|
    name=Basic interaction with MarbleWidget|


    pre=[http://mindview.net/Books/TICPP/ThinkingInCPP2e.html C++], [http://www.trolltech.com/products/qt/ Qt]|
    pre=[[Projects/Marble/MarbleMarbleWidget|Tutorial 2 - Changing basic map properties]]|


    next=[[Projects/Marble/MarbleGeoPainter|Tutorial 4 - GeoPainter: Painting onto the map]]|  
    next=[[Projects/Marble/Runners/LoadingKML|Tutorial 4 - Loading KML files into MarbleWidget]]|  
    }}
    }}




    == Creating a window with controls ==
    == Creating a window with controls ==
    We'd like to add other widgets to our Marble window: A zoom slider and a label that shows the current mouse position.
    We'd like to add other widgets to our Marble window: A '''zoom slider''' and a '''label''' that shows the current mouse position in '''geodetic''' coordinates: ''longitude'' and ''latitude''.


    In order to achieve this we need to create a vertical layout. Once done we add the slider and the label that we created to the layout. Also we zoom the globe to the slider's default value using the [http://api.kde.org/4.x-api/kdeedu/marble/classMarble_1_1MarbleWidget.html#d49d8ab0be0721c579bb511bdda45829 MarbleWidget::zoomView(int)] method.
    In order to achieve this we need to create a vertical layout. Once we are done we add the slider and the label that we created to the layout. Also we zoom the globe to the slider's default value using the [http://api.kde.org/4.x-api/kdeedu-apidocs/marble/html/classMarble_1_1MarbleWidget.html#d49d8ab0be0721c579bb511bdda45829 MarbleWidget::zoomView(int)] method.


    We want to center our globe onto South America. So we create a new [http://api.kde.org/4.x-api/kdeedu/marble/classMarble_1_1GeoDataCoordinates.html GeoDataCoordinates] object that takes the longitude and the latitude as a parameter and we call [http://api.kde.org/4.x-api/kdeedu/marble/classMarble_1_1MarbleWidget.html#7cda9942ead26d60c89a7b54a073a2fd MarbleWidget::centerOn].
    We want to center our globe onto South America. So we create a new [http://api.kde.org/4.x-api/kdeedu-apidocs/marble/html/classMarble_1_1GeoDataCoordinates.html GeoDataCoordinates] object that takes the longitude and the latitude as a parameter and we call [http://api.kde.org/4.x-api/kdeedu-apidocs/marble/html/classMarble_1_1MarbleWidget.html#7cda9942ead26d60c89a7b54a073a2fd MarbleWidget::centerOn].  


    Finally we connect the [http://doc.trolltech.com/signalsandslots.html signals and slots] that MarbleWidget offers to the signals and slots of the slider and the label:
    As you might have realized already GeoDataCoordinates is the geodetic "sister" of [http://doc.trolltech.com/qapplication.html QPoint]. They share a very similar API. Additionally GeoDataCoordinates features a nice set of string conversion methods ([http://api.kde.org/4.x-api/kdeedu-apidocs/marble/html/classMarble_1_1GeoDataCoordinates.html#ce27e6f714e21be067995c2cf96544d6 GeoDataCoordinates::fromString()], [http://api.kde.org/4.x-api/kdeedu-apidocs/marble/html/classMarble_1_1GeoDataCoordinates.html#558b72384563190dc2ce119a1f75de86 GeoDataCoordinates::lonToString()] and [http://api.kde.org/4.x-api/kdeedu-apidocs/marble/html/classMarble_1_1GeoDataCoordinates.html#558b72384563190dc2ce119a1f75de86 GeoDataCoordinates::latToString()]). They are used in various places inside Marble such as the signal [http://api.kde.org/4.x-api/kdeedu-apidocs/marble/html/classMarble_1_1MarbleWidget.html#0869df8f4666014aff93d9ba1c130bc3 MarbleWidget::mouseMoveGeoPosition(const QString&) ].


    <code cppqt>
    Finally we connect the [http://qt-project.org/doc/qt-4.8/signalsandslots.html signals and slots] that MarbleWidget offers to the signals and slots of the slider and the label:
     
    <source lang="cpp">
    #include <QtGui/QApplication>
    #include <QtGui/QApplication>


    Line 47: Line 49:
         mapWidget->setShowScaleBar(false);
         mapWidget->setShowScaleBar(false);
         mapWidget->setShowCompass(false);
         mapWidget->setShowCompass(false);
        // Set the map quality to gain speed
        mapWidget->setMapQuality( NormalQuality, Still );
        mapWidget->setMapQuality( LowQuality, Animation );
          
          
         // Create a horizontal zoom slider and set the default zoom
         // Create a horizontal zoom slider and set the default zoom
    Line 90: Line 88:
         return app.exec();
         return app.exec();
    }
    }
    </code>
    </source>


    Save the code above as <tt>marble_control.cpp</tt> and compile it:
    Save the code above as <tt>marble_control.cpp</tt> and compile it:


    <code>
    <source lang="bash">
      g++ -I /usr/include/qt4/ -o marble_control marble_control.cpp -lmarblewidget -lQtGui
      g++ -I /usr/include/qt4/ -o marble_control marble_control.cpp -lmarblewidget -lQtGui -lQtCore
    </code>
    </source>
     
    If things go fine, execute <tt>./marble_control</tt> and you end up with a map application that displays our globe with a zoom slider below:
     
    [[Image:Marble_control.png]]


    If things go fine, execute <tt>./marble_control</tt> and you end up with a map application that displays our globe with a zoom slider below: [[Image:Marble_control.png]]
    The latest source code of this example can be found [https://quickgit.kde.org/?p=marble.git&a=blob&f=examples%2Fcpp%2Fmap-controls%2Fmain.cpp here].

    Latest revision as of 21:01, 10 March 2016

    Basic interaction with MarbleWidget
    Tutorial Series   Marble C++ Tutorial
    Previous   Tutorial 2 - Changing basic map properties
    What's Next   Tutorial 4 - Loading KML files into MarbleWidget
    Further Reading   n/a


    Creating a window with controls

    We'd like to add other widgets to our Marble window: A zoom slider and a label that shows the current mouse position in geodetic coordinates: longitude and latitude.

    In order to achieve this we need to create a vertical layout. Once we are done we add the slider and the label that we created to the layout. Also we zoom the globe to the slider's default value using the MarbleWidget::zoomView(int) method.

    We want to center our globe onto South America. So we create a new GeoDataCoordinates object that takes the longitude and the latitude as a parameter and we call MarbleWidget::centerOn.

    As you might have realized already GeoDataCoordinates is the geodetic "sister" of QPoint. They share a very similar API. Additionally GeoDataCoordinates features a nice set of string conversion methods (GeoDataCoordinates::fromString(), GeoDataCoordinates::lonToString() and GeoDataCoordinates::latToString()). They are used in various places inside Marble such as the signal MarbleWidget::mouseMoveGeoPosition(const QString&) .

    Finally we connect the signals and slots that MarbleWidget offers to the signals and slots of the slider and the label:

    #include <QtGui/QApplication>
    
    #include <QtGui/QLayout>
    #include <QtGui/QSlider>
    #include <QtGui/QLabel>
    
    #include <marble/MarbleWidget.h>
    
    using namespace Marble;
    
    int main(int argc, char** argv)
    {
        QApplication app(argc,argv);
        QWidget *window = new QWidget;
    
        // Create a Marble QWidget without a parent
        MarbleWidget *mapWidget = new MarbleWidget();
    
        // Load the Plain map
        mapWidget->setMapThemeId("earth/plain/plain.dgml");
    
        // Hide the FloatItems: OverviewMap, ScaleBar and Compass
        mapWidget->setShowOverviewMap(false);
        mapWidget->setShowScaleBar(false);
        mapWidget->setShowCompass(false);
        
        // Create a horizontal zoom slider and set the default zoom
        QSlider * zoomSlider = new QSlider(Qt::Horizontal);
        zoomSlider->setMinimum( 1000 );
        zoomSlider->setMaximum( 2400 );
        
        mapWidget->zoomView( zoomSlider->value() );
    
        // Create a label to show the geodetic position
        QLabel * positionLabel = new QLabel();
        positionLabel->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
    
        // Add all widgets to the vertical layout.
        QVBoxLayout *layout = new QVBoxLayout;
        layout->addWidget(mapWidget);
        layout->addWidget(zoomSlider);
        layout->addWidget(positionLabel);
    
        // Center the map onto a given position
        GeoDataCoordinates home(-60.0, -10.0, 0.0, GeoDataCoordinates::Degree);
        mapWidget->centerOn(home);
        
        // Connect the map widget to the position label.
        QObject::connect( mapWidget, SIGNAL( mouseMoveGeoPosition( QString ) ),
                          positionLabel, SLOT( setText( QString ) ) );
    
        // Connect the zoom slider to the map widget and vice versa.
        QObject::connect( zoomSlider, SIGNAL( valueChanged(int) ),
                          mapWidget, SLOT( zoomView(int) ) );
        QObject::connect( mapWidget, SIGNAL( zoomChanged(int) ),
                          zoomSlider, SLOT( setValue(int) ) );
    
        window->setLayout(layout);
        window->resize( 400, 300 );
    
        window->show();
    
        return app.exec();
    }
    

    Save the code above as marble_control.cpp and compile it:

     g++ -I /usr/include/qt4/ -o marble_control marble_control.cpp -lmarblewidget -lQtGui -lQtCore
    

    If things go fine, execute ./marble_control and you end up with a map application that displays our globe with a zoom slider below:

    The latest source code of this example can be found here.