用PyQt 5 開發的雷達基數據可視化軟體
來自專欄 PyQt5圖形界面編程8 人贊了文章
解決方案
軟體布局
軟體界面垂直布局遵循普通軟體布局習慣,依次為標題欄、菜單欄、工具欄、功能界面、狀態欄。主功能界面布局原則遵循簡潔優雅充分考慮軟體功能和用戶操作習慣,最左邊是數據選擇界面,下置開始處理按鈕、三維繪製按鈕和顯示數據處理進度的進度條;中間大部分空間維圖像顯示區域,盡量縮小邊框,擴展展示區域,為用戶帶來較好的視覺體驗;圖片顯示區域設有下拉選項卡用於顯示控制;界面右側是數據信息和操作事件記錄,一方面方便開發者調試軟體,另一方面隨時記錄用戶的歷史操作和顯示相關的數據動態信息,這樣可以彌補數據參數欄只能靜態顯示的弊端。
連續顯示界面在布局上根據功能有別於單個數據顯示界面,在數據選擇區的下拉選項卡有所不同,圖像控制區的滑塊變為按鈕,方便用戶進行連續觀察。而右側的數據參數和時間記錄功能區布局相同。
核心功能
單擊菜單欄中的文件菜單可以選擇打開特定雷達基數據文件,或者直接單擊工具欄的打開文件會彈出數據選擇窗口,可在系統磁碟目錄中選擇.bin格式數據。
在數據選擇區依次打開下拉菜單選擇站點、日期、時間。需要注意的是,下拉菜單中包含的站點、日期、時間信息是軟體預設目錄(可在配置文件中更改)里的基數據信息,因此不用擔心選擇到不存在的基數據文件。選定數據後單擊開始處理按鈕,程序開始處理選擇的基數據文件,包括抽取反射率因子、速度、譜寬數值,進行坐標轉換,繪製平面位置顯示和距離高度顯示圖像,進度條開始跳動,待所有計算完成後,第一幅雷達回波圖像會出現在圖像顯示區域,接下來拖動功能區的滑塊可以設定仰角和方位角,這樣就能看到一個體掃數據中的所有仰角、所有方位角的反射率因子平面位置顯示圖像和距離高度顯示圖像,右上角的數據參數則顯示了選定數據的站號、日期、時間、體掃模式、庫數、庫長、速度解析度等信息。右下角的事件記錄區域可以顯示當前圖像的序號和已處理得到的所有圖像序號。
通過拖動滑塊可以實現單個體掃數據不同仰角的數據展示,滑塊可以通過滑鼠或鍵盤左右移動,更方便用戶切換圖像。同時右下角的事件記錄區域則顯示了該處理結果中共生成了多少張平面位置顯示圖像以及當前顯示的圖像為第幾張。
距離高度顯示的回波圖像也可以通過拖動滑塊來切換,默認設定單個體掃數據共生成36張距離高度顯示圖像,角度解析度為10°,能夠滿足觀測的基本需求,若需要更高解析度的距離高度顯示圖像,也可以通過修改相關參數實現,當拖動方位角滑塊時,時間記錄區域顯示了基數據處理完成後生成的距離高度顯示圖像數量(36)以及當前顯示的圖像為第幾張。
通過點擊工具欄按鈕可以實現放大、縮小、複位、轉移視角、保存圖片、更改背景、更改透明度等操作,也可通過滑鼠點擊和滑鼠滾輪滑動快捷實現。以上三張圖片即為三位交互可視化的示例,可以看出不同方向、不同距離的相機位置能夠給用戶帶來更加豐富的視覺體驗,實際應應中能夠輔助觀測員迅速找到強回波中心,估計雷達回波的覆蓋範圍。
連續顯示選項卡有別於單個數據選項卡,它在設定數據是並非選擇單個數據文件,而是選定了站點和想要連續查看的時間區間(起始日期、時間和終止日期、時間),相同的是,在下拉選項卡中依次選擇站點、日期和時間時不用擔心會選中一個空區間或者不對應的站點與時間,因為下拉菜單是根據用戶的每一步選擇依次刷新的,這得益於Qt先進的信號/槽機制。首要選擇的站點是在軟體啟動時初始化在預設工作目錄里遍歷所有文件夾得到的站點列表,只要下拉菜單中出現的站點選項都是存在的,都能夠在硬碟里找到對應的目錄和.bin基數據文件。
設定完成後單擊設定完成按鈕程序即在後台開始快速繪製所選站點時間區間內的所有平面位置顯示圖像(後會進行解析度變更以便在界面中顯示),這個繪製過程單獨封裝,不與前面的單個數據處理程序共用類,因此處理速度較快,能夠有效減少用戶等待時間,待進度條充滿到100%後,處理完成。即可開始點擊操作區按鈕進行切換操作。右側的數據參數會根據當前顯示的圖像相應刷新變更,時間記錄區域會列印出操作項目、選定站點時間區間內的所有圖像數量和當前展示的圖片編號。
軟體配置方法
運行環境
得益於Python靈活的語法結構和跨平台特性以及功能豐富的擴展庫,這款用PyQt開發的小軟體能夠跨操作系統在任何配置了Python環境的操作系統中運行,而且磁碟佔用量極小。由於Python是高級的解釋型、動態的、面向對象的腳本語言,在運行python程序之前省去了複雜的編譯過程,也不用考慮平台不兼容特性,只要將程序的源代碼文件和配置文件複製到相應的計算機即可立即運行。
configure目錄存放了軟體啟動初始化時的配置文件;data目錄存放了.bin基數據,按站點號分文件夾保存;source目錄存放了軟體運行相關的媒體文件(如圖標、字體、提示音等);temp目錄是緩存目錄,當處理數據或者繪製圖像時,處理結果和繪製結果會存在此目錄,用戶可直接查看或手動刪除,緩存文件不會無限大而浪費磁碟空間,每一次處理都會清楚上一次數據處理殘留的圖像或數據文件;configure文件是配置信息,格式為json文件;PyRadar是封裝成的計算性的專門處理雷達基數據的庫,格式為文本文件,源代碼;ui文件是圖形用戶界面和軟體底層邏輯信號/槽等框架性功能的源代碼文件。
configure配置信息詳情:
{"installation_path":"c:/data/gui/","data_path":"c:/data/gui/data/","cache_path":"c:/data/gui/temp/","animation_path":"c:/data/gui/temp/animation/","ppi_ref_path":"c:/data/gui/temp/ppi_ref/","rhi_ref_path":"c:/data/gui/temp/rhi_ref/"}
以上為文件內容,文件本身保存為json格式,也是文本文件,它記錄了軟體啟動必須的初始化信息,安裝路徑、基數據存放路徑、緩存路徑、動畫保存路徑、平面位置顯示圖像保存路徑、距離高度顯示圖像保存路徑等。用戶可以根據自己需要或喜好更改。
在計算機上先配置好Python環境,安裝PyQt 5 、Numpy、 Scipy、 Matplotlib、 Mayavi等庫之後用Python運行ui.py文件即可進入軟體。對於需要自定義配置的地方,比如改變圖像解析度、設定配色卡(color map)、設定坐標軸、設定圖片標題、設定三位交互可視化背景顏色等都可以通過更改源代碼相關內容可輕易實現,這也是動態解釋型語言的優勢。若要更改運行計算機或複製程序到其他平台,直接複製以上目錄和文件到該計算機後配置完python環境即可運行。
軟體的編程原理
PyQt的核心機制是信號/槽,只要理解了其中主要的信號/槽機制,就能夠理解軟體的運行機理,並根據需要自定義修改。
附錄源代碼是軟體運行過程中用到的核心信號/槽,它們是整個軟體的基礎架構,支撐著整個軟體的功能實現。如上文所說,信號和槽可以多對多連接,這從一定程度上提高了運行效率並減少了開發人員開發周期,是代碼更加簡潔清晰,也便於其他使用者的修改。
上述核心信號/槽主要有:
- 打開文件按鈕-點擊-彈出文件選擇對話框;
- 打開目錄按鈕-點擊-彈出目錄設定對話框;
- 站點選項卡-文本改變-刷新日期選擇選項卡;
- 日期選項卡-文本改變-刷新時間選項卡;
- 設定完成按鈕-點擊-更新播放列表,更新顯示區間,更新狀態欄,調用數據處理函數,開始計數,刷新進度條;
- 播放控制按鈕-點擊-調用圖像刷新函數,刷新顯示區域,設定顯示序號;
- 三位繪製按鈕-點擊-調用三位交互可視化函數,刷新進度條;
- 滑塊控制項-值改變-刷新顯示圖像。
信號和槽函數可自定義,以實現複雜功能封裝。
核心代碼
self.actionOpen_folder.triggered.connect(self.set_path)self.station_set.currentIndexChanged.connect(self.refresh_date_begin)self.station_set_2.currentIndexChanged.connect(self.refresh_date_begin)self.date_begin_set.currentIndexChanged.connect(self.refresh_time_begin)self.time_begin_set.currentIndexChanged.connect(self.refresh_date_end)self.date_set.currentIndexChanged.connect(self.refresh_time_begin)self.time_set.currentIndexChanged.connect(self.set_file)self.date_end_set.currentIndexChanged.connect(self.refresh_time_end)self.actionopen.triggered.connect(lambda: self.display_1(0))self.actionopen.triggered.connect(self.open_file)self.set_done.clicked.connect(lambda: self.counter_zero)self.set_done.clicked.connect(self.play_list_reset)self.set_done.clicked.connect(self.generate_animation)self.first_img.clicked.connect(self.counter_zero)self.first_img.clicked.connect(lambda: self.show_radarimage1(self.counter))self.last_img.clicked.connect(self.counter_end)self.last_img.clicked.connect(lambda: self.show_radarimage1(-1))self.before_slide.clicked.connect(self.counter_reduce)self.before_slide.clicked.connect(lambda: self.show_radarimage1(self.counter))self.after_slide.clicked.connect(self.counter_add)self.after_slide.clicked.connect(lambda: self.show_radarimage1(self.counter))self.auto_play.clicked.connect(self.play_all)self.start_process.clicked.connect(self.ppi_play_list_reset)self.start_process.clicked.connect(self.rhi_play_list_reset)self.start_process.clicked.connect(self.process_data)self.points.clicked.connect(self.plot_points)self.ele_set.valueChanged.connect(lambda: self.show_ppi_img(int(len(self.ppi_play_list) * self.ele_set.value()/100)))self.azi_set.valueChanged.connect(lambda: self.show_rhi_img(int(len(self.rhi_play_list) * self.azi_set.value()/100)))
代碼倉庫地址
點擊這裡在GitHub上查看。
推薦閱讀:
※將 matplotlib 嵌入 PyQt5
※Python工具安裝與配置
※PyQt5系列教程(42):TIM模擬(QTreeWidget的使用)3
※【Python】【PyQt5】配置QtDesigner到PyCharm
※PyQt5.7如何安裝?題主已昏迷。