ãã®æçš¿ã¯ãã³ã³ãã¹ãã Smart Phones for Smart Posts ãã«åå ããŠããŸã
åã®èšäºã§ã¯ãQMLã§ãããã³ã°ã¢ããªã±ãŒã·ã§ã³ãäœæããæ¹æ³ãåŠã³ãŸãããä»æ¥ã¯ãAPIã¢ãžã¥ãŒã«QtLocationã䜿çšããŠãã°ã©ãã£ã«ã«ãªè¡šçŸQt Graphics Viewã®ã¢ãŒããã¯ãã£ã«åºã¥ãã¢ããªã±ãŒã·ã§ã³ã®éçºãæ€èšããŸãã ãã®èšäºã¯ãçè«ãšå®çšã®2ã€ã®éšåã«åããããšãã§ããŸãã çè«éšåã§ã¯ã ã°ã©ãã£ãã¯ã¹ãã¥ãŒã®ã¢ãŒããã¯ãã£ãšQtLocationã¢ãžã¥ãŒã«ã䜿çšããäž»ãªãã€ã³ãã«ã€ããŠèª¬æããŸãã å®éã®éšåã§ã¯ããããžã§ã¯ããæåããäœæããããšã¯èª¬æããŸãããããããã®æ £æ§éåãç¹å®ã®åº§æšãžã®ã¢ãã¡ãŒã·ã§ã³åãããé·ç§»ã GPSäœçœ®ãããã¹ãæ å ±ã®ã¹ã±ãŒãªã³ã°ãšè¡šç€ºã®ããã®èŠçŽ ãªã©ããããžã§ã¯ãã®æãèå³æ·±ãæ©èœã®ã³ãŒããæäŸããŸãã
åã®èšäºããè¿œå ã®ãã©ã°ã€ã³ãåéããå Žåããã®ãããžã§ã¯ãã§ãããã䜿çšã§ããŸãã
ç®æ¬¡
- ã°ã©ãã£ãã¯ã¹ãã¥ãŒã¢ãŒããã¯ãã£
- ã°ã©ãã£ãã¯èŠçŽ ã®çŽ¹ä»
- QtLocationã¢ãžã¥ãŒã«
- å°å³ãšãµãŒãã¹
- GPS座æšã®ååŸ
- ãããžã§ã¯ãåæ
- ãã³ããšã³ã
- ãããã«
- åç §è³æ
ã°ã©ãã£ãã¯ã¹ãã¥ãŒã¢ãŒããã¯ãã£
ã°ã©ãã£ãã¯è¡šçŸã®ã¢ãŒããã¯ãã£ã¯ã QGraphicsSceneããŒã¿ãä¿åããã¯ã©ã¹ãšããã®ããŒã¿QGraphicsViewãèŠèŠåããã¯ã©ã¹ãæã£ãŠãããšããæå³ã§ã ã¢ãã«/ãã¥ãŒã®ã¢ãŒããã¯ãã£ã«äŒŒãŠããŸãã å¿ èŠã«å¿ããŠãåãã·ãŒã³ãç°ãªããã¥ãŒã§èŠèŠåã§ããŸãã ã°ã©ãã£ãã¯ã·ãŒã³ã«ã¯ãèŠçŽ -æœè±¡ã¯ã©ã¹QGraphicsItemãã掟çããã¯ã©ã¹ã®ãªããžã§ã¯ããå«ãŸããŸãã
æåãããé床ã®åäžãšæ©èœã®æ¡åŒµãç®çãšããã°ã©ãã£ãã¯è¡šçŸã®ã¢ãŒããã¯ãã£ã®éçºã«å€ãã®åªåã泚ãããŸããã ã·ãŒã³ã¯ã¹ã±ãŒãªã³ã°ãå転ãå°å·ã§ããŸãã衚瀺ããã«ã¯ãçµã¿èŸŒã¿ã®Qtãšã³ãžã³ãšOpenGLã©ã€ãã©ãªã®äž¡æ¹ã䜿çšããŸãã ãã®ã¢ãŒããã¯ãã£ã¯ãã¢ãã¡ãŒã·ã§ã³ãšãã©ãã°ã¢ã³ãããããããµããŒãããŠããŸãã ã°ã©ãã£ãã¯ã·ãŒã³ã¯ããŠãããããæ°äžåã®èŠçŽ ãŸã§ã®è¡šç€ºã«é©ããŠããŸãã40,000ãããã®äŸãè¯ãäŸã§ãã QWidgetãã掟çãããŠã£ãžã§ãããã¹ããŒãžã«é 眮ã§ããŸãããã®ããã«ã¯ããŠã£ãžã§ãããQGraphicsProxyWidgetã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ã ããããã·ãŠã£ãžã§ãããã¹ããŒãžã«é 眮ããå¿ èŠããããŸãã ãããã·ãŠã£ãžã§ããïŒãŸãã¯QWidgetãªããžã§ã¯ãèªäœïŒã¯äœéã§ããããã®é床äœäžãé¡èã«ãªããã©ããã¯ã¢ããªã±ãŒã·ã§ã³ã«ãã£ãŠç°ãªããŸãïŒè©³çŽ°ã«ã€ããŠã¯ã QtLabs [En]ãåç §ããŠãã ããïŒã
ã°ã©ãã£ãã¯èŠçŽ ã®çŽ¹ä»
QGraphicsItemã¯ã©ã¹ã¯ããã¹ãŠã®ã°ã©ãã£ãã¯èŠçŽ ã®åºæ¬ã¯ã©ã¹ã§ãã 2ã€ã®çŽç²ã«ä»®æ³çãªã¡ãœããã boundingRectïŒïŒããã³paintïŒïŒãããããããã®ã€ã³ã¹ã¿ã³ã¹ãäœæããããšã¯ã§ããŸããã paintïŒïŒã¡ãœããã¯QWidget :: paintEventïŒïŒã¡ãœããã«å¯Ÿå¿ãããã®å®è£ ã¯èŠçŽ ãæç»ããå¿ èŠããããŸãã boundingRectïŒïŒã¡ãœããã¯ãã€ã³ãã©ã¹ãã©ã¯ãã£ã«èŠçŽ ã®å¢çç©åœ¢ã«ã€ããŠéç¥ããŸã-è¡çªãæ€åºããèŠããªãèŠçŽ ãåæç»ããªãããã«äœ¿çšãããŸãã ãã®ã¯ã©ã¹ã¯ãããŠã¹ããã³ããŒããŒãã€ãã³ãããã©ãã°ã¢ã³ããããããèŠçŽ ã®ã°ã«ãŒãåããµããŒãããŸãã ã€ãã³ãåŠçã¯æ¬¡ã®ããã«æ©èœããŸãããã¥ãŒã¯ããŠã¹ã€ãã³ããšããŒããŒãã€ãã³ããåä¿¡ããããããã·ãŒã³ã®ã€ãã³ãã«å€æããã·ãŒã³ã®åº§æšã«åŸã£ãŠåº§æšãå€æŽããã€ãã³ããç®çã®èŠçŽ ã«æž¡ããŸãã
QtLocationã¢ãžã¥ãŒã«
QtLocationã¢ãžã¥ãŒã«ã¯ãäœçœ®æ å ±ã«ã¢ã¯ã»ã¹ããããã®äŸ¿å©ãªã€ã³ã¿ãŒãã§ãŒã¹ãéçºè ã«æäŸããŸãã APIã䜿çšãããšãè¡æã®ãªã¹ããä»ã®ãœãŒã¹ããã®ããŒã¿ãªã©ã®æ å ±ãœãŒã¹ããæœè±¡åã§ããŸãã
QtLocationã«ã¯ãããã²ãŒã·ã§ã³ã®ããŸããŸãªåŽé¢ã«é¢é£ããäžé£ã®ã¯ã©ã¹ãä»å±ããŠããŸãã ã°ããŒãã«ããžã·ã§ãã³ã°ã·ã¹ãã ïŒGPSïŒãŸãã¯ä»ã®äœçœ®æ å ±æºã䜿çšããŠãŠãŒã¶ãŒã®äœçœ®ã«é¢ããæ å ±ãæäŸããQGeoPositionInfoSourceãªã©ã®ããŒããŠã§ã¢é¢é£ã®ã¯ã©ã¹ãããã³è¡æ枬äœæ å ±ãååŸããããã«äœ¿çšãããQGeoSatelliteInfoSourceãå«ãŸããŸãã
ãã®ã¢ãžã¥ãŒã«ã«ã¯ã緯床ãçµåºŠãé«åºŠãå«ãQGeoCoordinateãªã© ãäœçœ®æ å ±ãèšè¿°ããããšãäž»ãªç®çãšããå€ãã®ã¯ã©ã¹ãå«ãŸããŠããŸãã QtLocationã¯ã QGeoBoundingAreaã®ãããªæœè±¡çãªåœ¢åŒã§ããŸãã¯ããæ£ç¢ºã«ã QGeoBoundingBoxãQGeoBoundingCircleã®ããã«ãå°ççé åãè¡šãæ¹æ³ãæäŸããŸãã
å°å³ãšãµãŒãã¹
ããããã·ãŒã³ãããã³ãã¥ãŒã®æäœãéå§ããåã«ãæåã«å°çããŒã¿ã®ãœãŒã¹ã«ã¢ã¯ã»ã¹ããå¿ èŠããããŸãã ãããè¡ãäžè¬çãªæ¹æ³ã¯ã QGeoServiceProviderã䜿çšããããšã§ã ã å©çšå¯èœãªãµãŒãã¹ã調ã¹ãã«ã¯ã QGeoServiceProvider :: availableServiceProvidersïŒïŒã䜿çšããŸããå©çšå¯èœãªãµãŒãã¹ããªãå Žåã¯ç©ºã®QStringListãè¿ããããéçºè ã¯ãã®ãªãã·ã§ã³ããã§ãã¯ããå¿ èŠããããŸãã
QStringList services = QGeoServiceProvider::availableServiceProviders(); if (services.isEmpty()) { // }
ãµãŒãã¹ãããã€ããŒãåãåããšã QGeoMappingManagerãååŸã§ããŸããããã«ããããããã€ã¡ãŒãžãååŸã§ããŸãã
QGeoMappingManager *manager = service.mappingManager();
ããããŸãã¯ã«ãŒãã£ã³ã°ã§ãªããžã§ã¯ããæ€çŽ¢ãããããããŒãžã£ãŒã«èŠæ±ããã«ã¯ã searchManagerïŒïŒãŸãã¯routingManagerïŒïŒãåŒã³åºãå¿
èŠããããŸãã
ãŠãŒã¶ãŒã®ããããæç»ããããã«ã QtLocationã¯QGraphicsGeoMapã¯ã©ã¹ãæäŸããŠQGeoMappingManagerããã®ããŒã¿ã衚瀺ããŸãã å¿ èŠãªã®ã¯ãéåžžã®æ¹æ³ã§ãã¥ãŒãšã·ãŒã³ãäœæããã·ãŒã³ã«ããããè¿œå ããããšã§ãã
QGraphicsScene scene; QGraphicsView view; view.setScene(&scene); QGraphicsGeoMap *geoMap = new QGraphicsGeoMap(manager); scene.addItem(geoMap);
GPS座æšã®ååŸ
GPS座æšãååŸããã«ã¯ã QGeoPositionInfoSource :: createDefaultSourceïŒïŒãåŒã³åºããŠQGeoPositionInfoSourceãäœæããå¿ èŠããããŸãã ããã«ãã ã QGeoPositionInfoã®åº§æšã«é¢ããããŸããŸãªæ å ±ã«ã¢ã¯ã»ã¹ã§ããŸãã ãã±ãŒã·ã§ã³ããŒã¿ãå¿ èŠãšããã¯ã©ã€ã¢ã³ãã¯ã positionUpdatedïŒïŒã·ã°ãã«ã«æ¥ç¶ããŠã QGeoPositionInfoSourceãstartUpdatesïŒïŒãŸãã¯requestUpdateïŒïŒãåŒã³åºããŠãã®ã·ã°ãã«ã®éä¿¡ãéå§ã§ããããã«ããŸãã
ãã±ãŒã·ã§ã³ããŒã¿ãåä¿¡ããã¯ã©ã€ã¢ã³ãã®äŸïŒ
class MyClass : public QObject { Q_OBJECT public: MyClass(QObject *parent = 0) : QObject(parent) { QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(this); if (source) { connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo))); source->startUpdates(); } } private slots: void positionUpdated(const QGeoPositionInfo &info) { qDebug() << "Position updated:" << info; } };
å®æçãªäœçœ®ã®æŽæ°ãå¿ èŠãªå Žåã setUpdateIntervalïŒïŒã䜿çšããŠããããã®æŽæ°ãçºçããé »åºŠã決å®ã§ããŸãã ééãæå®ãããŠããªãå ŽåãæŽæ°ã¯å©çšå¯èœã«ãªã£ããšãã«è¡ãããŸãã ããšãã°ãã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã30ç§ããšã«æŽæ°ããå¿ èŠãããå ŽåïŒ
// Emit updates every 30 seconds if available QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(someParent); if (source) source->setUpdateInterval(30000);
ç¹å®ã®åº§æšãžã®ã¢ãã¡ãŒã·ã§ã³åãããé·ç§»
ããã§ãç§ãã¡ã¯ãã¹ãŠãã©ã®ããã«æ©èœãããã«ã€ããŠã®äžè¬çãªã¢ã€ãã¢ãåŸãŸãããä»ãç§ãã¡ã¯ã³ãŒãã«è¡ãããšãã§ããŸãã ç¹å®ã®åº§æšãžã®ã¹ã ãŒãºãªãããã®åããäœæããã«ã¯ã QGraphicsGeoMapã¯ã©ã¹ã«ãã£ãŠæäŸãããæ©èœãæ¡åŒµããå¿ èŠããããŸãã
class GeoMap : public QGraphicsGeoMap { Q_OBJECT Q_PROPERTY(double centerLatitude READ centerLatitude WRITE setCenterLatitude) Q_PROPERTY(double centerLongitude READ centerLongitude WRITE setCenterLongitude) public: GeoMap(QGeoMappingManager *manager, QGraphicsItem *parent = 0); void animatedPanTo(const QGeoCoordinate& center); double centerLatitude() const { return center().latitude(); } void setCenterLatitude(double lat); double centerLongitude() const { return center().longitude(); } void setCenterLongitude(double lon); //...
ããã³å®è£ ïŒ
void GeoMap::animatedPanTo(const QtMobility::QGeoCoordinate ¢er) { QGeoCoordinate curStart(this->center()); if (curStart == center) return; // setStatusBarText(QString("Panning to %1").arg(center.toString(QGeoCoordinate::Degrees))); QPropertyAnimation *latAnim = new QPropertyAnimation(this, "centerLatitude"); latAnim->setEndValue(center.latitude()); latAnim->setDuration(300); QPropertyAnimation *lonAnim = new QPropertyAnimation(this, "centerLongitude"); lonAnim->setEndValue(center.longitude()); lonAnim->setDuration(300); QParallelAnimationGroup *group = new QParallelAnimationGroup; group->addAnimation(latAnim); group->addAnimation(lonAnim); group->start(QAbstractAnimation::DeleteWhenStopped); } void GeoMap::setCenterLatitude(double lat) { QGeoCoordinate c = center(); c.setLatitude(lat); setCenter( c); } void GeoMap::setCenterLongitude(double lon) { QGeoCoordinate c = center(); c.setLongitude(lon); setCenter( c); }
ããã§ã animatedPanToïŒïŒãåŒã³åºããšããããã¯æå®ããã座æšã«ãåžæããè§åºŠã§ãã€ãŸã æ°ãã座æšãçŸåšã®äžå¿ã«å¯ŸããŠçžå¯Ÿçã«é«ãå Žåããããã¯äžã«ç§»åããŸãã QPropertyAnimationã¯ããã©ã«ãã§ã¯QGeoCoordinateã§åäœããªããããã¢ãã¡ãŒã·ã§ã³ã§äœ¿çšã§ãã2ã€ã®ããããã£ã§ããããè£å®ããŸããïŒãµããŒããããŠããã¿ã€ãã®ãªã¹ã ïŒã ãã¡ããã ã€ã³ã¿ãŒã ã¬ãŒã¿ãŒãç»é²ãã QVariantã«QGeoCoordinateãç»é²ããããšãã§ããŸãããããããã£ã䜿çšãããšãã¯ããã«ãããããããšã¬ã¬ã³ãã«ãªããŸãã
ãã³ããžã§ã¹ãã£ãŒ
Qtã«ã¯ãå ¥åæ¹æ³ã«é¢ä¿ãªããäžé£ã®ã€ãã³ãããã€ãã³ããçæãããžã§ã¹ãã£ããã°ã©ãã³ã°ãã¬ãŒã ã¯ãŒã¯ãå«ãŸããŠããŸãã ãžã§ã¹ãã£ã¯ãããŠã¹ã®åããã¿ããã¹ã¯ãªãŒã³ã®ã¿ããããŸãã¯ä»ã®ãœãŒã¹ããã®äžé£ã®ã€ãã³ãã§ãã Qtã§ã¯ããžã§ã¹ãã£ãŒåŠçã¯QPanGesture ã QPinchGestureãããã³QSwipeGestureã®ã¯ã©ã¹ã§è¡šãããŸãã ã¹ã©ã€ãã¯ãç»åãå¢æžããããã«äœ¿çšãããŸãããã®å Žåãå°å³ã®çž®å°ºãå€æŽããŸãã ã¯ã©ã¹ã«å®è£ ããã«ã¯ã grabGestureïŒQt :: PinchGestureïŒã¡ãœãããåŒã³åºããŠãã®ãžã§ã¹ãã£ãŒã®åŠçãæå¹ã«ã ããããã®sceneEventïŒïŒã§åŠçããå¿ èŠããããŸãã
bool GeoMap::sceneEvent(QEvent *event) { switch (event->type()) { case QEvent::Gesture: { if (QGestureEvent *gesture = static_cast<QGestureEvent *>(event)) { if (QPinchGesture *pinch = static_cast<QPinchGesture *>(gesture->gesture(Qt::PinchGesture))) { qreal scale = qLn(pinch->scaleFactor())/qLn(2); qreal zoom = 0; zoom = scale > 0 ? 1 : -1; setZoomLevel(zoomLevel() + zoom); return true; } } } default: break; } return QGraphicsGeoMap::sceneEvent(event); }
Qtã§ã¯ãç»é¢äžã®ã¿ããã€ãã³ãã«å ããŠã ãžã§ã¹ãã£ãŒãåŠçã§ããŸãã ãããããŠã£ãžã§ããã§åãå ¥ããã«ã¯ã Qt :: WA_AcceptTouchEventså±æ§ãèšå®ããå¿ èŠããããã°ã©ãã£ãã¯èŠçŽ ã®å Žåã¯acceptTouchEventsïŒtrueïŒãåŒã³åºããŸã ã
ãããã£ãã¯ã¹ã¯ããŒã«
ãããã£ãã¯ã¹ã¯ããŒã«ã¯å°å³ã®æ £æ§éåã§ããããã®æ©èœãèšèã§ããæ£ç¢ºã«äŒããæ¹æ³ãããããªãã®ã§ãåç»ãæçš¿ããŸããã100åèªããããäžåºŠèŠãã»ããããã§ãã ãã®æ©èœãå®è£ ããŠããŸãã ããããŒãã¡ã€ã«ã®æ®ãã®éšåïŒ
protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); void wheelEvent(QGraphicsSceneWheelEvent *event); void keyPressEvent(QKeyEvent * event); void keyReleaseEvent(QKeyEvent * event); bool sceneEvent(QEvent *event); private slots: void kineticTimerEvent(); private: void panFloatWrapper(const QPointF & delta); void applyPan(const Qt::KeyboardModifiers & modifiers); void setStatusBarText(const QString &text); private: bool panActive; bool panDecellerate; // Fractional pan, used by panFloatWrapper QPointF remainingPan; // current kinetic panning speed, in pixel/msec QPointF kineticPanSpeed; QPoint panDir; QTimer kineticTimer; QTime lastMoveTime; // An entry in the mouse history. first=speed, second=time typedef QPair<QPointF, QTime> MouseHistoryEntry; // A history of the last (currently 5) mouse move events is stored in order to smooth out // movement detection for kinetic panning QList<MouseHistoryEntry> mouseHistory; StatusBarItem *m_statusBar; };
ãã¡ãããå®è£ ã§æãèå³æ·±ãã®ã¯ãæåã«åããå¶åŸ¡ããããã®èšå®ãæ€èšããããšã§ãã
//////////////////////////////////////////////////////////////////////////////// // TODO: Some of these could be exposed in a GUI and should probably be put elsewhere in that case // (and made non-const) // Kinect annimation properties static const bool enableKineticPanning = true; // time until kinetic panning speed slows down to 50%, in msec static const qreal kineticPanningHalflife = 160.0; // keyboard panning speed without modifiers, in pixels/msec static const qreal panSpeedNormal = 0.3; // keyboard panning speed with shift, in pixels/msec static const qreal panSpeedFast = 1.0; // minimum panning speed, in pixels/msec static const qreal kineticPanSpeedThreshold = 0.005; // temporal resolution. Smaller values take more CPU but improve visual quality static const int kineticPanningResolution = 20; // maximum time between last mouse move and mouse release for kinetic panning to kick in static const int holdTimeThreshold = 100; ////////////////////////////////////////////////////////////////////////////////
äœã説æããå¿
èŠã¯ãªããšæããŸããã³ã¡ã³ããããã¹ãŠãæããã§ãã
å®è£ ã®æ®ãïŒ
void GeoMap::mousePressEvent(QGraphicsSceneMouseEvent *event) { setFocus(); if (event->button() == Qt::LeftButton) { panActive = true; // When pressing, stop the timer and stop all current kinetic panning kineticTimer.stop(); kineticPanSpeed = QPointF(); lastMoveTime = QTime::currentTime(); } event->accept(); } void GeoMap::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if (panActive) { setCursor(Qt::ClosedHandCursor); // Calculate time delta QTime currentTime = QTime::currentTime(); int deltaTime = lastMoveTime.msecsTo(currentTime); lastMoveTime = currentTime; // Calculate position delta QPointF delta = event->lastPos() - event->pos(); // Calculate and set speed if (deltaTime > 0) { kineticPanSpeed = delta / deltaTime; mouseHistory.push_back(MouseHistoryEntry(kineticPanSpeed, currentTime)); mouseHistory.pop_front(); } // Pan map panFloatWrapper(delta); } event->accept(); } void GeoMap::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) { if (event->button() == Qt::LeftButton && panActive) { panActive = false; setCursor(Qt::OpenHandCursor); if (!enableKineticPanning || lastMoveTime.msecsTo(QTime::currentTime()) > holdTimeThreshold) { return; } kineticPanSpeed = QPointF(); int entries_considered = 0; QTime currentTime = QTime::currentTime(); foreach(MouseHistoryEntry entry, mouseHistory) { // first=speed, second=time int deltaTime = entry.second.msecsTo(currentTime); if (deltaTime < holdTimeThreshold) { kineticPanSpeed += entry.first; entries_considered++; } } if (entries_considered > 0) kineticPanSpeed /= entries_considered; lastMoveTime = currentTime; // When releasing the mouse button/finger while moving, // start the kinetic panning timer kineticTimer.start(); panDecellerate = true; } event->accept(); } void GeoMap::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * event) { setFocus(); animatedPanTo(screenPositionToCoordinate(event->pos())); event->accept(); } // ... void GeoMap::kineticTimerEvent() { QTime currentTime = QTime::currentTime(); int deltaTime = lastMoveTime.msecsTo(currentTime); lastMoveTime = currentTime; if (panDecellerate) kineticPanSpeed *= qPow(qreal(0.5), qreal(deltaTime / kineticPanningHalflife)); QPointF scaledSpeed = kineticPanSpeed * deltaTime; if (kineticPanSpeed.manhattanLength() < kineticPanSpeedThreshold) { // Kinetic panning is almost halted -> stop it. kineticTimer.stop(); return; } panFloatWrapper(scaledSpeed); } // Wraps the pan(int, int) method to achieve floating point accuracy, // which is needed to scroll smoothly. void GeoMap::panFloatWrapper(const QPointF & delta) { // Add to previously stored panning distance remainingPan += delta; // Convert to integers QPoint move = remainingPan.toPoint(); // Commit mouse movement pan(move.x(), move.y()); // Store committed mouse movement remainingPan -= move; }
ããŒããŒãåŠçã®å®è£
ãçç¥ããŸããã ãããžã§ã¯ãå
šäœãããŠã³ããŒãããããšã§ãããŒããŒãåŠçã®å®è£
ãç解ã§ããŸãã æ
£æ§éåã®å®è£
ã¯ãåªããããã¥ã¡ã³ããŒã·ã§ã³ãšåªããäŸã«å¯Ÿããéçºè
ã®ãããã§ã ãã®äŸããå®å
šã«ã¯ã»ã©ã»ã©ã§ã¯ãããŸããã
ã¹ããŒã¿ã¹ããŒã®ã¢ã€ãã
次ã«ãã¹ããŒã¿ã¹è¡ã«ããŸããŸãªããã¹ãæ å ±ã衚瀺ããããã®èŠçŽ ãèŠãŠã¿ãŸãããã
ããã¹ãã衚瀺ãããšãèŠçŽ ã¯æåã«ã¹ã ãŒãºã«è¡šç€ºãããèšå®ãããæéã ãé ããŠåŸã ã«é衚瀺ã«ãªããŸãã ããã§ã¯ãçºè¡šããå§ããŸãããã
// An animated status bar item that appears at the bottom // of the map class StatusBarItem : public QObject, public QGraphicsRectItem { Q_OBJECT Q_PROPERTY(int offset READ offset WRITE setOffset) public: explicit StatusBarItem(); ~StatusBarItem(); int offset() const; void setRect(qreal x, qreal y, qreal w, qreal h); public slots: void setText(QString text); void showText(QString text, quint32 timeout=3000); void show(); void hide(); void setOffset(int offset); private: int m_offset; QGraphicsSimpleTextItem *m_textItem; };
ãŸããèŠçŽ èªäœã¯QGraphicsSimpleTextItemãå«ãé·æ¹åœ¢ã§ãããåçŽã«ãããå¶åŸ¡ããŸãã ãã®ã¯ã©ã¹ã®å®è£
ãèŠãŠã¿ãŸãããã
StatusBarItem::StatusBarItem() { m_offset = 0; setPen(QPen(QBrush(), 0)); setBrush(QBrush(QColor(0,0,0,120))); m_textItem = new QGraphicsSimpleTextItem(this); m_textItem->setBrush(QBrush(Qt::white)); setText(""); } StatusBarItem::~StatusBarItem() { } void StatusBarItem::setText(QString text) { m_textItem->setText(text); QRectF rect = m_textItem->boundingRect(); QPointF delta = this->rect().center() - rect.center(); m_textItem->setPos(delta.x(), delta.y()); } int StatusBarItem::offset() const { return m_offset; } void StatusBarItem::setRect(qreal x, qreal y, qreal w, qreal h) { QGraphicsRectItem::setRect(x, y + m_offset, w, h); QFont f; f.setFixedPitch(true); f.setPixelSize(h/1.1); m_textItem->setFont(f); setText(m_textItem->text()); } void StatusBarItem::setOffset(int offset) { this->setY(this->y() - m_offset + offset); m_offset = offset; } void StatusBarItem::showText(QString text, quint32 timeout) { setText(text); show(); QTimer::singleShot(timeout, this, SLOT(hide())); } void StatusBarItem::show() { QPropertyAnimation *anim = new QPropertyAnimation(this, "offset"); anim->setStartValue(0); anim->setEndValue(-1 * rect().height()); anim->setDuration(500); anim->start(QAbstractAnimation::DeleteWhenStopped); } void StatusBarItem::hide() { QPropertyAnimation *anim = new QPropertyAnimation(this, "offset"); anim->setStartValue(m_offset); anim->setEndValue(0); anim->setDuration(500); anim->start(QAbstractAnimation::DeleteWhenStopped); }
ã¢ãã¡ãŒã·ã§ã³ã¯èŠçŽ ã®äœçœ®ãå¶åŸ¡ããã¡ãœããã«å¿ããŠãèŠçŽ ãäžäžã«åãããŸãã Qt ã®ã¢ãããŒã¯ãã³ãŒãã¬ã¹ãã§ãã ããã«äœæããŸãããå®å
šã«æ©èœããŸãã
ã¹ã±ãŒã«èŠçŽ
ããã§ãã¹ã±ãŒãªã³ã°ã®ããã®ãã¿ã³ã®å®è£ ãæ€èšãããã£ãã®ã§ãããæåŸã«æ°ãå€ããïŒçµæã®èšäºã®ããªã¥ãŒã ãèŠãŠïŒããã®æäœã®åºæ¬åçã®ã¿ã説æããŸããã ãããã£ãŠãããã¯éåžžã®QGraphicsRectItemã§ãããããã«ã¯+ãš-ã衚瀺ããããã®2ã€ã®ããã¹ãèŠçŽ ãããã³èŠèŠçãªåé¢ã®ããã®QGraphicsLineItemãå«ãŸããŸãã èŠçŽ ã¯ãŠãŒã¶ãŒã®ã¢ã¯ã·ã§ã³ã«å¿çããæŒããããšããããã®ã¹ã±ãŒã«ãæ¡å€§ãŸãã¯çž®å°ããŸãã
// // , 0 m_geoMap->setZoomLevel(m_geoMap->zoomLevel() + zoomLevel(event->pos()));
ååãšããŠãèŠçŽ ã¯QGraphicsItemããã®åäžã®ç¶æ¿ã§å®è£ ã§ããå¿ èŠãªæ å ±ãæç»ããã ãã§ããããããŸããŸãªã°ã©ãã£ãã¯èŠçŽ ã®æäœã¯ããèŠèŠçã ãšæããŸããã 誰ã§ããã®ã¯ã©ã¹ãå€æŽã§ããŸãããã®åŸãå°ãã ãã¡ã¢ãªãæ¶è²»ããŸãã
ãã³ããšã³ã
QGraphicsViewãã¬ã³ããªã³ã°ã«OpenGL ã䜿çšããã«ã¯ã次ã®ããã«QGLWidgetãèšå®ããã ãã§ãã
#ifndef QT_NO_OPENGL setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); viewport()->setMouseTracking(true); setRenderHint(QPainter::HighQualityAntialiasing, true); #endif
QGLWidgetã¯éšåçãªç»é¢æŽæ°ããµããŒãããŠããªãããã QGraphicsViewã® ãã©ã°ãèšå®ããŸãã
graphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
ãŸããã·ãŒã³å
ã«ã¢ãã¡ãŒã·ã§ã³åãŸãã¯ç§»åããèŠçŽ ãå€æ°ããå Žåã¯ãããã©ãŒãã³ã¹ãåäžãããããã«ãèŠçŽ ã®ã€ã³ããã¯ã¹ä»ããç¡å¹ã«ã§ããŸãã
graphicsScene->setItemIndexMethod(QGraphicsScene::NoIndex);
ã€ã³ããã¯ã¹ã¯éçãªã·ãŒã³èŠçŽ ã«æé©ã§ã; itemsïŒïŒãitemAtïŒïŒãªã©ã®é¢æ°ã§ã·ãŒã³èŠçŽ ã®æ€çŽ¢ã匷åããŸãã QGraphicsViewã®ãã©ã°ãæé©åããããšãæ€èšã§ããŸãã
ãããã«
ãã®èšäºã¯å€§èŠæš¡ã§ããããšãå€æããç¡éã«æ¡åŒµã§ããããã«æããŸãã ãªããžã§ã¯ãã®æ€çŽ¢ ãã«ãŒãã®ã¬ã€ã¢ãŠããããã³Landmark APIã®æäœã®ããã®APIã¯èæ ®ããŸããã§ããïŒèå³ãããå Žåã¯ãäŸ1ããã³2ãåç §ããŠãã ããïŒã ãã®èšäºã§ã¯ã QtLocation APIã䜿çšããéã®äž»èŠãªãã€ã³ãã§ããGraphics View Frameworkã«ç²Ÿéãã Animation Frameworkã®æäœæ¹æ³ãåŠã³ããããã®æ £æ§éåã®å®è£ ããããã管çããããã¹ãæ å ±ã衚瀺ããããã®ããŸããŸãªèŠçŽ ã調ã¹ãŸããã äžè¬ã«ãããã¯æ¬æ Œçãªããã²ãŒã¿ãŒã«æ¡åŒµã§ããå°å³ã衚瀺ããããã®è¯ãã³ã³ããŒãã³ãã§ããããšãå€æããŸããã ã¢ããªã±ãŒã·ã§ã³ãå®éã«è©Šãã«ã¯ã Qt SDKãã€ã³ã¹ããŒã«ããQtãšãã¥ã¬ãŒã¿ãŒã®ãããžã§ã¯ããã³ããŒããå¿ èŠããããŸãã æåŸã«ãããã€ãã®äŸ¿å©ãªãªã³ã¯ã
åç §è³æ
- Qtãããª
- ã·ãŒã³ã°ã©ãïŒQtã®ã°ã©ãã£ãã¯ã¹ãžã®ç°ãªãã¢ãããŒã
- ããã©ãŒãã³ã¹ïŒã°ã©ãã£ãã¯ã¹ãæ£ããæ¹æ³ã§å®è¡ãã
- Qt GraphicsViewã®è©³çŽ°
- ãã¬ãŒãã³ã°è³æ-ã°ã©ãã£ãã¯ã¹ãã¥ãŒ
- ã®ããªãŠã¹ã®ãããžã§ã¯ãå šäœ
PSèšäºãžã®ã³ã¡ã³ããæè¿ããŸããããã¯ãç§ã®ãããªçµéšã®æµ ãèè ã«ãšã£ãŠéåžžã«åœ¹ç«ã¡ãŸãã äºåã«æè¬ããŸãã