如何實(shí)時(shí)繪制旅客在地圖上的狀態(tài)

這一部分我想詳細(xì)地展開敘述张症,因?yàn)樽约涸趯?shí)現(xiàn)這個(gè)功能上確實(shí)是下了很大的功夫,最后卻幾乎一無所獲鸵贬,導(dǎo)致自己的體會(huì)非常深刻俗他,讓我認(rèn)識(shí)到了自己的才疏學(xué)淺以及眼高手低的毛病,當(dāng)然阔逼,針對(duì)此功能兆衅,我最大的認(rèn)識(shí)就是,一個(gè)你未曾嘗試實(shí)現(xiàn)過的功能嗜浮,決不能輕易地下手編寫代碼羡亩,這不僅是對(duì)軟件的不尊重,更是對(duì)自己精力危融、甚至生命的一種不尊重畏铆,當(dāng)你費(fèi)了很大功夫完成一半的功能時(shí),你發(fā)現(xiàn)下一個(gè)功能根本沒法在現(xiàn)有基礎(chǔ)上添加時(shí)吉殃,你會(huì)崩潰的辞居。
因此,對(duì)一個(gè)新的功能蛋勺,有一個(gè)很好的頂層設(shè)計(jì)瓦灶,以及對(duì)全局的思考是至關(guān)重要的,決不能眼高手低抱完,盲目下手編寫代碼贼陶,到頭來一定是手忙腳亂,發(fā)現(xiàn)自己的垃圾代碼確實(shí)是一無是處巧娱。同時(shí)碉怔,善于參考借鑒別人的思想也不是一件壞事,當(dāng)然了禁添,有自己的思想最好眨层,但大部分的時(shí)間理應(yīng)放在你自己這個(gè)思想的可行性上,而不是無效的代碼編寫上荡!

個(gè)人失敗案例

未經(jīng)過充分的考慮以及判斷趴樱,我盲目的開始了動(dòng)畫效果的代碼編寫,當(dāng)時(shí)的想法是酪捡,我一定要盡快實(shí)現(xiàn)當(dāng)前旅客的動(dòng)畫狀態(tài)顯示功能(因?yàn)楫?dāng)時(shí)還沒有添加多個(gè)旅客叁征,實(shí)現(xiàn)多個(gè)旅客的旅行,即狀態(tài)查詢)逛薇,因此我未經(jīng)思考地開始了一個(gè)旅客的該功能實(shí)現(xiàn)捺疼,我將這部分代碼也放在widget模塊中,因?yàn)槔L圖就是在widget中實(shí)現(xiàn)的永罚。
實(shí)現(xiàn)方法:
1啤呼、查詢旅行方案并點(diǎn)擊確定后卧秘,算法得出旅客的旅行信息;
2官扣、將該信息轉(zhuǎn)化為一行字符串翅敌,傳遞給widget中;
3惕蹄、widget監(jiān)控子窗口中何時(shí)點(diǎn)擊了確定蚯涮,點(diǎn)擊時(shí)進(jìn)入移動(dòng)乘客的函數(shù),并根據(jù)當(dāng)前時(shí)間較之旅客出發(fā)時(shí)間來判斷他現(xiàn)在應(yīng)處于什么狀態(tài)(停留卖陵、運(yùn)動(dòng)遭顶、還是到達(dá)狀態(tài))
4、針對(duì)如何實(shí)現(xiàn)停留泪蔫,我產(chǎn)生了思考棒旗,如何讓該乘客的狀態(tài)保持在當(dāng)前一段時(shí)間(即停留這張圖片繪制在地圖上幾“小時(shí)”),我決定采用sleep的方式撩荣,直接根據(jù)參數(shù)sleep一定時(shí)間嗦哆;
5、針對(duì)如何實(shí)現(xiàn)運(yùn)動(dòng)婿滓,我參考了example中別人移動(dòng)乘客的算法老速,見附1,雖然實(shí)現(xiàn)了高幀率運(yùn)動(dòng)(如60幀)凸主,但是每兩幀之間的時(shí)間又如何停止呢橘券?(不停止的話,函數(shù)直接執(zhí)行完卿吐,即圖像直接繪制完旁舰,根本看不到運(yùn)動(dòng)效果),我又采用了sleep嗡官;
最后效果:完全ok箭窜,非常完美,單個(gè)乘客的運(yùn)動(dòng)效果完全達(dá)到需求衍腥。

