https://github.com/douzujun/MyMapView
主要算法講解:
1. 計算最短路徑(dijkstra算法)
Step1:
(1)找到最短路徑已經確定的頂點,從它已經確定的頂點,從它除法更新相鄰頂點的最短距離。
(2)此后不需要再關心1中的“最短距離已經確定的頂點”。
(3)在(1)和(2)中提到的“最短距離已經確定的頂點”要求解的關鍵。在最開始時,只有起點的最短距離是確定的。而在尚未使用過的頂點中,距離d[i]最小的頂點就是最短距離已經確定的頂點。這是因為由於不存在負邊,所以d[i]不會在更新中變小。
定義幾個方便算法描述的變量:
int cost[MAX_V][MAX_V]; //cost[u][v]表示表e=(u,v)的權值(不存在這條邊時設為INF)
int d[MAX_V]; //頂點s出發的最短路徑
bool used[MAX_V]; //已經使用的圖
Step2:
(1)如果,我們需要輸出最短路的路徑。注,在求解最短路徑時,滿足d[j] = d[k] + cost[k][j]的頂點k(d[j]是表示從起點開始到j的最短路徑距離,cost[k][j]是表示k到j的距離),就是最短路上的頂點j的前驅結點,因此通過不斷尋找前驅結點就可以恢復最短路。時間復雜度是O(E)。
(2)如果,我們用prev[j]來記錄最短路上的頂點j的前驅,那么就可以在O(|V|)時間內完成最短路的恢復。在d[j]=d[k]+cost[k][j]更新時,修改prev[j]=k, 這樣就可以求得prev數組。在計算從起點s出發到j的最短路時,通過prev[j]就可以知道頂點j的前驅,因此不斷把j替換成prev[j]直到j = s為止即可。代碼如下:
1. 首先要對圖進行初始化,才能正常計算最短路徑
1 MainWindow::DijkstraFindPath::DijkstraFindPath() 2 { 3 mgraph.vexnum = 40; //初始化點數目 4 for (int i = 0; i < mgraph.vexnum; i++) //初始化點編號 5 mgraph.vexs.push_back (i); 6 mgraph.arcnum = 98; //邊數 7 for (int i = 0; i < mgraph.vexnum; i++) { 8 for (int j = 0; j < mgraph.vexnum; j++) { 9 if (i == j) 10 mgraph.arcs[i][j].adj = 0; 11 else 12 mgraph.arcs[i][j].adj = INF; 13 } 14 } 15 }
2. 設置圖的景點之間的權值。
1 void MainWindow::DijkstraFindPath::CreateGraph () 2 { 3 mgraph.arcs[0][1].adj = mgraph.arcs[1][0].adj = 45; //6 - 5 4 mgraph.arcs[0][6].adj = mgraph.arcs[6][0].adj = 165; //6 - 10 5 mgraph.arcs[1][2].adj = mgraph.arcs[2][1].adj = 45; //5 - 4 6 mgraph.arcs[2][3].adj = mgraph.arcs[3][2].adj = 45; //4 - 3 7 mgraph.arcs[3][4].adj = mgraph.arcs[4][3].adj = 45; //3 - 2 8 mgraph.arcs[3][15].adj = mgraph.arcs[15][3].adj = 24; //3 - 22 9 mgraph.arcs[4][5].adj = mgraph.arcs[5][4].adj = 45; //2 - 1 10 mgraph.arcs[13][15].adj = mgraph.arcs[15][13].adj = 85;//23 - 22 11 mgraph.arcs[0][13].adj = mgraph.arcs[13][0].adj = 55; //6 - 23 12 mgraph.arcs[13][2].adj = mgraph.arcs[2][13].adj = 50; //23 - 4 13 mgraph.arcs[5][11].adj = mgraph.arcs[11][5].adj = 65; //1 - 一食堂 14 mgraph.arcs[11][12].adj = mgraph.arcs[12][11].adj = 10;//一食堂-操場 15 mgraph.arcs[11][27].adj = mgraph.arcs[27][11].adj = 85;//一食堂-祁通1 16 mgraph.arcs[27][28].adj = mgraph.arcs[28][27].adj = 85;//祁通1-祁通2(路口) 17 mgraph.arcs[5][29].adj = mgraph.arcs[29][5].adj = 87; //一食堂-岔路口 18 mgraph.arcs[29][11].adj = mgraph.arcs[11][29].adj = 50;//一食堂到岔路(通向7號樓的) 19 mgraph.arcs[29][30].adj = mgraph.arcs[30][29].adj = 32;//岔路-祁通大道 20 mgraph.arcs[30][10].adj = mgraph.arcs[10][30].adj = 90;//祁通大道-圖書館 21 mgraph.arcs[30][28].adj = mgraph.arcs[28][30].adj = 80;//祁通大道-祁通2 22 mgraph.arcs[28][26].adj = mgraph.arcs[26][28].adj = 15;//祁通2-方肇周 23 mgraph.arcs[25][27].adj = mgraph.arcs[27][25].adj = 273;//西大門-祁通1 24 mgraph.arcs[27][28].adj = mgraph.arcs[28][27].adj = 84; //祁通1-祁通2 25 mgraph.arcs[5][12].adj = mgraph.arcs[12][5].adj = 70; //1 - 操場 26 mgraph.arcs[6][7].adj = mgraph.arcs[7][6].adj = 45; //10 - 9 27 mgraph.arcs[7][8].adj = mgraph.arcs[8][7].adj = 45; //9 - 8 28 mgraph.arcs[8][9].adj = mgraph.arcs[9][8].adj = 45; //8 - 7 29 mgraph.arcs[9][10].adj = mgraph.arcs[10][9].adj = 150; //7 - 圖書館 30 mgraph.arcs[6][14].adj = mgraph.arcs[14][6].adj = 140; //10 - 13 31 mgraph.arcs[14][16].adj = mgraph.arcs[16][14].adj = 39;//13 - 12 32 mgraph.arcs[14][17].adj = mgraph.arcs[17][14].adj = 39;//13 - 16 33 mgraph.arcs[16][18].adj = mgraph.arcs[18][16].adj = 39;//12 - 15 34 mgraph.arcs[17][18].adj = mgraph.arcs[18][17].adj = 39;//16 - 15 35 mgraph.arcs[18][19].adj = mgraph.arcs[19][18].adj = 20;//15 - 14 36 mgraph.arcs[17][20].adj = mgraph.arcs[20][17].adj = 137;//16 - 19 37 mgraph.arcs[20][21].adj = mgraph.arcs[21][20].adj = 39; //19 - 18 38 mgraph.arcs[21][22].adj = mgraph.arcs[22][21].adj = 39; //18 - 17 39 mgraph.arcs[19][22].adj = mgraph.arcs[22][19].adj = 130;//14 - 17 40 mgraph.arcs[22][23].adj = mgraph.arcs[23][22].adj = 53; //17 - 二超 41 mgraph.arcs[23][24].adj = mgraph.arcs[24][23].adj = 5; //二超 - 二食堂 42 43 //以下處理細節—這是景點之間的一小段路之間的權值,因為用界面繪制路線,會//出現弧狀的路線,所以需要定額外的坐標 44 mgraph.arcs[30][31].adj = mgraph.arcs[31][30].adj = 30; //祁通大道-祁通大道2 45 mgraph.arcs[31][32].adj = mgraph.arcs[32][31].adj = 10; //祁通大道2-祁通大道3 46 mgraph.arcs[32][10].adj = mgraph.arcs[10][32].adj = 20; //祁通大道3-圖書館 47 mgraph.arcs[10][33].adj = mgraph.arcs[33][10].adj = 80; //圖書館-祁通大道4 48 mgraph.arcs[33][34].adj = mgraph.arcs[34][33].adj = 45; //祁通4-祁通5 49 mgraph.arcs[34][24].adj = mgraph.arcs[24][34].adj = 45; //祁通5-二食堂 50 mgraph.arcs[34][23].adj = mgraph.arcs[23][34].adj = 45; //祁通5-二超 51 mgraph.arcs[33][35].adj = mgraph.arcs[35][33].adj = 30; //祁通4-通向14號樓的小道 52 mgraph.arcs[35][19].adj = mgraph.arcs[19][35].adj = 10; //小道-14號樓 53 mgraph.arcs[35][36].adj = mgraph.arcs[36][35].adj = 10; //小道14-小道15 54 mgraph.arcs[36][18].adj = mgraph.arcs[18][36].adj = 10; //小道15-15 55 mgraph.arcs[36][16].adj = mgraph.arcs[16][36].adj = 5; //小道15-12 56 mgraph.arcs[37][29].adj = mgraph.arcs[29][37].adj = 40; //岔路-岔路2 57 mgraph.arcs[37][9].adj = mgraph.arcs[9][37].adj = 45; //岔路2-7 58 60 }
3. 計算最短路徑,並對輸出路徑進行初始化工作。
1 void MainWindow::DijkstraFindPath::dijkstra (int startPos) 2 { 3 for (int i = 0; i < mgraph.vexnum; i++) d[i] = INF; 4 for (int i = 0; i < mgraph.vexnum; i++) used[i] = false; 5 for (int i = 0; i < mgraph.vexnum; i++) prev[i] = -1; 6 d[startPos] = 0; 7 8 while (true) { 9 int v = -1; 10 for (int u = 0; u < mgraph.vexnum; u++) { 11 if (!used[u] && (v == -1 || d[u] < d[v])) v = u; 12 } 13 14 if (v == -1) break; 15 used[v] = true; 16 17 for (int u = 0; u < mgraph.vexnum; u++) { 18 if (d[u] > d[v] + mgraph.arcs[v][u].adj) { 19 d[u] = d[v] + mgraph.arcs[v][u].adj; 20 prev[u] = v; 21 } 22 } 23 } 24 }
4.存儲起點到終點之間的路徑。
1 QVector<int> MainWindow::DijkstraFindPath::get_Path (int endPos) 2 { 3 QVector<int> path; 4 //保存景點之間的最短路徑上的全部景點 5 for ( ; endPos != -1; endPos = prev[endPos]) { 6 path.push_back (endPos); 7 } 8 //由於路徑是從終點向起點保存的,還需要將路徑逆置。 9 std::reverse(path.begin (), path.end ()); 10 return path; 11 }
全部代碼:
1 首先要對圖進行初始化,才能正常計算最短路徑
1 /** 2 * 主要功能: 3 * 1. 繪制輸入起點,終點最短路徑 4 * 2. 雙擊地點, 查看景點信息 5 * 3. 修改景點圖片 6 * 4. 打開測試地圖,查看地圖坐標,可縮放地圖. 7 **/ 8 #ifndef MAINWINDOW_H 9 #define MAINWINDOW_H 10 11 #include <QMainWindow> 12 #include "mapwidget.h" 13 #include <QToolButton> 14 #include <QGraphicsLineItem> 15 #include <QGraphicsScene> 16 #include <QGraphicsView> 17 #include <QLabel> 18 #include <QComboBox> 19 #include <QTextEdit> 20 #include <QVector> 21 #include <QMouseEvent> 22 #include <QDialog> 23 #include <QPixmap> 24 #include <QGridLayout> 25 #include <QLineEdit> 26 #include <QFileDialog> 27 #include <QHBoxLayout> 28 29 class MainWindow : public QMainWindow 30 { 31 Q_OBJECT 32 public: 33 MainWindow(QWidget *parent = 0); 34 ~MainWindow(); 35 void createToolBar(); 36 void createAction(); 37 void setStart(int X, int Y); 38 void setEnd(int X, int Y); 39 void setNextPos (int index); 40 void initScene(); 41 public slots: 42 void setStartStation(); 43 void setEndStation(); 44 void FindPath(); 45 void Clear(); 46 void Revise(); 47 void callOtherMap(); 48 void ShowDialog(); 49 private: 50 MapWidget *mapWidget; 51 QLabel *startLabel; 52 QLabel *endLabel; 53 QComboBox *startComboBox; 54 QComboBox *endComboBox; 55 QComboBox *reviseComboBox; 56 57 QAction *findPathAction; 58 QAction *clearAction; 59 QAction *reviseAction; 60 QAction *callMap; 61 62 QGraphicsScene *scene; 63 QGraphicsView *view; 64 65 int startX, startY, endX, endY; 66 QVector<int> nextPath; 67 68 /* 69 * 圖的實現,和最短路徑算法聲明 70 */ 71 struct ArcCell{ //弧信息 72 int adj; //對無權圖有1,0表示是否相鄰,對帶權圖,則為權值類型 73 // string info; //該弧的相關信息 74 }; 75 76 77 //內部類 78 static const int MAX_VERTEX_NUM = 50; 79 static const int INF = 999999; 80 81 struct MGraph{ 82 QVector<int> vexs; //頂點集合 83 //臨接矩陣 84 ArcCell arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; 85 int vexnum; //頂點數 86 int arcnum; //邊數 87 // int kind; //圖的類型 88 }; 89 90 class DijkstraFindPath 91 { 92 public: 93 DijkstraFindPath(); 94 MGraph mgraph; 95 void CreateGraph(); 96 97 int prev[MAX_VERTEX_NUM]; //最短路上的前驅頂點 98 int d[MAX_VERTEX_NUM]; //表示邊e = (u,v)的權值(不存在時為INF,不過d[i][i]=0) 99 bool used[MAX_VERTEX_NUM]; //已經使用過的圖 100 void dijkstra(int startPos); //求從起點startPos出發到各個頂點的最短距離 101 QVector<int> get_Path(int endPos);//到頂點endPos的最短路 102 }; 103 104 DijkstraFindPath *dj; 105 106 //鼠標事件 107 protected: 108 void mouseDoubleClickEvent (QMouseEvent *e); 109 private: 110 QPixmap library; //圖書館 111 QPixmap canteen; //餐廳 112 QPixmap jxjBuilding; //計算機樓 113 QPixmap westgate; //西門 114 QPixmap westground; //西操 115 QPixmap twoMarket; //二超 116 QString strPath; //文件路徑 117 QLabel *label; 118 }; 119 120 #endif // MAINWINDOW_H
1 #include "mainwindow.h" 2 #include <qdebug.h> 3 #include <QToolBar> 4 #include <QtAlgorithms> 5 #include <iostream> 6 #include <windows.h> 7 8 MainWindow::MainWindow(QWidget *parent) 9 : QMainWindow(parent) 10 { 11 setWindowTitle ("可愛的豆豆豆 校園導航"); 12 dj = new MainWindow::DijkstraFindPath(); 13 dj->CreateGraph (); 14 15 scene = new QGraphicsScene; 16 scene->setSceneRect (-100, -100, 700, 700); 17 initScene(); 18 19 view = new QGraphicsView; 20 view->setScene (scene); 21 view->setMinimumSize (800, 800); 22 view->show (); 23 setCentralWidget (view); 24 25 createAction (); 26 createToolBar (); //實現一個工具欄 27 setMinimumSize (800, 800); //設置最小尺寸 28 Sleep(2000); 29 } 30 31 MainWindow::DijkstraFindPath::DijkstraFindPath() 32 { 33 mgraph.vexnum = 40; //初始化點數目 34 for (int i = 0; i < mgraph.vexnum; i++) //初始化點編號 35 mgraph.vexs.push_back (i); 36 mgraph.arcnum = 98; //暫定 37 for (int i = 0; i < mgraph.vexnum; i++) { 38 for (int j = 0; j < mgraph.vexnum; j++) { 39 if (i == j) 40 mgraph.arcs[i][j].adj = 0; 41 else 42 mgraph.arcs[i][j].adj = INF; 43 // mgraph.arcs[i][j].info = ""; 44 } 45 } 46 } 47 48 void MainWindow::DijkstraFindPath::CreateGraph () 49 { 50 mgraph.arcs[0][1].adj = mgraph.arcs[1][0].adj = 45; //6 - 5 51 mgraph.arcs[0][6].adj = mgraph.arcs[6][0].adj = 165; //6 - 10 52 mgraph.arcs[1][2].adj = mgraph.arcs[2][1].adj = 45; //5 - 4 53 mgraph.arcs[2][3].adj = mgraph.arcs[3][2].adj = 45; //4 - 3 54 mgraph.arcs[3][4].adj = mgraph.arcs[4][3].adj = 45; //3 - 2 55 mgraph.arcs[3][15].adj = mgraph.arcs[15][3].adj = 24; //3 - 22 56 mgraph.arcs[4][5].adj = mgraph.arcs[5][4].adj = 45; //2 - 1 57 mgraph.arcs[13][15].adj = mgraph.arcs[15][13].adj = 85;//23 - 22 58 mgraph.arcs[0][13].adj = mgraph.arcs[13][0].adj = 55; //6 - 23 59 mgraph.arcs[13][2].adj = mgraph.arcs[2][13].adj = 50; //23 - 4 60 mgraph.arcs[5][11].adj = mgraph.arcs[11][5].adj = 65; //1 - 一食堂 61 mgraph.arcs[11][12].adj = mgraph.arcs[12][11].adj = 10;//一食堂-操場 62 mgraph.arcs[11][27].adj = mgraph.arcs[27][11].adj = 85;//一食堂-祁通1 63 mgraph.arcs[27][28].adj = mgraph.arcs[28][27].adj = 85;//祁通1-祁通2(路口) 64 mgraph.arcs[5][29].adj = mgraph.arcs[29][5].adj = 87; //一食堂-岔路口 65 // mgraph.arcs[29][9].adj = mgraph.arcs[9][29].adj = 80; //岔路-7 66 mgraph.arcs[29][11].adj = mgraph.arcs[11][29].adj = 50;//一食堂到岔路(通向7號樓的) 67 mgraph.arcs[29][30].adj = mgraph.arcs[30][29].adj = 32;//岔路-祁通大道 68 mgraph.arcs[30][10].adj = mgraph.arcs[10][30].adj = 90;//祁通大道-圖書館 69 mgraph.arcs[30][28].adj = mgraph.arcs[28][30].adj = 80;//祁通大道-祁通2 70 mgraph.arcs[28][26].adj = mgraph.arcs[26][28].adj = 15;//祁通2-方肇周 71 mgraph.arcs[25][27].adj = mgraph.arcs[27][25].adj = 273; //西大門-祁通1 72 mgraph.arcs[27][28].adj = mgraph.arcs[28][27].adj = 84; //祁通1-祁通2 73 mgraph.arcs[5][12].adj = mgraph.arcs[12][5].adj = 70; //1 - 操場 74 mgraph.arcs[6][7].adj = mgraph.arcs[7][6].adj = 45; //10 - 9 75 mgraph.arcs[7][8].adj = mgraph.arcs[8][7].adj = 45; //9 - 8 76 mgraph.arcs[8][9].adj = mgraph.arcs[9][8].adj = 45; //8 - 7 77 mgraph.arcs[9][10].adj = mgraph.arcs[10][9].adj = 150; //7 - 圖書館 78 mgraph.arcs[6][14].adj = mgraph.arcs[14][6].adj = 140; //10 - 13 79 mgraph.arcs[14][16].adj = mgraph.arcs[16][14].adj = 39;//13 - 12 80 mgraph.arcs[14][17].adj = mgraph.arcs[17][14].adj = 39;//13 - 16 81 mgraph.arcs[16][18].adj = mgraph.arcs[18][16].adj = 39;//12 - 15 82 mgraph.arcs[17][18].adj = mgraph.arcs[18][17].adj = 39;//16 - 15 83 mgraph.arcs[18][19].adj = mgraph.arcs[19][18].adj = 20;//15 - 14 84 mgraph.arcs[17][20].adj = mgraph.arcs[20][17].adj = 137;//16 - 19 85 mgraph.arcs[20][21].adj = mgraph.arcs[21][20].adj = 39; //19 - 18 86 mgraph.arcs[21][22].adj = mgraph.arcs[22][21].adj = 39; //18 - 17 87 mgraph.arcs[19][22].adj = mgraph.arcs[22][19].adj = 130;//14 - 17 88 mgraph.arcs[22][23].adj = mgraph.arcs[23][22].adj = 53; //17 - 二超 89 mgraph.arcs[23][24].adj = mgraph.arcs[24][23].adj = 5; //二超 - 二食堂 90 // mgraph.arcs[24][10].adj = mgraph.arcs[10][24].adj = 260;//二食堂-圖書館 91 92 //以下處理細節 93 mgraph.arcs[30][31].adj = mgraph.arcs[31][30].adj = 30; //祁通大道-祁通大道2 94 mgraph.arcs[31][32].adj = mgraph.arcs[32][31].adj = 10; //祁通大道2-祁通大道3 95 mgraph.arcs[32][10].adj = mgraph.arcs[10][32].adj = 20; //祁通大道3-圖書館 96 mgraph.arcs[10][33].adj = mgraph.arcs[33][10].adj = 80; //圖書館-祁通大道4 97 mgraph.arcs[33][34].adj = mgraph.arcs[34][33].adj = 45; //祁通4-祁通5 98 mgraph.arcs[34][24].adj = mgraph.arcs[24][34].adj = 45; //祁通5-二食堂 99 mgraph.arcs[34][23].adj = mgraph.arcs[23][34].adj = 45; //祁通5-二超 100 mgraph.arcs[33][35].adj = mgraph.arcs[35][33].adj = 30; //祁通4-通向14號樓的小道 101 mgraph.arcs[35][19].adj = mgraph.arcs[19][35].adj = 10; //小道-14號樓 102 mgraph.arcs[35][36].adj = mgraph.arcs[36][35].adj = 10; //小道14-小道15 103 mgraph.arcs[36][18].adj = mgraph.arcs[18][36].adj = 10; //小道15-15 104 mgraph.arcs[36][16].adj = mgraph.arcs[16][36].adj = 5; //小道15-12 105 mgraph.arcs[37][29].adj = mgraph.arcs[29][37].adj = 40; //岔路-岔路2 106 mgraph.arcs[37][9].adj = mgraph.arcs[9][37].adj = 45; //岔路2-7 107 108 109 } 110 111 void MainWindow::DijkstraFindPath::dijkstra (int startPos) 112 { 113 for (int i = 0; i < mgraph.vexnum; i++) d[i] = INF; 114 for (int i = 0; i < mgraph.vexnum; i++) used[i] = false; 115 for (int i = 0; i < mgraph.vexnum; i++) prev[i] = -1; 116 d[startPos] = 0; 117 118 while (true) { 119 int v = -1; 120 for (int u = 0; u < mgraph.vexnum; u++) { 121 if (!used[u] && (v == -1 || d[u] < d[v])) v = u; 122 } 123 124 if (v == -1) break; 125 used[v] = true; 126 127 for (int u = 0; u < mgraph.vexnum; u++) { 128 if (d[u] > d[v] + mgraph.arcs[v][u].adj) { 129 d[u] = d[v] + mgraph.arcs[v][u].adj; 130 prev[u] = v; 131 } 132 } 133 } 134 } 135 136 QVector<int> MainWindow::DijkstraFindPath::get_Path (int endPos) 137 { 138 QVector<int> path; 139 140 for ( ; endPos != -1; endPos = prev[endPos]) { 141 // std::cout << "EndPos: " << endPos << ", "; 142 path.push_back (endPos); 143 } 144 145 std::reverse(path.begin (), path.end ()); 146 147 return path; 148 } 149 150 void MainWindow::initScene () 151 { 152 QGraphicsPixmapItem *item = 153 scene->addPixmap (QPixmap("NanTong.jpg")); 154 // item->setFlag (QGraphicsItem::ItemIsMovable); 155 item->setPos (-500, -420); 156 } 157 158 MainWindow::~MainWindow() 159 { 160 161 } 162 163 void MainWindow::createAction () 164 { 165 findPathAction = new QAction(QIcon("Search.png"),tr("搜索路徑"), this); 166 findPathAction->setShortcut (tr("Ctrl+F")); 167 findPathAction->setStatusTip (tr("搜索路徑")); 168 connect (findPathAction, SIGNAL(triggered(bool)), this, SLOT(FindPath())); 169 170 clearAction = new QAction(QIcon("Clear.png"), tr("清理路徑"), this); 171 clearAction->setShortcut (tr("Ctrl+W")); 172 clearAction->setStatusTip (tr("清理路徑")); 173 connect (clearAction, SIGNAL(triggered(bool)), this, SLOT(Clear())); 174 175 reviseAction = new QAction(QIcon("revise.png"), tr("修改景點"), this); 176 reviseAction->setShortcut (tr("Ctrl+R")); 177 clearAction->setStatusTip (tr("修改景點")); 178 connect (reviseAction, SIGNAL(triggered(bool)), this, SLOT(Revise())); 179 180 callMap = new QAction(QIcon("map.png"), tr("調用測試地圖"), this); 181 callMap->setShortcut (tr("Ctrl+M")); 182 callMap->setStatusTip (tr("調用測試地圖")); 183 connect (callMap, SIGNAL(triggered(bool)), this, SLOT(callOtherMap())); 184 185 } 186 187 void MainWindow::createToolBar () 188 { 189 QToolBar *toolBar = addToolBar ("Tool"); 190 startLabel = new QLabel(tr("起點: ")); 191 startComboBox = new QComboBox; 192 startComboBox->addItem (tr("公寓6號樓")); //0 193 startComboBox->addItem (tr("公寓5號樓")); //1 194 startComboBox->addItem (tr("公寓4號樓")); //2 195 startComboBox->addItem (tr("公寓3號樓")); //3 196 startComboBox->addItem (tr("公寓2號樓")); //4 197 startComboBox->addItem (tr("公寓1號樓")); //5 198 199 startComboBox->addItem (tr("公寓10號樓")); //6 200 startComboBox->addItem (tr("公寓9號樓")); //7 201 startComboBox->addItem (tr("公寓8號樓")); //8 202 startComboBox->addItem (tr("公寓7號樓")); //9 203 startComboBox->addItem (tr("圖書館")); //10 204 startComboBox->addItem (tr("一食堂")); startComboBox->addItem (tr("西操場")); //11 12 205 startComboBox->addItem (tr("公寓23號樓")); startComboBox->addItem (tr("公寓13號樓")); //13 14 206 startComboBox->addItem (tr("公寓22號樓")); startComboBox->addItem (tr("公寓12號樓")); //15 16 207 startComboBox->addItem (tr("公寓樓16")); startComboBox->addItem (tr("公寓樓15")); //17 18 208 startComboBox->addItem (tr("公寓樓14")); startComboBox->addItem (tr("公寓樓19")); //19 20 209 startComboBox->addItem (tr("公寓樓18")); startComboBox->addItem (tr("公寓樓17")); //21 22 210 startComboBox->addItem (tr("二超")); startComboBox->addItem (tr("二食堂")); //23 24 211 startComboBox->addItem (tr("西大門")); startComboBox->addItem (tr("方肇周教學樓")); //25 26 212 213 endLabel = new QLabel(tr("終點: ")); 214 215 endComboBox = new QComboBox; 216 endComboBox->addItem (tr("公寓6號樓")); 217 endComboBox->addItem (tr("公寓5號樓")); 218 endComboBox->addItem (tr("公寓4號樓")); 219 endComboBox->addItem (tr("公寓3號樓")); 220 endComboBox->addItem (tr("公寓2號樓")); 221 endComboBox->addItem (tr("公寓1號樓")); 222 endComboBox->addItem (tr("公寓10號樓")); 223 endComboBox->addItem (tr("公寓9號樓")); 224 endComboBox->addItem (tr("公寓8號樓")); 225 endComboBox->addItem (tr("公寓7號樓")); 226 endComboBox->addItem (tr("圖書館")); 227 endComboBox->addItem (tr("一食堂")); endComboBox->addItem (tr("西操場")); 228 endComboBox->addItem (tr("公寓23號樓"));endComboBox->addItem (tr("公寓13號樓")); 229 endComboBox->addItem (tr("公寓22號樓"));endComboBox->addItem (tr("公寓12號樓")); 230 endComboBox->addItem (tr("公寓樓16")); endComboBox->addItem (tr("公寓樓15")); 231 endComboBox->addItem (tr("公寓樓14")); endComboBox->addItem (tr("公寓樓19")); 232 endComboBox->addItem (tr("公寓樓18")); endComboBox->addItem (tr("公寓樓17")); 233 endComboBox->addItem (tr("二超")); endComboBox->addItem (tr("二食堂")); 234 endComboBox->addItem (tr("西大門")); endComboBox->addItem (tr("方肇周教學樓")); 235 236 connect (startComboBox, SIGNAL(activated(int)), this, SLOT(setStartStation())); 237 connect (endComboBox, SIGNAL(activated(int)), this, SLOT(setEndStation())); 238 239 toolBar->addWidget (startLabel); 240 toolBar->addWidget (startComboBox); 241 toolBar->addSeparator (); 242 toolBar->addWidget (endLabel); 243 toolBar->addWidget (endComboBox); 244 toolBar->addSeparator (); 245 toolBar->addAction(findPathAction); 246 toolBar->addSeparator (); 247 toolBar->addAction(clearAction); 248 toolBar->addSeparator (); 249 toolBar->addAction(reviseAction); 250 toolBar->addSeparator (); 251 toolBar->addAction(callMap); 252 253 } 254 255 void MainWindow::setStart(int X, int Y) { 256 startX = X; startY = Y; 257 // qDebug() << X << ", " << Y; 258 } 259 260 void MainWindow::setEnd (int X, int Y) 261 { 262 endX = X; endY = Y; 263 } 264 265 void MainWindow::setStartStation () 266 { 267 switch (startComboBox->currentIndex ()) { 268 case 0: 269 setStart(-660, -534); break; 270 case 1: 271 setStart (-673, -490); break; 272 case 2: 273 setStart (-682, -446); break; 274 case 3: 275 setStart (-690, -400); break; 276 case 4: 277 setStart (-701, -355); break; 278 case 5: 279 setStart (-711, -310); break; 280 case 6: 281 setStart (-457, -555); break; 282 case 7: 283 setStart (-449, -485); break; 284 case 8: 285 setStart(-446, -432); break; 286 case 9: 287 setStart (-451, -400); break; 288 case 10: 289 setStart (-328, -368); break; 290 case 11: 291 setStart (-720, -247); break; 292 case 12: 293 setStart (-789, -252); break; 294 case 13: 295 setStart (-721, -517); break; 296 case 14: 297 setStart (-271, -540); break; 298 case 15: 299 setStart (-721, -439); break; 300 case 16: 301 setStart (-274, -495); break; 302 case 17: 303 setStart (-180, -552); break; 304 case 18: 305 setStart (-178, -508); break; 306 case 19: 307 setStart (-179, -456); break; 308 case 20: 309 setStart (-41, -552); break; 310 case 21: 311 setStart (-56, -500); break; 312 case 22: 313 setStart (-59, -448); break; 314 case 23: 315 setStart (-83, -393); break; 316 case 24: 317 setStart (-69, -351); break; 318 case 25: 319 setStart (-1070, -92); break; 320 case 26: 321 setStart (-438, -125); break; 322 case 27: 323 setStart (-721, -119); break; 324 case 28: 325 setStart (-550, -122); break; 326 case 29: 327 setStart (-555, -263); break; 328 case 30: 329 setStart (-498, -235); break; 330 case 31: 331 setStart (-439, -306); break; 332 case 32: 333 setStart (-390, -344); break; 334 case 33: 335 setStart (-226, -386); break; 336 case 34: 337 setStart (-144, -370); break; 338 case 35: 339 setStart (-218, -454); break; 340 case 36: 341 setStart (-223, -495); break; 342 case 37: 343 setStart (-513, -379); break; 344 default: 345 break; 346 } 347 } 348 349 void MainWindow::setEndStation () 350 { 351 switch (endComboBox->currentIndex ()) { 352 case 0: 353 setEnd(-660, -534); break; 354 case 1: 355 setEnd (-673, -490); break; 356 case 2: 357 setEnd (-682, -446); break; 358 case 3: 359 setEnd (-690, -400); break; 360 case 4: 361 setEnd (-701, -355); break; 362 case 5: 363 setEnd (-711, -310); break; 364 case 6: 365 setEnd (-457, -555); break; 366 case 7: 367 setEnd (-449, -485); break; 368 case 8: 369 setEnd (-446, -432); break; 370 case 9: 371 setEnd (-451, -400); break; 372 case 10: 373 setEnd (-328, -368); break; 374 case 11: 375 setEnd (-720, -247); break; 376 case 12: 377 setEnd (-789, -252); break; 378 case 13: 379 setEnd (-721, -517); break; 380 case 14: 381 setEnd (-271, -540); break; 382 case 15: 383 setEnd (-721, -439); break; 384 case 16: 385 setEnd (-274, -495); break; 386 case 17: 387 setEnd (-180, -552); break; 388 case 18: 389 setEnd (-178, -508); break; 390 case 19: 391 setEnd (-179, -456); break; 392 case 20: 393 setEnd (-41, -552); break; 394 case 21: 395 setEnd (-56, -500); break; 396 case 22: 397 setEnd (-59, -448); break; 398 case 23: 399 setEnd (-83, -393); break; 400 case 24: 401 setEnd (-69, -351); break; 402 case 25: 403 setEnd (-1070, -92); break; 404 case 26: 405 setEnd (-438, -125); break; 406 case 27: 407 setEnd (-721, -119); break; 408 case 28: 409 setEnd (-550, -122); break; 410 case 29: 411 setEnd (-555, -263); break; 412 case 30: 413 setEnd (-498, -235); break; 414 case 31: 415 setEnd (-439, -306); break; 416 case 32: 417 setEnd (-390, -344); break; 418 case 33: 419 setEnd (-226, -386); break; 420 case 34: 421 setEnd (-144, -370); break; 422 case 35: 423 setEnd (-218, -454); break; 424 case 36: 425 setEnd (-223, -495); break; 426 case 37: 427 setEnd (-513, -379); break; 428 default: 429 break; 430 } 431 } 432 433 void MainWindow::setNextPos (int index) 434 { 435 switch (index) { 436 case 0: 437 setEnd(-660, -534); break; 438 case 1: 439 setEnd (-673, -490); break; 440 case 2: 441 setEnd (-682, -446); break; 442 case 3: 443 setEnd (-690, -400); break; 444 case 4: 445 setEnd (-701, -355); break; 446 case 5: 447 setEnd (-711, -310); break; 448 case 6: 449 setEnd (-457, -555); break; 450 case 7: 451 setEnd (-449, -485); break; 452 case 8: 453 setEnd (-446, -432); break; 454 case 9: 455 setEnd (-451, -400); break; 456 case 10: 457 setEnd (-328, -368); break; 458 case 11: 459 setEnd (-720, -247); break; 460 case 12: 461 setEnd (-789, -252); break; 462 case 13: 463 setEnd (-721, -517); break; 464 case 14: 465 setEnd (-271, -540); break; 466 case 15: 467 setEnd (-721, -439); break; 468 case 16: 469 setEnd (-274, -495); break; 470 case 17: 471 setEnd (-180, -552); break; 472 case 18: 473 setEnd (-178, -508); break; 474 case 19: 475 setEnd (-179, -456); break; 476 case 20: 477 setEnd (-41, -552); break; 478 case 21: 479 setEnd (-56, -500); break; 480 case 22: 481 setEnd (-59, -448); break; 482 case 23: 483 setEnd (-83, -393); break; 484 case 24: 485 setEnd (-69, -351); break; 486 case 25: 487 setEnd (-1070, -92); break; 488 case 26: 489 setEnd (-438, -125); break; 490 case 27: 491 setEnd (-721, -119); break; 492 case 28: 493 setEnd (-550, -122); break; 494 case 29: 495 setEnd (-555, -263); break; 496 case 30: 497 setEnd (-498, -235); break; 498 case 31: 499 setEnd (-439, -306); break; 500 case 32: 501 setEnd (-390, -344); break; 502 case 33: 503 setEnd (-226, -386); break; 504 case 34: 505 setEnd (-144, -370); break; 506 case 35: 507 setEnd (-218, -454); break; 508 case 36: 509 setEnd (-223, -495); break; 510 case 37: 511 setEnd (-513, -379); break; 512 default: 513 break; 514 } 515 } 516 517 void MainWindow::FindPath () 518 { 519 //Demo 在圖片上繪線 在原有基礎上 (+700, +440); 520 QVector<QPoint> v; 521 522 dj->dijkstra (startComboBox->currentIndex ()); 523 //設置下一處的終點 524 nextPath = dj->get_Path (endComboBox->currentIndex ()); 525 526 //准備繪制 527 Clear (); 528 //將路線繪制下來 529 QGraphicsPathItem *item = new QGraphicsPathItem(); 530 531 QPen pen; 532 pen.setWidth (4); 533 pen.setColor (Qt::red); 534 item->setPen (pen); 535 item->setFlag (QGraphicsItem::ItemIsPanel); 536 537 // qDebug() << startX << " " << startY << " " << endX << " " << endY; 538 539 // qDebug() << "Hello World !"; 540 541 542 for (int i = 1; i < nextPath.size (); i++) { 543 qDebug() << nextPath[i] << " , "; 544 } 545 scene->addItem (item); 546 547 QPainterPath pa; //path 548 549 pa.moveTo (startX + 700, startY + 440); 550 551 //將路徑用坐標存入到路徑 552 for (int i = 1; i < nextPath.size() ; i++) { 553 setNextPos (nextPath[i]); 554 pa.lineTo (endX + 700, endY + 440); 555 } 556 item->setPath (pa); 557 558 } 559 560 void MainWindow::Clear () 561 { 562 QList<QGraphicsItem*> listItem = scene->items (); 563 while (!listItem.empty ()) 564 { 565 scene->removeItem (listItem.at (0)); 566 listItem.removeAt (0); 567 } 568 QGraphicsPixmapItem *item = 569 scene->addPixmap (QPixmap("NanTong.jpg")); 570 // item->setFlag (QGraphicsItem::ItemIsMovable); 571 item->setPos (-500, -420); 572 } 573 574 void MainWindow::Revise () 575 { 576 QDialog *reviseDlg = new QDialog; 577 QLabel *reviseLabel = new QLabel(tr("修改圖片路徑:")); 578 QLineEdit *revison = new QLineEdit(tr("\\image\\library.png")); 579 QPushButton *SureBtn = new QPushButton(tr("確定")); 580 QPushButton *CancelBtn = new QPushButton(tr("取消")); 581 582 revison->setEnabled (false); 583 584 reviseComboBox = new QComboBox; 585 reviseComboBox->addItem (tr("圖書館")); 586 reviseComboBox->addItem (tr("食堂")); 587 reviseComboBox->addItem (tr("西操")); 588 reviseComboBox->addItem (tr("jsj教學樓")); 589 590 connect(reviseComboBox, SIGNAL(activated(int)), this, SLOT(ShowDialog())); 591 connect (SureBtn, SIGNAL(clicked(bool)), reviseDlg, SLOT(close())); 592 connect (CancelBtn, SIGNAL(clicked(bool)), reviseDlg, SLOT(close ())); 593 594 revison->setText (strPath); 595 596 QGridLayout *mainlayout = new QGridLayout(reviseDlg); 597 mainlayout->addWidget (reviseLabel, 0, 0); mainlayout->addWidget (revison, 0, 1); 598 mainlayout->addWidget (reviseComboBox, 0 , 2); 599 mainlayout->addWidget (SureBtn, 1, 1, 1, 1); mainlayout->addWidget (CancelBtn, 1, 2, 1, 1); 600 601 602 reviseDlg->setWindowTitle (tr("修改景點信息")); 603 reviseDlg->show (); 604 } 605 606 void MainWindow::ShowDialog () 607 { 608 strPath = QFileDialog::getOpenFileName (this, "打開", "/", "PNG圖像(*.png)::JPEG圖像(*.jpg)"); 609 switch (reviseComboBox->currentIndex ()) { 610 case 0: 611 library.load (strPath); break; 612 case 1: 613 canteen.load (strPath); break; 614 case 2: 615 westground.load (strPath); break; 616 case 3: 617 jxjBuilding.load (strPath); break; 618 default: 619 break; 620 } 621 } 622 623 //鼠標事件 624 void MainWindow::mouseDoubleClickEvent (QMouseEvent *e) 625 { 626 QDialog *dialog = new QDialog; 627 QGridLayout *layout = new QGridLayout(dialog); 628 label = new QLabel; 629 630 qDebug() << "x : " << e->x () << ", y : " << e->y (); 631 //食堂(1060, 260) 632 if ( (e->x () >= 1060-40 && e->x () <= 1060 + 40) && 633 (e->y () >= 260 - 10 && e->y () <= 260 + 10 )) 634 { 635 strPath = "images//canteen"; 636 canteen.load (strPath); 637 label->setPixmap (canteen); 638 layout->addWidget (label); 639 dialog->setMinimumSize (1193, 274); 640 dialog->setWindowTitle ("二食堂"); 641 dialog->show (); 642 } 643 else if ((e->x () >= 708-50 && e->x () <= 708 + 50) && 644 (e->y () >= 498 - 40 && e->y () <= 498 + 40 ) ) { 645 strPath = "images//computer"; 646 jxjBuilding.load (strPath); 647 label->setPixmap (jxjBuilding); 648 layout->addWidget (label); 649 dialog->setMinimumSize (437, 265); 650 dialog->setWindowTitle ("計算機樓(方肇周教學樓)"); 651 dialog->show (); 652 } 653 else if ((e->x () >= 787-50 && e->x () <= 787 + 50) && 654 (e->y () >= 287 - 50 && e->y () <= 287 + 50 ) ) { 655 strPath = "images//library"; 656 library.load (strPath); 657 label->setPixmap (library); 658 layout->addWidget (label); 659 dialog->setMinimumSize (397, 340); 660 dialog->setWindowTitle ("圖書館"); 661 dialog->show (); 662 } 663 else if ((e->x () >= 64-50 && e->x () <= 64 + 100) && 664 (e->y () >= 516 - 100 && e->y () <= 516 + 100 ) ) { 665 strPath = "images//westgate"; 666 westgate.load (strPath); 667 label->setPixmap (westgate); 668 layout->addWidget (label); 669 dialog->setMinimumSize (1100, 283); 670 dialog->setWindowTitle ("西大門"); 671 dialog->show (); 672 } 673 else if ((e->x () >= 200-200 && e->x () <= 200 + 200) && 674 (e->y () >= 167 - 500 && e->y () <= 167 + 500 ) ) { 675 strPath = "images//westground"; 676 westground.load (strPath); 677 label->setPixmap (westground); 678 layout->addWidget (label); 679 dialog->setMinimumSize (395, 345); 680 dialog->setWindowTitle ("西操"); 681 dialog->show (); 682 } 683 else if ((e->x () >= 1045 - 5 && e->x () <= 1045 + 5) && 684 (e->y () >= 233 - 5 && e->y () <= 233 + 5 ) ) { 685 strPath = "images//twoMarket"; 686 twoMarket.load (strPath); 687 label->setPixmap (twoMarket); 688 layout->addWidget (label); 689 dialog->setMinimumSize (611, 294); 690 dialog->setWindowTitle ("二超"); 691 dialog->show (); 692 } 693 } 694 695 void MainWindow::callOtherMap () 696 { 697 mapWidget = new MapWidget; 698 mapWidget->show (); 699 }
1 #ifndef MAPWIDGET_H 2 #define MAPWIDGET_H 3 4 #include <QGraphicsView> 5 #include <QLabel> 6 #include <QLineEdit> 7 #include <QPushButton> 8 #include <QMouseEvent> 9 10 class MapWidget : public QGraphicsView 11 { 12 Q_OBJECT 13 public: 14 MapWidget(); 15 void readMap(); //讀取地圖信息 16 QPointF mapToMap(QPointF); //用於實現場景坐標系與地圖坐標間的映射.以獲得某點的經緯度 17 18 public slots: 19 void slotZoom(int); //縮放信號 20 protected: 21 //完成地圖的顯示功能 22 void drawBackground (QPainter *painter, const QRectF &rect); 23 24 void mouseMoveEvent (QMouseEvent *event); 25 private: 26 QPixmap map; 27 qreal zoom; 28 QLabel *viewCoord; //視圖目前坐標(以窗口左上為原點) 29 QLabel *sceneCoord; //場景目前坐標(以場景中心為原點) 30 QLabel *mapCoord; //地圖目前坐標 31 32 33 double x1, y1; 34 double x2, y2; 35 36 }; 37 38 #endif // MAPWIDGET_H
1 #include "mapwidget.h" 2 #include <QSlider> //滑動條 3 #include <QGridLayout> 4 #include <QFile> 5 #include <QTextStream> 6 #include <QGraphicsScene> 7 #include <math.h> 8 9 MapWidget::MapWidget() 10 { 11 //讀取地圖信息--用於讀取描述地圖信息的文件(包括地圖名及經緯度等信息) 12 readMap (); 13 zoom = 50; 14 int width = map.width (); 15 int height = map.height (); 16 //新建一個QGraphicsScene對象為主窗口連接一個場景 17 QGraphicsScene *scene = new QGraphicsScene(this); 18 //限定場景的顯示區域為地圖大小 19 scene->setSceneRect (-width/2, -height/2, width, height); 20 setScene (scene); 21 /*** 22 * The background is cached(隱藏,緩存). This affects both custom backgrounds, and 23 * backgrounds based on the backgroundBrush property. When this flag is enabled, 24 * QGraphicsView will allocate one pixmap with the full size of the viewport 25 */ 26 setCacheMode (CacheBackground); 27 /*** 28 * 用於地圖縮放的滑動條 29 * 新建一個QSlider對象作為地圖的縮放控制 30 */ 31 QSlider *slider = new QSlider; 32 //設置滾動條方向-垂直 33 slider->setOrientation (Qt::Vertical); 34 slider->setRange (1, 100); //設置地圖縮放比例值范圍為0~100 35 slider->setTickInterval (10); //顯示刻度間隔為10 36 slider->setValue (0); //設置當前初始值為50 37 // 將縮放控制條的valueChanged()信號與地圖縮放slotZoom()槽函數相關聯 38 connect (slider, SIGNAL(valueChanged(int)), this, SLOT(slotZoom(int))); 39 40 //縮放圖標 41 QLabel *zoominLabel = new QLabel; 42 zoominLabel->setScaledContents (true); 43 zoominLabel->setPixmap (QPixmap("zoomin.png")); 44 QLabel *zoomoutLabel = new QLabel; 45 zoomoutLabel->setScaledContents (true); 46 zoomoutLabel->setPixmap (QPixmap("zoomout.png")); 47 48 //坐標值顯示區 49 QLabel *label1 = new QLabel(tr("GraphicsView:")); 50 viewCoord = new QLabel; 51 QLabel *label2 = new QLabel(tr("GraphicsScene:")); 52 sceneCoord = new QLabel; 53 QLabel *label3 = new QLabel(tr("map:")); 54 mapCoord = new QLabel; 55 56 //坐標顯示區布局 57 QGridLayout *gridLayout = new QGridLayout; 58 gridLayout->addWidget (label1, 0, 0); 59 gridLayout->addWidget (viewCoord, 0, 1); 60 61 gridLayout->addWidget (label2, 1, 0); 62 gridLayout->addWidget (sceneCoord, 1, 1); 63 64 gridLayout->addWidget (label3, 2, 0); 65 gridLayout->addWidget (mapCoord, 2, 1); 66 67 gridLayout->setSizeConstraint (QLayout::SetFixedSize); 68 QFrame *coordFrame = new QFrame; 69 coordFrame->setLayout (gridLayout); 70 71 //縮放控制子布局 72 QVBoxLayout *zoomLayout = new QVBoxLayout; 73 zoomLayout->addWidget (zoominLabel); 74 zoomLayout->addWidget (slider); 75 zoomLayout->addWidget (zoomoutLabel); 76 77 //坐標顯示區布局 78 QVBoxLayout *coordLayout = new QVBoxLayout; 79 coordLayout->addWidget (coordFrame); 80 coordLayout->addStretch (); 81 //主布局 82 QHBoxLayout *mainLayout = new QHBoxLayout; 83 mainLayout->addLayout (zoomLayout); 84 mainLayout->addLayout (coordLayout); 85 mainLayout->addStretch (); //平均分割 86 mainLayout->setMargin (30); //設置對話框(或窗體)的邊距為30 87 mainLayout->setSpacing (10); //設定各個控件之間的間距為10 88 setLayout (mainLayout); //在場景中設置為布局 89 90 setWindowTitle ("Map Widget"); 91 setMinimumSize (600, 400); 92 } 93 94 //讀取地圖信息 95 void MapWidget::readMap () 96 { 97 QString mapName; 98 //新建一個QFile對象,“map.txt"是描述地圖信息的文本文件 99 QFile mapFile("maps.txt"); 100 //以"只讀"的方式打開此文件 101 int ok = mapFile.open (QIODevice::ReadOnly); 102 if (ok) //分別以讀取地圖的名稱和四個經緯度信息 103 { 104 QTextStream ts(&mapFile); 105 if (!ts.atEnd ()) { //沒有到末尾返回false 106 ts >> mapName; //儲存字符串 107 ts >> x1 >> y1 >> x2 >> y2; //儲存地圖左上角和右下角的經緯度 108 } 109 } 110 map.load (mapName); //將地圖讀取至私有標量map中 111 } 112 113 //根據縮放滑動條的當前值,確定縮放的比例,調用scale()函數實現地圖縮放--完成地圖縮放功能slotZoom 114 void MapWidget::slotZoom (int value) 115 { 116 qreal s; //縮放大小 117 if (value > zoom) { //放大 118 s = pow (1.01, (value - zoom)); 119 } 120 else { 121 s = pow(1/1.01, (zoom - value)); 122 } 123 scale(s, s); 124 zoom = value; //當前放大值 125 } 126 127 //drawBackground()--以地圖圖片重繪場景的背景來實現地圖顯示 128 void MapWidget::drawBackground (QPainter *painter, const QRectF &rect) 129 { 130 /*** 131 * The scene rectangle defines the extent of the scene, and in the view's case, 132 * this means the area of the scene that you can navigate using the scroll bars. 133 */ 134 painter->drawPixmap (int(sceneRect ().left ()) + 10, int(sceneRect ().top ()) - 10, map); 135 136 } 137 138 //完成某點在各層坐標中的映射及顯示 139 void MapWidget::mouseMoveEvent (QMouseEvent *event) 140 { 141 //QGraphicesView 坐標 142 QPoint viewPoint = event->pos (); //鼠標事件位置 143 viewCoord->setText (QString::number (viewPoint.x ()) + "," + QString::number (viewPoint.y ())); 144 145 //QGraphiccsScene 坐標 -- 將視圖坐標轉換成場景坐標 146 QPointF scenePoint = mapToScene (viewPoint); 147 sceneCoord->setText (QString::number (scenePoint.x ()) + "," + QString::number (scenePoint.y ())); 148 149 //地圖坐標(經,緯度值) 150 QPointF latLon = mapToMap (scenePoint); 151 mapCoord->setText (QString::number (latLon.x ()) + "," + QString::number (latLon.y ())); 152 153 154 } 155 156 //完成從場景至地圖坐標的轉換mapToMap() 157 QPointF MapWidget::mapToMap (QPointF p) 158 { 159 QPointF latLon; //地圖坐標 160 qreal w = sceneRect ().width (); //場景長度 161 qreal h = sceneRect ().height (); //場景高度 162 qreal lon = y1 - ( (h/2+p.y ()) * abs(y1-y2)/h ); 163 qreal lat = x1 + ( (w/2+p.x ()) * abs(x1-x2)/w ); 164 165 latLon.setX (lat); 166 latLon.setY (lon); 167 return latLon; 168 }
1 #include "mainwindow.h" 2 #include "mapwidget.h" 3 #include <QApplication> 4 #include <QFont> 5 #include <QDebug> 6 #include <QPixmap> 7 #include <QSplashScreen> 8 9 int main(int argc, char *argv[]) 10 { 11 QApplication a(argc, argv); 12 QPixmap pixmap("312"); //創建QPixmap對象,設置啟動圖片 13 QSplashScreen splash(pixmap); //利用QPixmap對象創建一個QSplashScreen對象 14 splash.show (); //顯示此啟動圖片 15 16 a.processEvents (); //使程序在顯示啟動動畫的同時能能響應鼠標等其他事件 17 18 QFont font("ARPL KaitiM GB", 12); 19 font.setBold (true); 20 a.setFont (font); 21 22 qDebug() << "Run............"; 23 MainWindow w; 24 w.show (); 25 26 //表示在主窗體對象初始化完成后,結束啟動畫面 27 splash.finish (&w); 28 29 30 return a.exec(); 31 }
源碼下載: http://pan.baidu.com/s/1boEzMJt
qt新手,如有錯誤,希望大神們指正~