在前面的分享中,我們制作了一個天眼查 GUI 程序,一個微博抓取 GUI 程序,今天我們在這個的基礎上,繼續開發新的功能,疫情信息快速查看工具,先來看下最終的效果。

整體的界面和框架還是繼承自前面分享的工具,我們直接來看相關功能。
搜集疫情數據網站
首先我們先搜集一些展示疫情相關信息的網站,比如上圖所示的百度疫情實時大數據報告,當然還有新浪,騰訊,丁香醫生以及美國中文網等等,大家也可以自行搜集相關網站,添加到程序當中即可。
# 疫情數據網站
site_map = {0: 'https://voice.baidu.com/act/newpneumonia/newpneumonia', 1: 'https://news.sina.cn/zt_d/yiqing0121',
2: 'https://wp.m.163.com/163/page/news/virus_report/index.html',
3: 'https://news.qq.com/zt2020/page/feiyan.htm#/', 4: 'https://sa.sogou.com/new-weball/page/sgs/epidemic',
5: 'https://news.ifeng.com/c/special/7tPlDSzDgVk', 6: 'http://www.tcrj.com.cn/yqzt/index.chtml',
7: 'http://shouji.360.cn/fyyqgjx/index.html', 8: 'https://ncov.dxy.cn/ncovh5/view/pneumonia',
9: 'https://vip.jianshiapp.com/p/covid19-overseas',
10: 'https://i.snssdk.com/ugc/hotboard_fe/hot_list/template/hot_list/forum_tab.html',
11: 'http://m.sinovision.net/newpneumonia.php'}
comboBox_text = [
"百度",
"新浪",
"網易",
"騰訊",
"搜狗",
"鳳凰",
"獼爾",
"360",
"丁香園",
"華爾街",
"今日頭條",
"美國中文網"]
上面定義了疫情數據網站的 map,同時定義了一個 combobox 組件的下拉文字列表。
頁面布局。
我們先定義疫情的 Widget 數據。
def yiqingWidget(self):
self.left_button_widget_4 = QtWidgets.QWidget()
self.yiqingWebEngine = QWebEngineView()
self.gridLayout_yiqing = QtWidgets.QGridLayout(self.left_button_widget_4)
self.gridLayout_yiqing.setContentsMargins(0, 0, 0, 0)
self.gridLayout_yiqing.setObjectName("gridLayout_yiqing")
self.label_yiqing = QtWidgets.QLabel()
self.label_yiqing.setObjectName("label_weibo")
self.label_yiqing.setText("選擇數據源")
self.gridLayout_yiqing.addWidget(self.label_yiqing, 0, 1, 1, 1)
self.yiqing_comboBox = QtWidgets.QComboBox()
for i, d in enumerate(comboBox_text):
self.yiqing_comboBox.addItem("")
self.yiqing_comboBox.setItemText(i, str(d))
self.yiqing_comboBox.setObjectName("yiqing_comboBox")
self.gridLayout_yiqing.addWidget(self.yiqing_comboBox, 0, 2, 1, 1)
self.gridLayout_yiqing.addWidget(self.yiqingWebEngine, 4, 0, 1, 9)
self.right_layout.addWidget(self.left_button_widget_4, 0, 0, 1, 9)
# 進度條
self.label_yiqing_pgb = QtWidgets.QLabel()
self.label_yiqing_pgb.setObjectName("label_yiqing_pgb")
self.label_yiqing_pgb.setText("頁面加載進度")
self.gridLayout_yiqing.addWidget(self.label_yiqing_pgb, 0, 3, 1, 1)
self.yiqing_pgb = QtWidgets.QProgressBar()
self.yiqing_pgb.setFixedHeight(10) # 設置進度條高度
self.yiqing_pgb.setMinimum(0)
self.yiqing_pgb.setMaximum(100)
self.yiqing_pgb.setValue(self.pv)
self.gridLayout_yiqing.addWidget(self.yiqing_pgb, 0, 4, 1, 1)
self.yiqingWebEngine.load(QUrl(site_map[0]))
self.slot_init()
頁面布局也比較簡單,有展示文字的 label,還有切換疫情網址的下拉框,以及展示網站加載進度的進度條組件,當然也少不了渲染網頁的 QWebEngineView 組件。
對于下拉框切換疫情網站,實現的邏輯是每次切換,都會自動請求該網站數據,并渲染到 QWebEngineView 組件中,而這個邏輯都通過函數 slot_init 來實現。
下面我們看看 slot_init 的具體實現。
引擎切換邏輯
我們先來看看函數 slot_init 的代碼
def slot_init(self):
self.yiqing_comboBox.currentIndexChanged[int].connect(self.change_engine)
self.yiqingWebEngine.loadFinished.connect(self.change_state)
self.yiqingWebEngine.loadProgress[int].connect(self.loadProgressHandler)
該函數實現了三個功能
- 切換引擎自動渲染
- 切換當中,下拉框不可被選中
- 在進度條中展示網站渲染進度
下面我們逐一查看各個功能。
切換引擎自動渲染
這里用到了槽函數,將組件 comboBox 的索引傳遞給函數 change_engine,然后在該函數中重新 load 網站 URL,并且設置 comboBox 不可用。
@pyqtSlot(int)
def change_engine(self, index):
"""
改變引擎,觸發
:param index:
:return:
"""
try:
self.yiqing_comboBox.setEnabled(False)
self.yiqingWebEngine.load(QUrl(site_map[index]))
except Exception as e:
print("yiqing web engine load error: ", e)
切換當中,下拉框不可被選中
下拉框是否可以使用,可以通過屬性 setEnabled 進行設置,當網站渲染完畢后,通過調用函數 change_state 來切換下拉框狀態。
def change_state(self):
"""
加載過程中,禁用comboBox
:return:
"""
self.yiqing_comboBox.setEnabled(True)
而網站是否渲染完畢,是通過屬性 loadFinished 來判斷的。
在進度條中展示網站渲染進度
這個功能稍微復雜一些,需要用到多線程,我們在前面微博抓取程序中也使用到了。
本程序的差異就在于需要通過屬性 loadProgress 來獲取網站加載進度,其余部分基本與微博抓取文章代碼相同。
@pyqtSlot(int)
def loadProgressHandler(self, prog):
# print(time.time(), ":load progress", prog)
self.yiqing_qth = YiQingQueryThread(prog)
self.yiqing_qth.update_yiqing_data.connect(self.yiqingPgbUpdate)
self.yiqing_qth.start()
疫情子進程代碼:
"""子進程疫情查詢"""
class YiQingQueryThread(QThread):
# 創建一個信號,觸發時傳遞當前時間給槽函數
def __init__(self, p):
super(YiQingQueryThread, self).__init__()
self.p = p
update_yiqing_data = pyqtSignal(int)
def run(self):
self.update_yiqing_data.emit(self.p)
因為需要傳遞屬性 loadProgress 的數值,所以定義了初始化函數來接受,并通過槽參數 update_yiqing_data 來進行傳遞。
至此,我們這個疫情數據查詢功能就完成了~。