而后磺樱,問題接踵而至,要求必須實(shí)現(xiàn)多個(gè)乘客同時(shí)在旅行系統(tǒng)中進(jìn)行查詢婆咸,并同時(shí)保存他們的狀態(tài)竹捉,并可以實(shí)現(xiàn)隨時(shí)切換,我面臨著如何實(shí)現(xiàn)保存旅客當(dāng)前位置尚骄,并根據(jù)該位置在切換回時(shí)再推算出旅客此時(shí)所在的位置并進(jìn)行移動(dòng)块差,事實(shí)上,根據(jù)我先前設(shè)計(jì)的算法,我認(rèn)為這一功能根本無法實(shí)現(xiàn)憨闰。以下是我的LJ代碼(可跳過):
(大致思想就是切換旅客時(shí)状蜗,我判斷當(dāng)前他應(yīng)該是停留狀態(tài)還是運(yùn)動(dòng)狀態(tài),若是停留狀態(tài)鹉动,再停留一段時(shí)間轧坎,進(jìn)入循環(huán)進(jìn)行當(dāng)次運(yùn)動(dòng),最后進(jìn)入主循環(huán)進(jìn)行剩余城市間的停留和運(yùn)動(dòng)训裆;若是運(yùn)動(dòng)狀態(tài),則找出他應(yīng)該從哪兒開始運(yùn)動(dòng)蜀铲,進(jìn)入循環(huán)進(jìn)行當(dāng)次運(yùn)動(dòng)边琉,最后進(jìn)入主循環(huán)進(jìn)行剩余城市間的停留和運(yùn)動(dòng))

