From bc30e5961db2223a316d0fce0b2e3798f33ff1b0 Mon Sep 17 00:00:00 2001 From: topfive Date: Tue, 22 Apr 2025 20:07:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=8D=E7=AB=AF=E4=BB=A3=E7=A0=811.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...系统“软件设计规格说明书.doc | Bin 0 -> 162 bytes Src/command_center/__init__.py | 1 + Src/command_center/main.py | 67 +++++++++ Src/command_center/ui/__init__.py | 1 + .../ui/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 149 bytes .../algorithm_config_view.cpython-312.pyc | Bin 0 -> 5560 bytes .../drone_detail_view.cpython-312.pyc | Bin 0 -> 4413 bytes .../drone_list_view.cpython-312.pyc | Bin 0 -> 3365 bytes .../ui/__pycache__/login_view.cpython-312.pyc | Bin 0 -> 4186 bytes .../ui/__pycache__/main_view.cpython-312.pyc | Bin 0 -> 4471 bytes .../ui/__pycache__/map_view.cpython-312.pyc | Bin 0 -> 3503 bytes .../path_layer_view.cpython-312.pyc | Bin 0 -> 3753 bytes .../path_planning_view.cpython-312.pyc | Bin 0 -> 4870 bytes .../path_simulation_view.cpython-312.pyc | Bin 0 -> 6853 bytes .../status_dashboard.cpython-312.pyc | Bin 0 -> 5594 bytes .../threat_layer_view.cpython-312.pyc | Bin 0 -> 3390 bytes .../ui/algorithm_config_view.py | 103 ++++++++++++++ Src/command_center/ui/drone_detail_view.py | 84 ++++++++++++ Src/command_center/ui/drone_list_view.py | 57 ++++++++ Src/command_center/ui/login_view.py | 69 ++++++++++ Src/command_center/ui/main_view.py | 87 ++++++++++++ Src/command_center/ui/map_view.py | 67 +++++++++ Src/command_center/ui/path_layer_view.py | 63 +++++++++ Src/command_center/ui/path_planning_view.py | 88 ++++++++++++ Src/command_center/ui/path_simulation_view.py | 109 +++++++++++++++ Src/command_center/ui/status_dashboard.py | 128 ++++++++++++++++++ Src/command_center/ui/threat_layer_view.py | 56 ++++++++ ...人机运输物资路径规划系统.txt | 0 28 files changed, 980 insertions(+) create mode 100644 Doc/~$人机后勤输送路径规划系统“软件设计规格说明书.doc create mode 100644 Src/command_center/__init__.py create mode 100644 Src/command_center/main.py create mode 100644 Src/command_center/ui/__init__.py create mode 100644 Src/command_center/ui/__pycache__/__init__.cpython-312.pyc create mode 100644 Src/command_center/ui/__pycache__/algorithm_config_view.cpython-312.pyc create mode 100644 Src/command_center/ui/__pycache__/drone_detail_view.cpython-312.pyc create mode 100644 Src/command_center/ui/__pycache__/drone_list_view.cpython-312.pyc create mode 100644 Src/command_center/ui/__pycache__/login_view.cpython-312.pyc create mode 100644 Src/command_center/ui/__pycache__/main_view.cpython-312.pyc create mode 100644 Src/command_center/ui/__pycache__/map_view.cpython-312.pyc create mode 100644 Src/command_center/ui/__pycache__/path_layer_view.cpython-312.pyc create mode 100644 Src/command_center/ui/__pycache__/path_planning_view.cpython-312.pyc create mode 100644 Src/command_center/ui/__pycache__/path_simulation_view.cpython-312.pyc create mode 100644 Src/command_center/ui/__pycache__/status_dashboard.cpython-312.pyc create mode 100644 Src/command_center/ui/__pycache__/threat_layer_view.cpython-312.pyc create mode 100644 Src/command_center/ui/algorithm_config_view.py create mode 100644 Src/command_center/ui/drone_detail_view.py create mode 100644 Src/command_center/ui/drone_list_view.py create mode 100644 Src/command_center/ui/login_view.py create mode 100644 Src/command_center/ui/main_view.py create mode 100644 Src/command_center/ui/map_view.py create mode 100644 Src/command_center/ui/path_layer_view.py create mode 100644 Src/command_center/ui/path_planning_view.py create mode 100644 Src/command_center/ui/path_simulation_view.py create mode 100644 Src/command_center/ui/status_dashboard.py create mode 100644 Src/command_center/ui/threat_layer_view.py delete mode 100644 Src/基于侦察信息为无人机运输物资路径规划系统.txt diff --git a/Doc/~$人机后勤输送路径规划系统“软件设计规格说明书.doc b/Doc/~$人机后勤输送路径规划系统“软件设计规格说明书.doc new file mode 100644 index 0000000000000000000000000000000000000000..3a1b11eaebd5daf48b7fb142e77d1c7963a9a890 GIT binary patch literal 162 gcmZQIG`BD|V;~W*G8i(LGgvSfGmxy6M4K2G02C4e9RL6T literal 0 HcmV?d00001 diff --git a/Src/command_center/__init__.py b/Src/command_center/__init__.py new file mode 100644 index 00000000..122acb7e --- /dev/null +++ b/Src/command_center/__init__.py @@ -0,0 +1 @@ +# 指挥控制中心包 \ No newline at end of file diff --git a/Src/command_center/main.py b/Src/command_center/main.py new file mode 100644 index 00000000..32baec59 --- /dev/null +++ b/Src/command_center/main.py @@ -0,0 +1,67 @@ +import sys +from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, + QHBoxLayout, QTabWidget, QPushButton, QLabel, + QGroupBox, QComboBox, QSpinBox, QDoubleSpinBox, + QProgressBar, QCheckBox) +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QFont +from ui.login_view import LoginView +from ui.main_view import MainView +from ui.map_view import MapView +from ui.threat_layer_view import ThreatLayerView +from ui.path_layer_view import PathLayerView +from ui.drone_list_view import DroneListView +from ui.drone_detail_view import DroneDetailView +from ui.status_dashboard import StatusDashboard +from ui.path_planning_view import PathPlanningView +from ui.algorithm_config_view import AlgorithmConfigView +from ui.path_simulation_view import PathSimulationView + +class CommandCenterApp(QMainWindow): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 设置窗口标题和大小 + self.setWindowTitle("无人机后勤输送系统 - 指挥控制中心") + self.setMinimumSize(1200, 800) + + # 创建主窗口部件 + central_widget = QWidget() + self.setCentralWidget(central_widget) + + # 创建主布局 + main_layout = QVBoxLayout(central_widget) + + # 创建标签页 + self.tab_widget = QTabWidget() + + # 添加各个功能标签页 + self.tab_widget.addTab(MapView(), "地图视图") + self.tab_widget.addTab(ThreatLayerView(), "威胁层") + self.tab_widget.addTab(PathLayerView(), "路径层") + self.tab_widget.addTab(DroneListView(), "无人机列表") + self.tab_widget.addTab(DroneDetailView(), "无人机详情") + self.tab_widget.addTab(StatusDashboard(), "状态仪表板") + self.tab_widget.addTab(PathPlanningView(), "路径规划") + self.tab_widget.addTab(AlgorithmConfigView(), "算法配置") + self.tab_widget.addTab(PathSimulationView(), "路径模拟") + + main_layout.addWidget(self.tab_widget) + + # 显示登录窗口 + self.show_login() + + def show_login(self): + self.login_view = LoginView() + self.login_view.show() + + # 连接登录成功信号 + # TODO: 实现登录成功后的处理逻辑 + +if __name__ == '__main__': + app = QApplication(sys.argv) + window = CommandCenterApp() + window.show() + sys.exit(app.exec_()) \ No newline at end of file diff --git a/Src/command_center/ui/__init__.py b/Src/command_center/ui/__init__.py new file mode 100644 index 00000000..db1f1c7a --- /dev/null +++ b/Src/command_center/ui/__init__.py @@ -0,0 +1 @@ +# UI组件包 \ No newline at end of file diff --git a/Src/command_center/ui/__pycache__/__init__.cpython-312.pyc b/Src/command_center/ui/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d489b6e556247ccac36458fd5e38eff3f1978646 GIT binary patch literal 149 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 literal 0 HcmV?d00001 diff --git a/Src/command_center/ui/__pycache__/drone_list_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/drone_list_view.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..48140a8a62079ece02bf23b388f18813ba91f3b4 GIT binary patch literal 3365 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 literal 0 HcmV?d00001 diff --git a/Src/command_center/ui/__pycache__/main_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/main_view.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b781628cd75c1ea6256ce1bc7e3768d5c9cca810 GIT binary patch literal 4471 zcmd5AZEO_Bb$0LeZhXG;7sc_}#y(@4=1OoIQK~>w^Iazl2K?m6TYG}vQwg9t27C+Vx?+D5iYd<`-kgYWozY1Nabwvs|eF3>aV`pz1_V# zOoZ}_Icet2ypNrE@6CH}?r(vB4?+9*5qA{(5&9RMSdA+Hs}TSukbne6LNXI!WH!Re zu82!^N8BF&cxH-8yyrSSUi|g zkM2onnv&Fg{fDB1HtT*-Rii^9@Prwi?bo2^`d?9!TFl&l*|UYo>K*{jz*$8UVFVOm z)94LGU{2$ROJGl z!1Uy+Y3SZ(CXi+$$C*)d9yC5vSYgm8N>~=KsSwy;rXbOv@D`y8puh^QnZk(-nu^D1 zoUaU{u)8ny9Uxhnn7ViK=F*2Z^Or8<-?_SS`@Q>Pr)p)KW}1d}ExMOhmyGNERh z*jYWvYPMNzSuV{sqvHajh#E=X9o3TWiIx;<%MYHE1-!ZLOYkkGd0e z*19t$);q8T!Kv#l*cmNJ;F7LH&{?-2;96ta8auTkwDj3;^EYnj z+-?$&O82QNr68f9`(tDIGdGt%n9JXKKSdqi4s*-1)618BWf0w)o6Db_E?UUXezY`k zefjdc5bz8N^II#kx0i3thU*CpBr2KthS1AMXj~xl0_%QNi)tyAmy9gs z1#+5s2;COJl)xL4;<00*0DzKALY&hBM>y+)UYEpcJwY}2^z)Jy%1r?(7j;jaxh(G1nLbLykRn#!&?^X+orm*^)IF? zA9>KamiM-#y^GBo@3e2vHt$Hgb2w;_2QxT0kJ~c1?P}+z-p}i@8^4>w+ZG$zr~0xD zThoCBynY^2ne(_agFB~$`AsinHocU?+wbD)c}&?SJLVfVXBs!>@CyrctuccebGX@n z4g8iIetrS3Gv!PU;e$8#%HS=a|1ajkMU2~ZZ=c2ysF&#{$yR+ShhRTr++l{{BE_@3p)h_6uET~%l zPCV^etZkkg$kw){J=9)cs|F|)KCHhJ+LaCN&fz_GtLxIfXGDWEB^F1oGW8K!*pV0M z5lhtbJgkhgm#b%uXs{IsSD#KhKgb5Vb9m>ork&zY{*>CGIdP<=Tsx)l@MWMO+i3S} zTqWuV#YyTZk4nA&aYtAq#{cli=cT#M2ptOm6o-yP;S~bQb{mBkjKDhYo&-&$WvvKH zlWAESf$x1a#Y`a}K>^MbQLgc&V{j2jEtG3Cjg~d5WMR-S{KBq2vk;h`U75XVRuw5j z>C?0M+25>ue5$z8$X}ZH_n)soUZi!1j^9j)suqXGsq3ersv=Pj|0+UA0@&+yfu-*Z%s|i39H*_g6q_m?ZRyRTS^fz(eez?QSt$SEk(*3s%b3tRD24i2i zO0PaR+^=ox>W8-`{j)$N)DeqPhFy#q1(#7RnKtoTj6DhwNhNUUmDbYURNO4m==QFe zH{95?j$bx4(oJ3g6g`bfi`@qphg F{|^s^>w5qI literal 0 HcmV?d00001 diff --git a/Src/command_center/ui/__pycache__/map_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/map_view.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4813c46ccc58c486da7a5d69039f2c01dce76725 GIT binary patch literal 3503 zcmb6b?{5@EbawB@&Ru&gSPQhJa7`(4ZK*&hQGOU{31|euS%YS6*lc%~_Kw}#I=cs4 zJ(8kLxJC>nXsE%YkdRR92QkJN(ew|{FI;-&noUib=u!BF6ovT7ncdslZF30B68@ZLmA3>uSP)(RWl;?&cA;uvgGyY9c}zbX3Q) zFZ!mSCIriyHPc08aR&y@;h-eIQX*jK3^-1S)F@;JrdP%rPnrKE>IbDpDwr25~#PB`G&Q1#VD> zBOb%2C5I$rK#q$gVmikejJYOb5!&!-l6>3Y(o4+8**01;}a~BgRyLgj7zJ0BxQH! zXz6vf$EA7A1pX{~dl zZRi=a!nUlly0oZxvqQI`v^(1%-eS|8HSM}V_$!u)C%(~p>&xpoNR zW#WDg>+QBpXI)}F?9grKIjncsI?n1?Pk~6q;r&TJ=H2;xx^V5f2`>D6qj2+r2^N0* zZsGb*mcaL)+&gz6Np4QztDA+((|5+F7p~nZoWE6=m>AyH&kH98keW=0n*~)?(av!5 z@h#-HE8MRlQNo0+L#M-ieVl72`%$@j|=A{LAQFN#(NG(oGKA`+7kB$fV@)n6;I-d;I2kWg?R zK&1N{6(-(e_5~w^`Mr8dmU;&zNk^njAyQh575X5Oc%75^l!Ul`Jz-Q0@%o?}@8>ni zg_9i>8+ia*ErN_7$AlA-XfU`tCvcZCYIJpAK$bYS17l^8==dm+95)e&YRm`}K9(S! z$)kbM@r$4zzX+;^RaL>AljF^Yfl+PZSi~j-hxih+N|AUii6omBvf{*h)R8J{B?+a0smmr3c?e!)#^1pK+G>7tUUc<2W;4HsK8%q*q>X&K`c3?|&8!m@3p}BC|yVJ*I^19%k}~J~RV=Vb zF4+jcVLhuav=wWhZFq7!dkN#ib<3PN_h%2$=_J!LMpWL*rgC1KE4g=xmq>s-UK6|` z;m2!`;}lg);+xJHl^pj$l9w%x`T8_36e0;jBoIXW7@^|xR*+RlaC-Kv%v zB2QDR$eM+Z7&WV(S#zyATWRa`s7NXnP@8lh8AGH5m=3J;kzAWwHQ;V5`qvQo66BC* mB-;BPilQFT6t(*iz|&u3Du9OHLE}U39x9X>_#5EG-1mQ;x7$+y literal 0 HcmV?d00001 diff --git a/Src/command_center/ui/__pycache__/path_layer_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/path_layer_view.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c36f3922d3e624e5a05f18aee0e00ced0a4f4b8e GIT binary patch literal 3753 zcmb^!TW=Iq_{{9>Y`fcf1A1o*<+9i=wsNyTBh*ANhP1(8vNle(I|J-Gvs2E@DlH|c zT4ReEF-DR2U^PaU@W7K2qwx>;;@B}mCVe1L3cM-BOMLQtXZP&P))FB)P0#r*=ewTE z_w9G_cpai&?6=VIhA2Wm0m8pf1z38D0_Tv7WI;umkQOvCEoy;uKntdWS|}aT!s)OU zNk;@&BdS=7rlSH9(UV9HOd~m{2p0ooUFo{`3t!Dk1eg#V@eba+oVhs-K-R+vO@(TrZKPy{rI@;t-URet_Bx*!}%2HcQQ z98-vkB`H_PnUds2*j&sdMK@?D>QOf;Nm(^x7?NZ_poyu!cFX-EV?@s@S+hDHCfSj! zu4$QqEM=8~sgRLkZe)xGBdHLL^db!>H8xJ}qdF#5*F>4(#>13ntf9l7Q)mIlXCoGF zvT@559D6%98+)r^iLy{lPJ)!ca?(Vjr5UN_i)Z4rU;>|goHmIhzGaXn(6Q{xN0t#N zDhn4Y+F5p2lA>pP`FD(-*-!pmvVOT7wHNT&6Y}wYu2|W3Ps(iMGCcCrqIo~3$w9u7 z=A-Jlk00{!**ykHA3yBlSN-?#BR+nNTb&f|5Xl34g*S6~n(sSFJ>;$C&|OHa=4-wA zE~J{g)g1Ck3Heq|_2x;@TVb|yx{NuMX1=;dbT>Qr3UAJLdN7B~bsWlfambswZgxsn z(pcRqPezXVr0#UqR?y{>LitUeJ`PRRp8OT|IKP>%_2&G;9?T({oo)_$bB+BK&cZ!t zPkCB7RHJ=`Gjk8xAK^N^xkmd6XX_rc_jy`5ci_{c{ngEuaHw)pC66MdtZ>vvy^XkrbwVC?cVbr?m!_-Xh%|@u+jkApo z-e}>Cb0=(^tWtU{-1|e{5gR{SC2g?qhVM5H*?9O0e$c_~7H+PHb4eRHW}zI_)UEemV6lm_P4_5;$k(Aiyje!g=LARSlnDhIE% z@Y=bcljyY)y*BQ<;-~dli9Q=YT0`4rCAQgkdkt-emDpk9omZ>wX*TYruC=Y3OU<|T zg0UtVj)R+M_u^m(=+n{93m+GlqADG-@%^UfY&_x%)agiB9Vr`cy-JhTFxznUl#SQ_ z5=POugPSef?BGrdcRDy};bf`nQqP4R8}DMqS}fe+;B^*W=in_C-cs6jY2d>^)@a%0~c>CG*b3d&*G{5cvHCr_b0(hhGAMAp9W; c!a?B=1mmx4yoOqD2m6Ki*(ZNPbYfoq4N1rP6aWAK literal 0 HcmV?d00001 diff --git a/Src/command_center/ui/__pycache__/path_planning_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/path_planning_view.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad35ab26546ca72218081e80c8d00a0321f2f9d1 GIT binary patch literal 4870 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 Gs{aGAP8o~< literal 0 HcmV?d00001 diff --git a/Src/command_center/ui/__pycache__/status_dashboard.cpython-312.pyc b/Src/command_center/ui/__pycache__/status_dashboard.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..02dc1706a1299c3046aa21402b2912b755e2793f GIT binary patch literal 5594 zcmeHLTWl2989uX@*|XkV8^^^ryzBKXWtBp(!KN4zm5XrIAj_6pDy>LH!^~jT?8QAZ z+hAj>u1d>Ng@lTzu zHs58asYClgtnekB{+5Nl_%hSka&^v$J^s8W-ST5{fe-io0^?6eBX{ zaojDs&ZD?TbOZI$ZO2*B3)CmFKyeP8W#aw`6!U2f6AG_nk>oOuf=w(ue|hc3bW-Y_`~nnP38ecPyV`3$t|y3aLdc|2d|KoLDXmE4L^g3k z){n!9)_HbL&yYr#WVW^HpgXPgeIS)vfPB7y?&8ozpNd-xxP27|-w0j|UaH>&5vsTr z4>0s=`5REU6#L4o%a~^rD%Xq1+%VKO1mk#eR|!$}`hJT$?{Rp2FWeVZy{aPCRouCK${OfE1v+F+ zRs$WZK-b%7uj8rERI7z3)z+EdJ!_3>FQKj06O8Jxu%)_el*jR9yk!XIm+_P#kmDS- zjWTEk#X_T5dgU8`xV3TXR~tY5)B3^>b;c(PZ{NRj)nxbqvHtG+AK&@q`s=^W(%#6} zM5S!)cW>XneaV>X%|EXHe#sCMYS%g!W?OsX&uf4AaP7n2=#2G+YajpU_WElV)|W2m zjKgE!xqti4#+&bLynZ1|t#j=sKVJLoVkK|m_RltMy=(Jg4TO3CLQP6*5s1Vq5@-6w zL|RM;yaJ)6QOKmz;7=2ov?Xae9q{gYK;%x+h$u{Fxvb1jN?I@_r82O-(F>&|<<$&1V{~II zp)N=Zr1(UdOBw;UNuH4vDP?&h78j=OcSp@V2|HJ@15ap$9DLezw^4 zg4*@M&Ghn_d{;c@Dd5Ozd!*Ptq_z)zaPFg*^6g_e&ua~)JjSdy?-qjNCTEo?b0^U`|DMojz z(cJ~Sr-C=2Mh6Ob_dUF=i2GFBx0KQmO+_45ad;)tU%&%!rtq^%>3qlF3U0d_-u}+Z zE3kfBxY*XOw)KCo^P{eO+Y#7({c1rG@6oy`md(LD%SPK%iOY zaFj^m{+N%@+adJ0gjxa^k)%v0Gf8RUv?M8{lk)1os3#O6DZ*(I1qO`LO|mXY6J1V` z&O!=o`X0T*zG@`NtZ9l~9jLJeMyA(gm|WDbIU0Rtzglf`HJsW2faMer$mAMZue9aZ zyNw-J!a4T-mgdW|`7PZ!@7>0h#X!EXH^;8x`XcU7amV7z1^nDS+G~Z>Z*gk@cj_{| z*Id9+z1ODVHZZ^vPM0)n&4s=|wYvWos%5K?^`yFDIjN1UdhqD1lTuWvo|9Tss-6>~ zQuQ2CMr)tC>e1x8syM0Mf9lL<*Q@gHqv*K`5tX0J5K#g>?Vmmyl{3kN80`@RVSf$W z4#JCxtUMeYoId+FhHB*wJ_(^}IBI-GRAS~UW-Z^?@UUTKVCRP!%AA*VOmtr zp2G)^4(_To^>u%hu@U;{8U~9y&L^`Hc@Da|#gVVkRusr}!_>$QXlvf@>#*mka2F;0 zl#8vX`nX+f1NrRs8g^wxcsuAH1oY+)fP8^rHFaKjF^5<2mLjIMve>6v4)h`_jyypA zXz&s8`$G?!k-x#w)ZnYD`%6=UOSa40m!@X?NAgsrHqgIs=;-cRrbhO_^^zeVj~hi8 zxV3{#Rel?%^X#Lfc4~qCfBxSwDX2;;0&QZ0`R0>DON}S(n|9w3I5Wm9E*;LdTy_!g6m zck$49?Nm>XKF0TB(1IV%5Q)&FLkn1}k!*s{KVJ#eBYlDEhB4@S)$jr14qhZjKu!-K m_W*g|W*Fu(7sCvGhJdW0ZT~>qA9-dOrup*Zr-;`2j{ghhUxJkY literal 0 HcmV?d00001 diff --git a/Src/command_center/ui/__pycache__/threat_layer_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/threat_layer_view.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a5fefa0faea5a1b479b2faaf631ffae66ab9d0a9 GIT binary patch literal 3390 zcmb6b?{5@EbawC8Tzhu~kstkaJ!pk4E!RQ|1_UB4iN%mYZG*|BvbpXq?H#+fIJ>9Z zQIZmBY&ArTQ8Yx;7^Byq5HNswQ=Dj!b ze$LE$@AqJ^3gC}=+=+WrPncV3GjfYL?BTyN}^-5z`F(NimMn}%>+Lxs7Cd`u^##K z;dn+)6Qs{ZyaR{hBZ7#DN7Kq!Pg+&wlo1#hijRmwk$II9JERH{LmBjd$`v#gM!JYB z?ZUwO*ck!DC?3SW~qM0Wq6eI zDFGRfWfQ4{%Cd&foYM)0Hr$FJo-q6@%ZYJCVOfPZ8JYNZAHQe#6q1tyryfeWD}yadYP;>H9sECR7x?kqH&f|$-4Pjv~j>%M@C{rWGwrVzGVcA z^3;{0bTh)0xcpCZjp94|_5X8LKh4Rz9Qvqa@aY|uZMV798jHvB{4A}mwrITD+KJ;) zvfQ!majcu~m~cAQy^i&g{p0ismcC%=wP%YT$8#mF7wz2^^bB0RQyN0FRP@!L3Al(C}b6P@Ju%1WA<4TyM!aFqr|pqRQ< zQU{HYBB;Hxn3ht#SfXmwV!TgAiL9Jb<6@r>$DWvFR55~hX;96G!r+*I3$H)U^Mx{s zNIgO%sTv_nWQz($)Ra*p@VNFk2&;KP6jZ@UB7zF_8F2w=4b#KdSy z!o>%XRAp3~c&}NE3_o5kmVX~7Cb*LVZ}>PlmBK~LsIu)bsvWi%!7@7-7b0)MsFvc1 z6e((?nFx-UEkhAiNTG>DB8XgXMDlEQ{ZM&Lj}{9ou~GRFmy-!_d)>xQq^atMUeL%~ z?w@k!VJ)tAI;_=Ttqxl?*qU3Nhiwj8mj=83=suo@tb@2kgIjL2zLAH6H{lu`Hfpf( zb6yX3XyJ}L?8MS*TP_Eug7aY}7o7|5CVJ}Uo3`fm&o%8KNW=Wb_T2Hgje7|az6ICn zut|eWGj2W7rA4~(u=}Qy)~!Xl^KfSwZI>3=m4`3iD(RQ9Uk%NMFq4B$T)x4)m50a6Jn7WJoq4$Z7VZT?)1ixJ^04{77x;rZtk+<@ z4x2UDtiv`9w&f09Ju-VF5BHiv8#LIU!xjy;=&)Ub?YSX++dggEzC7G-u7@=k*5PIi zZq{K`gVCI-cO1|<4*Usw&{}*xLO_C9?czR_dn90TzR|pu1u4$M7_ZEEJk9K1k oxfcqlpZ8r9MLnh|>Jar9knwMGTmbbC-Cb1h;^-rQC)3LR0AfPI8UO$Q literal 0 HcmV?d00001 diff --git a/Src/command_center/ui/algorithm_config_view.py b/Src/command_center/ui/algorithm_config_view.py new file mode 100644 index 00000000..265299c4 --- /dev/null +++ b/Src/command_center/ui/algorithm_config_view.py @@ -0,0 +1,103 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QGroupBox, QFormLayout, QComboBox, + QSpinBox, QDoubleSpinBox, QCheckBox) +from PyQt5.QtCore import Qt + +class AlgorithmConfigView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建A*算法配置组 + astar_group = QGroupBox("A*算法配置") + astar_layout = QFormLayout() + + self.astar_heuristic = QComboBox() + self.astar_heuristic.addItems(["欧几里得距离", "曼哈顿距离", "对角线距离"]) + + self.astar_weight = QDoubleSpinBox() + self.astar_weight.setRange(0.1, 10.0) + self.astar_weight.setValue(1.0) + self.astar_weight.setSingleStep(0.1) + + astar_layout.addRow("启发函数:", self.astar_heuristic) + astar_layout.addRow("权重:", self.astar_weight) + + astar_group.setLayout(astar_layout) + main_layout.addWidget(astar_group) + + # 创建遗传算法配置组 + ga_group = QGroupBox("遗传算法配置") + ga_layout = QFormLayout() + + self.ga_population = QSpinBox() + self.ga_population.setRange(10, 1000) + self.ga_population.setValue(100) + + self.ga_generations = QSpinBox() + self.ga_generations.setRange(10, 1000) + self.ga_generations.setValue(100) + + self.ga_mutation_rate = QDoubleSpinBox() + self.ga_mutation_rate.setRange(0.01, 1.0) + self.ga_mutation_rate.setValue(0.1) + self.ga_mutation_rate.setSingleStep(0.01) + + ga_layout.addRow("种群大小:", self.ga_population) + ga_layout.addRow("迭代次数:", self.ga_generations) + ga_layout.addRow("变异率:", self.ga_mutation_rate) + + ga_group.setLayout(ga_layout) + main_layout.addWidget(ga_group) + + # 创建RRT算法配置组 + rrt_group = QGroupBox("RRT算法配置") + rrt_layout = QFormLayout() + + self.rrt_step_size = QDoubleSpinBox() + self.rrt_step_size.setRange(0.1, 10.0) + self.rrt_step_size.setValue(1.0) + self.rrt_step_size.setSingleStep(0.1) + + self.rrt_goal_bias = QDoubleSpinBox() + self.rrt_goal_bias.setRange(0.0, 1.0) + self.rrt_goal_bias.setValue(0.1) + self.rrt_goal_bias.setSingleStep(0.01) + + self.rrt_smooth_path = QCheckBox("平滑路径") + self.rrt_smooth_path.setChecked(True) + + rrt_layout.addRow("步长:", self.rrt_step_size) + rrt_layout.addRow("目标偏向:", self.rrt_goal_bias) + rrt_layout.addRow("", self.rrt_smooth_path) + + rrt_group.setLayout(rrt_layout) + main_layout.addWidget(rrt_group) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.save_config_btn = QPushButton("保存配置") + self.reset_config_btn = QPushButton("重置配置") + + button_layout.addWidget(self.save_config_btn) + button_layout.addWidget(self.reset_config_btn) + + main_layout.addLayout(button_layout) + + self.setLayout(main_layout) + + # 连接信号 + self.save_config_btn.clicked.connect(self.save_config) + self.reset_config_btn.clicked.connect(self.reset_config) + + def save_config(self): + # TODO: 实现保存配置功能 + pass + + def reset_config(self): + # TODO: 实现重置配置功能 + pass \ No newline at end of file diff --git a/Src/command_center/ui/drone_detail_view.py b/Src/command_center/ui/drone_detail_view.py new file mode 100644 index 00000000..cc0d6731 --- /dev/null +++ b/Src/command_center/ui/drone_detail_view.py @@ -0,0 +1,84 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QGroupBox, QFormLayout) +from PyQt5.QtCore import Qt + +class DroneDetailView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建基本信息组 + basic_info_group = QGroupBox("基本信息") + basic_layout = QFormLayout() + + self.id_label = QLabel("") + self.model_label = QLabel("") + self.status_label = QLabel("") + self.battery_label = QLabel("") + + basic_layout.addRow("ID:", self.id_label) + basic_layout.addRow("型号:", self.model_label) + basic_layout.addRow("状态:", self.status_label) + basic_layout.addRow("电量:", self.battery_label) + + basic_info_group.setLayout(basic_layout) + main_layout.addWidget(basic_info_group) + + # 创建位置信息组 + position_group = QGroupBox("位置信息") + position_layout = QFormLayout() + + self.latitude_label = QLabel("") + self.longitude_label = QLabel("") + self.altitude_label = QLabel("") + self.speed_label = QLabel("") + + position_layout.addRow("纬度:", self.latitude_label) + position_layout.addRow("经度:", self.longitude_label) + position_layout.addRow("高度:", self.altitude_label) + position_layout.addRow("速度:", self.speed_label) + + position_group.setLayout(position_layout) + main_layout.addWidget(position_group) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.takeoff_btn = QPushButton("起飞") + self.land_btn = QPushButton("降落") + self.return_btn = QPushButton("返航") + self.emergency_btn = QPushButton("紧急停止") + + button_layout.addWidget(self.takeoff_btn) + button_layout.addWidget(self.land_btn) + button_layout.addWidget(self.return_btn) + button_layout.addWidget(self.emergency_btn) + + main_layout.addLayout(button_layout) + + self.setLayout(main_layout) + + # 连接信号 + self.takeoff_btn.clicked.connect(self.takeoff) + self.land_btn.clicked.connect(self.land) + self.return_btn.clicked.connect(self.return_home) + self.emergency_btn.clicked.connect(self.emergency_stop) + + def takeoff(self): + # TODO: 实现起飞功能 + pass + + def land(self): + # TODO: 实现降落功能 + pass + + def return_home(self): + # TODO: 实现返航功能 + pass + + def emergency_stop(self): + # TODO: 实现紧急停止功能 + pass \ No newline at end of file diff --git a/Src/command_center/ui/drone_list_view.py b/Src/command_center/ui/drone_list_view.py new file mode 100644 index 00000000..5ce4fa4d --- /dev/null +++ b/Src/command_center/ui/drone_list_view.py @@ -0,0 +1,57 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QTableWidget, QTableWidgetItem) +from PyQt5.QtCore import Qt + +class DroneListView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建无人机列表 + self.drone_table = QTableWidget() + self.drone_table.setColumnCount(5) + self.drone_table.setHorizontalHeaderLabels(["ID", "型号", "状态", "位置", "电量"]) + self.drone_table.setStyleSheet("QTableWidget { border: 1px solid #ccc; }") + main_layout.addWidget(self.drone_table) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.add_drone_btn = QPushButton("添加无人机") + self.edit_drone_btn = QPushButton("编辑信息") + self.delete_drone_btn = QPushButton("删除无人机") + self.refresh_btn = QPushButton("刷新状态") + + button_layout.addWidget(self.add_drone_btn) + button_layout.addWidget(self.edit_drone_btn) + button_layout.addWidget(self.delete_drone_btn) + button_layout.addWidget(self.refresh_btn) + + main_layout.addLayout(button_layout) + + self.setLayout(main_layout) + + # 连接信号 + self.add_drone_btn.clicked.connect(self.add_drone) + self.edit_drone_btn.clicked.connect(self.edit_drone) + self.delete_drone_btn.clicked.connect(self.delete_drone) + self.refresh_btn.clicked.connect(self.refresh_status) + + def add_drone(self): + # TODO: 实现添加无人机功能 + pass + + def edit_drone(self): + # TODO: 实现编辑无人机信息功能 + pass + + def delete_drone(self): + # TODO: 实现删除无人机功能 + pass + + def refresh_status(self): + # TODO: 实现刷新状态功能 + pass \ No newline at end of file diff --git a/Src/command_center/ui/login_view.py b/Src/command_center/ui/login_view.py new file mode 100644 index 00000000..b256be98 --- /dev/null +++ b/Src/command_center/ui/login_view.py @@ -0,0 +1,69 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QLineEdit, QPushButton, QMessageBox) +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QFont + +class LoginView(QWidget): + def __init__(self): + super().__init__() + self.setWindowTitle("无人机后勤输送系统 - 登录") + self.setFixedSize(400, 300) + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + main_layout.setAlignment(Qt.AlignCenter) + main_layout.setSpacing(20) + + # 标题 + title_label = QLabel("无人机后勤输送系统") + title_label.setFont(QFont('Arial', 16, QFont.Bold)) + title_label.setAlignment(Qt.AlignCenter) + main_layout.addWidget(title_label) + + # 用户名输入 + username_layout = QHBoxLayout() + username_label = QLabel("用户名:") + self.username_input = QLineEdit() + self.username_input.setPlaceholderText("请输入用户名") + username_layout.addWidget(username_label) + username_layout.addWidget(self.username_input) + main_layout.addLayout(username_layout) + + # 密码输入 + password_layout = QHBoxLayout() + password_label = QLabel("密码:") + self.password_input = QLineEdit() + self.password_input.setPlaceholderText("请输入密码") + self.password_input.setEchoMode(QLineEdit.Password) + password_layout.addWidget(password_label) + password_layout.addWidget(self.password_input) + main_layout.addLayout(password_layout) + + # 按钮区域 + button_layout = QHBoxLayout() + login_button = QPushButton("登录") + register_button = QPushButton("注册") + login_button.clicked.connect(self.handle_login) + register_button.clicked.connect(self.handle_register) + button_layout.addWidget(login_button) + button_layout.addWidget(register_button) + main_layout.addLayout(button_layout) + + self.setLayout(main_layout) + + def handle_login(self): + username = self.username_input.text() + password = self.password_input.text() + + if not username or not password: + QMessageBox.warning(self, "错误", "请输入用户名和密码") + return + + # TODO: 实现实际的登录逻辑 + print(f"尝试登录 - 用户名: {username}, 密码: {password}") + + def handle_register(self): + # TODO: 实现注册功能 + QMessageBox.information(self, "提示", "注册功能待实现") \ No newline at end of file diff --git a/Src/command_center/ui/main_view.py b/Src/command_center/ui/main_view.py new file mode 100644 index 00000000..36ffd5f0 --- /dev/null +++ b/Src/command_center/ui/main_view.py @@ -0,0 +1,87 @@ +from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, + QLabel, QPushButton, QTabWidget, QMessageBox) +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QFont + +class MainView(QMainWindow): + def __init__(self): + super().__init__() + self.setWindowTitle("无人机后勤输送系统 - 指挥控制中心") + self.setMinimumSize(800, 600) + self.init_ui() + + def init_ui(self): + # 创建主窗口部件 + central_widget = QWidget() + self.setCentralWidget(central_widget) + main_layout = QVBoxLayout(central_widget) + + # 顶部工具栏 + toolbar = QHBoxLayout() + self.status_label = QLabel("系统状态: 正常") + self.status_label.setFont(QFont('Arial', 10)) + logout_button = QPushButton("退出登录") + logout_button.clicked.connect(self.handle_logout) + + toolbar.addWidget(self.status_label) + toolbar.addStretch() + toolbar.addWidget(logout_button) + main_layout.addLayout(toolbar) + + # 主内容区域 + self.tab_widget = QTabWidget() + + # 创建各个功能标签页 + self.tab_widget.addTab(self.create_drone_management_tab(), "无人机管理") + self.tab_widget.addTab(self.create_task_management_tab(), "任务管理") + self.tab_widget.addTab(self.create_monitoring_tab(), "实时监控") + self.tab_widget.addTab(self.create_system_settings_tab(), "系统设置") + + main_layout.addWidget(self.tab_widget) + + def create_drone_management_tab(self): + tab = QWidget() + layout = QVBoxLayout(tab) + + # 添加无人机管理相关的控件 + layout.addWidget(QLabel("无人机管理功能待实现")) + + return tab + + def create_task_management_tab(self): + tab = QWidget() + layout = QVBoxLayout(tab) + + # 添加任务管理相关的控件 + layout.addWidget(QLabel("任务管理功能待实现")) + + return tab + + def create_monitoring_tab(self): + tab = QWidget() + layout = QVBoxLayout(tab) + + # 添加实时监控相关的控件 + layout.addWidget(QLabel("实时监控功能待实现")) + + return tab + + def create_system_settings_tab(self): + tab = QWidget() + layout = QVBoxLayout(tab) + + # 添加系统设置相关的控件 + layout.addWidget(QLabel("系统设置功能待实现")) + + return tab + + def handle_logout(self): + reply = QMessageBox.question(self, '确认退出', + '确定要退出登录吗?', + QMessageBox.Yes | QMessageBox.No, + QMessageBox.No) + + if reply == QMessageBox.Yes: + # TODO: 实现实际的登出逻辑 + self.close() + # 这里应该触发登录窗口的显示 \ No newline at end of file diff --git a/Src/command_center/ui/map_view.py b/Src/command_center/ui/map_view.py new file mode 100644 index 00000000..20110f16 --- /dev/null +++ b/Src/command_center/ui/map_view.py @@ -0,0 +1,67 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QToolBar, QAction) +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QIcon + +class MapView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建工具栏 + toolbar = QToolBar() + toolbar.setMovable(False) + + # 添加工具栏按钮 + zoom_in_action = QAction("放大", self) + zoom_out_action = QAction("缩小", self) + pan_action = QAction("平移", self) + measure_action = QAction("测量", self) + + toolbar.addAction(zoom_in_action) + toolbar.addAction(zoom_out_action) + toolbar.addAction(pan_action) + toolbar.addAction(measure_action) + + main_layout.addWidget(toolbar) + + # 创建地图显示区域 + self.map_widget = QLabel("地图显示区域") + self.map_widget.setAlignment(Qt.AlignCenter) + self.map_widget.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc;") + main_layout.addWidget(self.map_widget) + + # 创建图层控制区域 + layer_control = QHBoxLayout() + self.threat_layer_btn = QPushButton("威胁层") + self.path_layer_btn = QPushButton("路径层") + self.base_layer_btn = QPushButton("基础层") + + layer_control.addWidget(self.threat_layer_btn) + layer_control.addWidget(self.path_layer_btn) + layer_control.addWidget(self.base_layer_btn) + + main_layout.addLayout(layer_control) + + self.setLayout(main_layout) + + # 连接信号 + self.threat_layer_btn.clicked.connect(self.toggle_threat_layer) + self.path_layer_btn.clicked.connect(self.toggle_path_layer) + self.base_layer_btn.clicked.connect(self.toggle_base_layer) + + def toggle_threat_layer(self): + # TODO: 实现威胁层的显示/隐藏 + pass + + def toggle_path_layer(self): + # TODO: 实现路径层的显示/隐藏 + pass + + def toggle_base_layer(self): + # TODO: 实现基础层的显示/隐藏 + pass \ No newline at end of file diff --git a/Src/command_center/ui/path_layer_view.py b/Src/command_center/ui/path_layer_view.py new file mode 100644 index 00000000..c4e40da4 --- /dev/null +++ b/Src/command_center/ui/path_layer_view.py @@ -0,0 +1,63 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QTableWidget, QTableWidgetItem) +from PyQt5.QtCore import Qt + +class PathLayerView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建路径列表 + self.path_table = QTableWidget() + self.path_table.setColumnCount(4) + self.path_table.setHorizontalHeaderLabels(["ID", "起点", "终点", "状态"]) + self.path_table.setStyleSheet("QTableWidget { border: 1px solid #ccc; }") + main_layout.addWidget(self.path_table) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.add_path_btn = QPushButton("添加路径") + self.edit_path_btn = QPushButton("编辑路径") + self.delete_path_btn = QPushButton("删除路径") + self.simulate_path_btn = QPushButton("模拟路径") + + button_layout.addWidget(self.add_path_btn) + button_layout.addWidget(self.edit_path_btn) + button_layout.addWidget(self.delete_path_btn) + button_layout.addWidget(self.simulate_path_btn) + + main_layout.addLayout(button_layout) + + # 创建路径详情区域 + self.path_detail = QLabel("路径详情") + self.path_detail.setAlignment(Qt.AlignCenter) + self.path_detail.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc;") + main_layout.addWidget(self.path_detail) + + self.setLayout(main_layout) + + # 连接信号 + self.add_path_btn.clicked.connect(self.add_path) + self.edit_path_btn.clicked.connect(self.edit_path) + self.delete_path_btn.clicked.connect(self.delete_path) + self.simulate_path_btn.clicked.connect(self.simulate_path) + + def add_path(self): + # TODO: 实现添加路径功能 + pass + + def edit_path(self): + # TODO: 实现编辑路径功能 + pass + + def delete_path(self): + # TODO: 实现删除路径功能 + pass + + def simulate_path(self): + # TODO: 实现路径模拟功能 + pass \ No newline at end of file diff --git a/Src/command_center/ui/path_planning_view.py b/Src/command_center/ui/path_planning_view.py new file mode 100644 index 00000000..e2d84cf3 --- /dev/null +++ b/Src/command_center/ui/path_planning_view.py @@ -0,0 +1,88 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QGroupBox, QFormLayout, QComboBox, + QSpinBox, QDoubleSpinBox) +from PyQt5.QtCore import Qt + +class PathPlanningView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建算法配置组 + algorithm_group = QGroupBox("算法配置") + algorithm_layout = QFormLayout() + + self.algorithm_combo = QComboBox() + self.algorithm_combo.addItems(["A*算法", "遗传算法", "RRT算法"]) + + self.max_iterations = QSpinBox() + self.max_iterations.setRange(100, 10000) + self.max_iterations.setValue(1000) + + self.safety_margin = QDoubleSpinBox() + self.safety_margin.setRange(0.1, 10.0) + self.safety_margin.setValue(1.0) + self.safety_margin.setSingleStep(0.1) + + algorithm_layout.addRow("路径规划算法:", self.algorithm_combo) + algorithm_layout.addRow("最大迭代次数:", self.max_iterations) + algorithm_layout.addRow("安全距离(m):", self.safety_margin) + + algorithm_group.setLayout(algorithm_layout) + main_layout.addWidget(algorithm_group) + + # 创建路径参数组 + path_group = QGroupBox("路径参数") + path_layout = QFormLayout() + + self.start_lat = QDoubleSpinBox() + self.start_lon = QDoubleSpinBox() + self.end_lat = QDoubleSpinBox() + self.end_lon = QDoubleSpinBox() + + for spinbox in [self.start_lat, self.start_lon, self.end_lat, self.end_lon]: + spinbox.setRange(-180, 180) + spinbox.setDecimals(6) + + path_layout.addRow("起点纬度:", self.start_lat) + path_layout.addRow("起点经度:", self.start_lon) + path_layout.addRow("终点纬度:", self.end_lat) + path_layout.addRow("终点经度:", self.end_lon) + + path_group.setLayout(path_layout) + main_layout.addWidget(path_group) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.plan_path_btn = QPushButton("规划路径") + self.clear_path_btn = QPushButton("清除路径") + self.export_path_btn = QPushButton("导出路径") + + button_layout.addWidget(self.plan_path_btn) + button_layout.addWidget(self.clear_path_btn) + button_layout.addWidget(self.export_path_btn) + + main_layout.addLayout(button_layout) + + self.setLayout(main_layout) + + # 连接信号 + self.plan_path_btn.clicked.connect(self.plan_path) + self.clear_path_btn.clicked.connect(self.clear_path) + self.export_path_btn.clicked.connect(self.export_path) + + def plan_path(self): + # TODO: 实现路径规划功能 + pass + + def clear_path(self): + # TODO: 实现清除路径功能 + pass + + def export_path(self): + # TODO: 实现导出路径功能 + pass \ No newline at end of file diff --git a/Src/command_center/ui/path_simulation_view.py b/Src/command_center/ui/path_simulation_view.py new file mode 100644 index 00000000..2f21a1b1 --- /dev/null +++ b/Src/command_center/ui/path_simulation_view.py @@ -0,0 +1,109 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QGroupBox, QFormLayout, QProgressBar, + QSpinBox, QDoubleSpinBox) +from PyQt5.QtCore import Qt, QTimer + +class PathSimulationView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + self.simulation_timer = QTimer() + self.simulation_timer.timeout.connect(self.update_simulation) + self.simulation_progress = 0 + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建模拟控制组 + control_group = QGroupBox("模拟控制") + control_layout = QFormLayout() + + self.speed_spinbox = QDoubleSpinBox() + self.speed_spinbox.setRange(0.1, 10.0) + self.speed_spinbox.setValue(1.0) + self.speed_spinbox.setSingleStep(0.1) + + self.interval_spinbox = QSpinBox() + self.interval_spinbox.setRange(10, 1000) + self.interval_spinbox.setValue(100) + self.interval_spinbox.setSingleStep(10) + + control_layout.addRow("模拟速度:", self.speed_spinbox) + control_layout.addRow("更新间隔(ms):", self.interval_spinbox) + + control_group.setLayout(control_layout) + main_layout.addWidget(control_group) + + # 创建模拟进度条 + self.progress_bar = QProgressBar() + self.progress_bar.setRange(0, 100) + self.progress_bar.setValue(0) + main_layout.addWidget(self.progress_bar) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.start_btn = QPushButton("开始模拟") + self.pause_btn = QPushButton("暂停") + self.stop_btn = QPushButton("停止") + self.reset_btn = QPushButton("重置") + + button_layout.addWidget(self.start_btn) + button_layout.addWidget(self.pause_btn) + button_layout.addWidget(self.stop_btn) + button_layout.addWidget(self.reset_btn) + + main_layout.addLayout(button_layout) + + # 创建状态显示组 + status_group = QGroupBox("模拟状态") + status_layout = QFormLayout() + + self.time_label = QLabel("0.0s") + self.distance_label = QLabel("0.0m") + self.altitude_label = QLabel("0.0m") + self.speed_label = QLabel("0.0m/s") + + status_layout.addRow("已用时间:", self.time_label) + status_layout.addRow("飞行距离:", self.distance_label) + status_layout.addRow("当前高度:", self.altitude_label) + status_layout.addRow("当前速度:", self.speed_label) + + status_group.setLayout(status_layout) + main_layout.addWidget(status_group) + + self.setLayout(main_layout) + + # 连接信号 + self.start_btn.clicked.connect(self.start_simulation) + self.pause_btn.clicked.connect(self.pause_simulation) + self.stop_btn.clicked.connect(self.stop_simulation) + self.reset_btn.clicked.connect(self.reset_simulation) + + def start_simulation(self): + self.simulation_timer.start(self.interval_spinbox.value()) + + def pause_simulation(self): + self.simulation_timer.stop() + + def stop_simulation(self): + self.simulation_timer.stop() + self.simulation_progress = 0 + self.progress_bar.setValue(0) + + def reset_simulation(self): + self.simulation_progress = 0 + self.progress_bar.setValue(0) + self.time_label.setText("0.0s") + self.distance_label.setText("0.0m") + self.altitude_label.setText("0.0m") + self.speed_label.setText("0.0m/s") + + def update_simulation(self): + # TODO: 实现模拟更新逻辑 + self.simulation_progress += self.speed_spinbox.value() + if self.simulation_progress > 100: + self.simulation_progress = 100 + self.simulation_timer.stop() + + self.progress_bar.setValue(int(self.simulation_progress)) \ No newline at end of file diff --git a/Src/command_center/ui/status_dashboard.py b/Src/command_center/ui/status_dashboard.py new file mode 100644 index 00000000..6e13ecdc --- /dev/null +++ b/Src/command_center/ui/status_dashboard.py @@ -0,0 +1,128 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QProgressBar, QGroupBox) +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QColor, QPalette + +class StatusDashboard(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建系统状态组 + system_status_group = QGroupBox("系统状态") + system_layout = QVBoxLayout() + + # 创建状态指示器 + self.connection_status = self.create_status_indicator("通信状态", "未连接") + self.gps_status = self.create_status_indicator("GPS状态", "未定位") + self.battery_status = self.create_battery_indicator("电池状态", 0) + self.signal_status = self.create_signal_indicator("信号强度", 0) + + system_layout.addWidget(self.connection_status) + system_layout.addWidget(self.gps_status) + system_layout.addWidget(self.battery_status) + system_layout.addWidget(self.signal_status) + + system_status_group.setLayout(system_layout) + main_layout.addWidget(system_status_group) + + # 创建性能指标组 + performance_group = QGroupBox("性能指标") + performance_layout = QVBoxLayout() + + self.cpu_usage = self.create_progress_bar("CPU使用率", 0) + self.memory_usage = self.create_progress_bar("内存使用率", 0) + self.network_usage = self.create_progress_bar("网络使用率", 0) + + performance_layout.addWidget(self.cpu_usage) + performance_layout.addWidget(self.memory_usage) + performance_layout.addWidget(self.network_usage) + + performance_group.setLayout(performance_layout) + main_layout.addWidget(performance_group) + + self.setLayout(main_layout) + + def create_status_indicator(self, label_text, status_text): + widget = QWidget() + layout = QHBoxLayout() + + label = QLabel(label_text) + status = QLabel(status_text) + status.setStyleSheet("color: red;") + + layout.addWidget(label) + layout.addWidget(status) + layout.addStretch() + + widget.setLayout(layout) + return widget + + def create_battery_indicator(self, label_text, value): + widget = QWidget() + layout = QHBoxLayout() + + label = QLabel(label_text) + progress = QProgressBar() + progress.setValue(value) + progress.setStyleSheet(""" + QProgressBar { + border: 1px solid #ccc; + border-radius: 5px; + text-align: center; + } + QProgressBar::chunk { + background-color: #4CAF50; + } + """) + + layout.addWidget(label) + layout.addWidget(progress) + layout.addStretch() + + widget.setLayout(layout) + return widget + + def create_signal_indicator(self, label_text, value): + widget = QWidget() + layout = QHBoxLayout() + + label = QLabel(label_text) + progress = QProgressBar() + progress.setValue(value) + progress.setStyleSheet(""" + QProgressBar { + border: 1px solid #ccc; + border-radius: 5px; + text-align: center; + } + QProgressBar::chunk { + background-color: #2196F3; + } + """) + + layout.addWidget(label) + layout.addWidget(progress) + layout.addStretch() + + widget.setLayout(layout) + return widget + + def create_progress_bar(self, label_text, value): + widget = QWidget() + layout = QHBoxLayout() + + label = QLabel(label_text) + progress = QProgressBar() + progress.setValue(value) + + layout.addWidget(label) + layout.addWidget(progress) + layout.addStretch() + + widget.setLayout(layout) + return widget \ No newline at end of file diff --git a/Src/command_center/ui/threat_layer_view.py b/Src/command_center/ui/threat_layer_view.py new file mode 100644 index 00000000..e77b9cb6 --- /dev/null +++ b/Src/command_center/ui/threat_layer_view.py @@ -0,0 +1,56 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QTableWidget, QTableWidgetItem) +from PyQt5.QtCore import Qt + +class ThreatLayerView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建威胁列表 + self.threat_table = QTableWidget() + self.threat_table.setColumnCount(4) + self.threat_table.setHorizontalHeaderLabels(["ID", "类型", "位置", "威胁等级"]) + self.threat_table.setStyleSheet("QTableWidget { border: 1px solid #ccc; }") + main_layout.addWidget(self.threat_table) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.add_threat_btn = QPushButton("添加威胁") + self.edit_threat_btn = QPushButton("编辑威胁") + self.delete_threat_btn = QPushButton("删除威胁") + + button_layout.addWidget(self.add_threat_btn) + button_layout.addWidget(self.edit_threat_btn) + button_layout.addWidget(self.delete_threat_btn) + + main_layout.addLayout(button_layout) + + # 创建威胁详情区域 + self.threat_detail = QLabel("威胁详情") + self.threat_detail.setAlignment(Qt.AlignCenter) + self.threat_detail.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc;") + main_layout.addWidget(self.threat_detail) + + self.setLayout(main_layout) + + # 连接信号 + self.add_threat_btn.clicked.connect(self.add_threat) + self.edit_threat_btn.clicked.connect(self.edit_threat) + self.delete_threat_btn.clicked.connect(self.delete_threat) + + def add_threat(self): + # TODO: 实现添加威胁功能 + pass + + def edit_threat(self): + # TODO: 实现编辑威胁功能 + pass + + def delete_threat(self): + # TODO: 实现删除威胁功能 + pass \ No newline at end of file diff --git a/Src/基于侦察信息为无人机运输物资路径规划系统.txt b/Src/基于侦察信息为无人机运输物资路径规划系统.txt deleted file mode 100644 index e69de29b..00000000 -- 2.34.1