//移動(dòng)旅客,在地圖上顯示其位置及當(dāng)前狀態(tài)
void Widget::moveTraveler()
{
    int j = 0,k = 0;
    i = 0;
    qDebug()<<"how many times i come";
    while(paintFlag != 0)
    {
        starttime = QDateTime::currentDateTime();//獲取開始時(shí)間
        qDebug()<<"starttime = "<<starttime;
        if(k == 0)
            map[now_traveler]->begintime = starttime;
//        qDebug()<<begintime;
        GetHowToMove();

        travelerStatus = 1;
        QWidget::repaint();
        sleep(stay_time * 10000);
        //sleep(1000);

        travelerStatus = 2;

        for(int i = 1;i != time*1000/SPEED;i++,j++)
        {
            if(i == 1&&j == 0)
            {
                departuredatetime = QDateTime::currentDateTime();//獲取離開的時(shí)間
                cityarrivaltime = departuredatetime.addSecs(time);//獲取到達(dá)的時(shí)間
                start2Begin = getSplitTime(starttime, departuredatetime);
                start2End = getSplitTime(starttime, cityarrivaltime);
//                qDebug()<<departuredatetime<<cityarrivaltime;
            }
            repaint();
            sleep(SPEED);
            if(increaseRatio >= 1)
                break;
        }
        j = 0;k++;
    }
    travelerStatus = 3;
    repaint();
    travelerStatus = 0;
    paintFlag = 1;
}
void Widget::moveTraveler2()
{
    QDateTime begintimeinthis;
    begintimeinthis = map[now_traveler]->begintime;
    qDebug()<<"begintimeinthis = "<<begintimeinthis;

    int sub = (int)getTimeDifference(begintimeinthis,ctime);
    qDebug()<<sub;
    int wheretobegin = sub/10000;
    int sum = 0;
    for(int i = 0;;i++) {                    ******剪枝掉不需要的字符
        qDebug()<<StrFromTra;
        int timebetween2city = StrFromTra.section("-",1,1).toInt()+StrFromTra.section("-",3,3).toInt();
        qDebug()<<timebetween2city;
       if(timebetween2city * 10000 < sub && timebetween2city != 0)
       {
           qDebug()<<StrFromTra.section("-",1,1).toInt()+StrFromTra.section("-",3,3).toInt();
           sum += StrFromTra.section("-",1,1).toInt()+StrFromTra.section("-",3,3).toInt();
           int num = 0;
           for(int j = 0;j < 4;j++)
               num += StrFromTra.section("-",j,j).length() + 1;
           StrFromTra = StrFromTra.mid(num);

           sub -= timebetween2city * 10000;
       }
       else {
           break;
       }
    }
    begintimeinthis = begintimeinthis.addSecs(sum * 10);
    sub = (int)getTimeDifference(begintimeinthis,ctime);
    wheretobegin = sub/10000;
    qDebug()<<"sub = "<<sub<<"wheretobegin = "<<wheretobegin;

    qDebug()<<"strFromTra = "<<StrFromTra;

    int total = 0;
    for(int i = 1;StrFromTra.section("-",i,i) != nullptr;i += 2)
    {
        total += StrFromTra.section("-",i,i).toInt();
    }
    qDebug()<<"total = "<<total;
    if(wheretobegin >= total)//若返回的時(shí)間大于總時(shí)間
    {
        dest2 = CityToNum(StrFromTra);
        qDebug()<<"dest2 = "<<dest2;
        travelerStatus = 3;
        repaint();
        travelerStatus = 0;
        paintFlag = 0;
    }

    if(wheretobegin < StrFromTra.section("-",1,1).toInt())******若返回的時(shí)間處于停留時(shí)間內(nèi)
    {
        travelerStatus = 1;
        depart2 = CityToNum(StrFromTra.section("-",0,0));
        update();
        sleep(StrFromTra.section("-",1,1).toInt() * 10000 - sub);//停留

        int j = 0;
        travelerStatus = 2;

        for(int i = 1;i != time*1000/SPEED;i++,j++)//運(yùn)動(dòng)
        {
            if(i == 1&&j == 0)
            {
                departuredatetime = QDateTime::currentDateTime();//獲取離開的時(shí)間
                cityarrivaltime = departuredatetime.addSecs(StrFromTra.section("-",3,3).toInt() * 10);//獲取到達(dá)的時(shí)間
                start2Begin = getSplitTime(starttime, departuredatetime);
                start2End = getSplitTime(starttime, cityarrivaltime);
//                qDebug()<<departuredatetime<<cityarrivaltime;
            }
            repaint();
            sleep(SPEED);
            if(increaseRatio >= 1)
                break;
        }
        j = 0;
    }
    else {//若返回的時(shí)間應(yīng)處于運(yùn)動(dòng)狀態(tài)
        depart2 = CityToNum(StrFromTra.section("-",0,0));

        int i = 0;
        double j;
        for(j = 0;j/(time*1000/SPEED) < getTimeDifference(begintimeinthis.addSecs(10 * StrFromTra.section("-",1,1).toInt()),ctime)
            (StrFromTra.section("-",3,3).toDouble() * 10000);j++,i++);******找到應(yīng)該從哪兒開始運(yùn)動(dòng)
        i = (int)j;
        qDebug()<<"i = "<<i;
        travelerStatus = 2;

        for(int j = 0;i != time*1000/SPEED;i++,j++)
        {
            if(j == 0)
            {
                departuredatetime = begintimeinthis.addSecs(StrFromTra.section("-",1,1).toInt() * 10);//獲取離開的時(shí)間
                cityarrivaltime = begintimeinthis.addSecs(StrFromTra.section("-",1,1).toInt() * 10 + StrFromTra.section("-",3,3).toInt() * 10);//獲取到達(dá)的時(shí)間

                start2Begin = getSplitTime(starttime, departuredatetime);
                start2End = getSplitTime(starttime, cityarrivaltime);
//                qDebug()<<departuredatetime<<cityarrivaltime;
            }
            repaint();
            sleep(SPEED);
            if(increaseRatio >= 1)
                break;
        }
        j = 0;
    }
    int num = 0;
    if(StrFromTra.section("-",1,1) != nullptr)
    {
        for(int j = 0;j < 4;j++)
            num += StrFromTra.section("-",j,j).length() + 1;
        StrFromTra = StrFromTra.mid(num);
        qDebug()<<"StrFromTra = "<<StrFromTra;
    }

    GetHowToMove();
    if(paintFlag == 0)
        dest2 = CityToNum(StrFromTra);

    int j = 0;
    while(paintFlag != 0)  ******開始剩余的幾個(gè)城市間正常的停留和運(yùn)動(dòng)
    {
//        starttime = QDateTime::currentDateTime();//獲取開始時(shí)間
//        qDebug()<<starttime;

        travelerStatus = 1;
        QWidget::repaint();
        sleep(stay_time * 10000);
        qDebug()<<"I sleep.";
        //sleep(1000);

        travelerStatus = 2;

        for(int i = 1;i != time*1000/SPEED;i++,j++)
        {
            if(i == 1&&j == 0)
            {
                departuredatetime = QDateTime::currentDateTime();//獲取離開的時(shí)間
                cityarrivaltime = departuredatetime.addSecs(time);//獲取到達(dá)的時(shí)間
                start2Begin = getSplitTime(starttime, departuredatetime);
                start2End = getSplitTime(starttime, cityarrivaltime);
//                qDebug()<<departuredatetime<<cityarrivaltime;
            }
            repaint();
            sleep(SPEED);
            if(increaseRatio >= 1)
                break;
        }
        qDebug()<<"I run.";
        j = 0;

        if(!GetHowToMove())
            break;
        qDebug()<<"i = "<<i;
    }
    travelerStatus = 3;
    paintFlag = 0;
    repaint();
    travelerStatus = 0;
    paintFlag = 1;
}
//獲取當(dāng)前輪次旅客從某出發(fā)地移動(dòng)至相應(yīng)目的地的信息
int Widget::GetHowToMove()
{
    paintFlag = 1;
//    qDebug()<<"StrFromTra = "<<StrFromTra;

    QString depart = StrFromTra .section("-",4*i,4*i);
    QString dest = StrFromTra.section("-",4*i+4,4*i+4);
    if(dest==nullptr)
    {
        i = -1;
        paintFlag = 0;
    }
    stay_time = StrFromTra.section("-",4*i+1,4*i+1).toInt();
    vehicle = StrFromTra.section("-",4*i+2,4*i+2);
    time = StrFromTra.section("-",4*i+3,4*i+3).toInt();
    time = time * 10;
    qDebug()<<depart<<stay_time<<vehicle<<time<<dest;

    depart2 = CityToNum(depart);
    dest2 = CityToNum(dest);

    i++;

    if(dest == nullptr)
        return 0;
    else {
        return 1;
    }
}

當(dāng)正常點(diǎn)擊確定時(shí)记劝,調(diào)用movetraveler()函數(shù)变姨,切換旅客時(shí)調(diào)用movetraveler2()函數(shù),姑且先不提我這個(gè)想法是不是bug很難調(diào)厌丑,想法簡單定欧,但代碼龐大且效率奇低,單是我在寫代碼時(shí)我就感到了深深的無力感怒竿,可是我依然硬著頭皮寫了好多天砍鸠,發(fā)現(xiàn)莫名其妙的bug讓我無所適從,最后發(fā)現(xiàn)問題所在:信號(hào)與槽的機(jī)制耕驰,槽內(nèi)調(diào)用函數(shù)時(shí)還沒有執(zhí)行完(因?yàn)橛衧leep函數(shù))爷辱,就要切換旅客進(jìn)入下一個(gè)函數(shù)(movetraveler2),其內(nèi)也有sleep函數(shù),若打斷函數(shù)1后去執(zhí)行函數(shù)2朦肘,當(dāng)函數(shù)2執(zhí)行完后又會(huì)返回到函數(shù)1繼續(xù)執(zhí)行饭弓,雖然初衷是徹底打斷函數(shù)1,只執(zhí)行函數(shù)2 媒抠,但connect機(jī)制如此弟断,無法改變,網(wǎng)上也沒有相關(guān)資料趴生,因此堅(jiān)持了好多天的思想阀趴,一朝徹底放棄,確實(shí)很不容易苍匆,因?yàn)檫@就像是壯士斷腕舍咖,更何況臨近ddl,害怕自己重頭來過沒法趕完這個(gè)功能锉桑。
就是因?yàn)槲译S意使用sleep函數(shù)以及將調(diào)用其的函數(shù)放在槽內(nèi)排霉,導(dǎo)致了這個(gè)很難解決的問題,最終發(fā)現(xiàn)功能根本無法實(shí)現(xiàn),真的非常痛苦攻柠。前車之鑒球订,希望大家不要像我一樣,對(duì)待一件事情瑰钮,一定實(shí)現(xiàn)做好頂層的設(shè)計(jì)與所有情況的考慮冒滩。

正確實(shí)現(xiàn)的功能:
(首先要考慮的是,不把正常點(diǎn)擊確定以及切換旅客割離開來浪谴,不管是哪種調(diào)用开睡,都只是改變了當(dāng)前顯示在地圖上的旅客的信息而已,這樣的需求下苟耻,問題就鞥呢迎刃而解)
1篇恒、封裝mapwidget類,widget窗口上添加一個(gè)widget控件并提升為mapwidget凶杖,在該控件中實(shí)現(xiàn)所有的重繪操作胁艰,包括地圖繪制。
2智蝠、mapwidget類中腾么,構(gòu)造函數(shù)中打開一個(gè)定時(shí)器,一直不斷地重復(fù)刷新重繪工作杈湾。
3解虱、若當(dāng)前旅客沒有進(jìn)行過查詢操作,將某參數(shù)設(shè)為-1,mapwidget中監(jiān)測(cè)該值,為-1時(shí)不繪制旅客狀態(tài)圖片茎辐;
4、當(dāng)旅客在一次旅行中時(shí)艰匙,將其出發(fā)時(shí)間、到達(dá)時(shí)間等信息存在struct traveler結(jié)構(gòu)體中抹恳,mapwidget隨時(shí)監(jiān)測(cè)员凝,并根據(jù)相應(yīng)的值繪制旅客狀態(tài);
以下為代碼:

//mapwidget.h
#ifndef MAPWIDGET_H
#define MAPWIDGET_H

#include "widget.h"

#include <QWidget>
#include <QTextEdit>
#include <QBrush>
#include <QPalette>
#include <QPixmap>
#include <QPen>
#include <QDebug>
#include <QRectF>
#include <QDateTime>
#include <QPointF>
#include <QMessageBox>
#include <QTimer>
#include <QThread>

class mapwidget : public QWidget
{
public:
    mapwidget(QWidget *);
    void paintEvent(QPaintEvent *);
    QPixmap setPointGraph();//設(shè)置圖標(biāo)
    QPointF setPointPos();//設(shè)置圖標(biāo)位置
    QDateTime getSplitTime(QDateTime former, QDateTime later);//獲取兩時(shí)間點(diǎn)時(shí)間間隔
    QPointF getCityCor(int city);//獲得城市對(duì)應(yīng)坐標(biāo)
    double getTimeDifference(QDateTime shorterDateTime, QDateTime longerDateTime);//獲得兩時(shí)間間隔時(shí)間差
    QPointF getMoveDistance(QDateTime starttime, QDateTime spentTime, QDateTime start2Begin, QDateTime start2End,
                            int from, int to);//獲得坐標(biāo)增量
    int nextCity();//獲得新計(jì)劃的始發(fā)地
    int CityToNum(QString);
    int VehicleToNum(QString);

private slots:
    void update();//刷新畫面
private:
    int state;
    QTimer * paintmstimer;
};

#endif // MAPWIDGET_H





//mapwidget.cpp
#include "mapwidget.h"

#include <QApplication>
#include <QStateMachine>
#include <QPushButton>
#include <QSignalTransition>
#include <QPropertyAnimation>
#include <QPainter>
#include <QState>
#include <QLabel>

//添加新的timer奋献,使得繪圖準(zhǔn)確
mapwidget::mapwidget(QWidget *parent) :
    QWidget(parent),state(-1)
{
    this->setAutoFillBackground(true);

    qDebug()<<"come mapwidget";

    paintmstimer = new QTimer;
    paintmstimer->start(1000/60);
    QObject::connect(paintmstimer, SIGNAL(timeout()), this, SLOT(update()));
}

//繪圖實(shí)踐健霹,繪制旅行過程
void mapwidget::paintEvent(QPaintEvent *)
{
    //設(shè)置一個(gè)畫家 叫painter1
    QPainter painter1(this);

    //繪制地圖map2
    QPixmap pix;
    pix.load(":/map2.png");
    pix = pix.scaled(pix.width()*0.55,pix.height()*0.55);
    painter1.drawPixmap(0,150,pix);
    QPainter painter(this);
    Widget *fatherPtr = (Widget *)parentWidget();
    if (fatherPtr->tra.currenttraveler != -1)
    {
        painter.drawPixmap((setPointPos()), setPointGraph());
    }
}

//根據(jù)當(dāng)前狀態(tài)、交通方式?jīng)Q定圖標(biāo)
QPixmap mapwidget::setPointGraph()
{
    QPixmap pointGraph;
    switch(state)
    {
    case -2://arrived destination
        pointGraph = QPixmap(":/vehicles/arrive.ico");
        break;
    case -1://pause waiting
        pointGraph = QPixmap(":/vehicles/pause.ico");
        break;
    case 0:
        pointGraph = QPixmap(":/vehicles/car.ico");
        break;
    case 1:
        pointGraph = QPixmap(":/vehicles/train.ico");
        break;
    case 2:
        pointGraph = QPixmap(":/vehicles/plane.ico");
        break;
    }

    return pointGraph;
}

//設(shè)置當(dāng)前圖標(biāo)所處位置
QPointF mapwidget::setPointPos()
{
    Widget *fatherPtr = (Widget *)parentWidget();
    static QPointF pointPos;
//    std::vector<Attribute> path = fatherPtr->travelers[fatherPtr->currentTraveler].getPlan();
    QDateTime spenttime = QDateTime::currentDateTime();
    QDateTime starttime = fatherPtr->tra.starttime;
    QDateTime totaltime = fatherPtr->tra.totaltime;
    QString plan = fatherPtr->tra.plan;

    //將字符串Plan剪短為需要的串
    int sub = (int)getTimeDifference(starttime,spenttime);
    int sum = 0;
    for(int i = 0;;i++) {
        int timebetween2city = plan.section("-",1,1).toInt()+plan.section("-",3,3).toInt();
       if(timebetween2city * 10000 < sub && timebetween2city != 0)
       {
//           qDebug()<<plan.section("-",1,1).toInt()+plan.section("-",3,3).toInt();
           sum += plan.section("-",1,1).toInt()+plan.section("-",3,3).toInt();
           int num = 0;
           for(int j = 0;j < 4;j++)
               num += plan.section("-",j,j).length() + 1;
           plan = plan.mid(num);
           sub -= timebetween2city * 10000;
       }
       else {
           break;
       }
    }
//    qDebug()<<"plan = "<<plan;

    //已用時(shí)間不小于總時(shí)間瓶蚂,當(dāng)前位置為目的地
    if(spenttime >= totaltime)
    {
            for(int j = 0;plan.section("-",1,1) != nullptr;j++)
            {
                int num = plan.section("-",0,0).length() + 1;
                plan = plan.mid(num);
            }
//            qDebug()<<"plan = "<<plan;

         pointPos = getCityCor(CityToNum(plan));
         state = -2;
    }
    else
        while(1)
        {
            QDateTime departuredatetime = starttime.addSecs(sum * 10 + plan.section("-",1,1).toInt()* 10);
            QDateTime cityarrivaltime = departuredatetime.addSecs(plan.section("-",3,3).toInt() * 10);
            QDateTime start2Begin = getSplitTime(starttime, departuredatetime);
            QDateTime start2End = getSplitTime(starttime, cityarrivaltime);
            //已用時(shí)間不超過一段路徑發(fā)車時(shí)間糖埋,狀態(tài)為等待
//            qDebug()<<getTimeDifference(starttime,spenttime)<<getTimeDifference(starttime,departuredatetime);
            if (getSplitTime(starttime,spenttime) <= start2Begin)
            {
                pointPos = getCityCor(CityToNum(plan.section("-",0,0)));
                state = -1;
                break;
            }
            //已用時(shí)間不超過一段路徑的到站時(shí)間,狀態(tài)為運(yùn)動(dòng)中
            else if (getSplitTime(starttime,spenttime) <= start2End)
            {
                pointPos = getCityCor(CityToNum(plan.section("-",0,0)));
                pointPos += getMoveDistance(starttime,spenttime, start2Begin, start2End, CityToNum(plan.section("-",0,0)), CityToNum(plan.section("-",4,4)));
                state = VehicleToNum(plan.section("-",2,2));
                if (spenttime == start2End)
                {
                    qDebug() << "Arriving at " << plan.section("-",4,4);
                }
                break;
            }
        }
    return pointPos;
}


//獲得兩時(shí)間點(diǎn)之間的時(shí)間差窃这,判斷當(dāng)前所處的狀態(tài)
QDateTime mapwidget::getSplitTime(QDateTime former, QDateTime later)
{
    int durationMsec = (later.time().msec() -  former.time().msec());
    int durationSec = (later.time().second() - former.time().second() - (int)((durationMsec >= 0)?0:1));
    int durationMin = (later.time().minute() - former.time().minute() - (int)((durationSec >= 0)?0:1));
    int durationHour = (later.time().hour() - former.time().hour() - (int)((durationMin >= 0)?0:1));
    int durationDay = (later.date().day() - former.date().day() - (int)((durationHour >= 0)?0:1) + former.date().daysInMonth())
            % former.date().daysInMonth();
    durationMsec = (durationMsec + 1000) % 1000;
    durationSec = (durationSec + 60) % 60;
    durationMin = (durationMin + 60) % 60;
    durationHour = (durationHour + 24) % 24;

    return QDateTime(QDate(1, 1, durationDay+1), QTime(durationHour, durationMin, durationSec, durationMsec));
}

//獲得兩個(gè)時(shí)間段的時(shí)間差瞳别,用于計(jì)算坐標(biāo)增量
double mapwidget::getTimeDifference(QDateTime former, QDateTime later)
{
    int durationMsec = (later.time().msec() - former.time().msec());
    int durationSec = (later.time().second() - former.time().second() - (int)((durationMsec >= 0)?0:1));
    int durationMin = (later.time().minute() - former.time().minute() - (int)((durationSec >= 0)?0:1));
    int durationHour = (later.time().hour() - former.time().hour() - (int)((durationMin >= 0)?0:1));
    int durationDay = (later.date().day() - former.date().day() - (int)((durationHour >= 0)?0:1) + former.date().daysInMonth())
            % former.date().daysInMonth();
    durationMsec = (durationMsec + 1000) % 1000;
    durationSec = (durationSec + 60) % 60;
    durationMin = (durationMin + 60) % 60;
    durationHour = (durationHour + 24) % 24;

    return (double)(1000 * (durationDay * 86400 + durationHour * 3600 + durationMin * 60 + durationSec) +durationMsec);
}

//計(jì)算坐標(biāo)增量
QPointF mapwidget::getMoveDistance(QDateTime starttime, QDateTime spentTime, QDateTime start2Begin, QDateTime start2End,
                                   int from, int to)
{
//    qDebug()<<start2Begin<<start2End<<spentTime;
    double increaseRatio = getTimeDifference(start2Begin, getSplitTime(starttime,spentTime))/getTimeDifference(start2Begin, start2End);
    double xIncrease = (getCityCor(to) - getCityCor(from)).x() * increaseRatio;
    double yIncrease = (getCityCor(to) - getCityCor(from)).y() * increaseRatio;

    return QPointF(xIncrease, yIncrease);
}

總結(jié)

快速的編碼是我們要掌握的技能要求之一,但快速編寫垃圾代碼的能力一定不是。思考永遠(yuǎn)要放在第一位祟敛,但思考的內(nèi)容也是重點(diǎn)疤坝,對(duì)全局的思考,對(duì)整個(gè)程序馆铁,整個(gè)軟件功能的思考才是重中之重跑揉!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市埠巨,隨后出現(xiàn)的幾起案子历谍,更是在濱河造成了極大的恐慌,老刑警劉巖辣垒,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件望侈,死亡現(xiàn)場離奇詭異,居然都是意外死亡乍构,警方通過查閱死者的電腦和手機(jī)甜无,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門扛点,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哥遮,“玉大人,你說我怎么就攤上這事陵究∶咭” “怎么了?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵铜邮,是天一觀的道長仪召。 經(jīng)常有香客問我,道長松蒜,這世上最難降的妖魔是什么扔茅? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮秸苗,結(jié)果婚禮上召娜,老公的妹妹穿的比我還像新娘。我一直安慰自己惊楼,他們只是感情好玖瘸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著檀咙,像睡著了一般雅倒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上弧可,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天蔑匣,我揣著相機(jī)與錄音,去河邊找鬼。 笑死殖演,一個(gè)胖子當(dāng)著我的面吹牛氧秘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播趴久,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼丸相,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了彼棍?” 一聲冷哼從身側(cè)響起灭忠,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎座硕,沒想到半個(gè)月后弛作,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡华匾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年映琳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜘拉。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡萨西,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出旭旭,到底是詐尸還是另有隱情谎脯,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布持寄,位于F島的核電站源梭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏稍味。R本人自食惡果不足惜废麻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望模庐。 院中可真熱鬧烛愧,春花似錦、人聲如沸赖欣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽顶吮。三九已至社牲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間悴了,已是汗流浹背搏恤。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來泰國打工违寿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人熟空。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓藤巢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親息罗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子掂咒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容