本篇介绍python中的GUI,Tkinter的使用。代码例子,抓取小米应用商店应用列表名称并且显示在gui中。
Tkinter(即 tk interface,简称 “Tk”), 提供了GUI编程接口。Tkinter是Python 自带的标准库,因此无须另行安装,它支持跨平台运行,不仅可以在 Windows 平台上运行,还支持在 Linux 和 Mac 平台上运行。Tkinter编写的程序,也称为TK GUI程序。
GUI (Graphical User Interface)指的是“图形用户界面”。它是计算机图形学(CG)的一门分支,主要研究如何在计算机中表示图形,以及利用计算机进行图形的计算、处理和显示等相关工作。一个 GUI 程序一般由窗口、下拉菜单或者对话框等图形化组件构成,通过鼠标点击菜单栏、按钮或者弹出对话框的形式来实现人机互动,从而提升人机交互的体验。
GUI属于计算机科学技术领域中的一个概念,比如使用 C/C++ 语言开发的 Qt、GTK、Electron 等都属于 GUI 软件包。
获取小米应用商店的应用列表名称,通过Tkinter GUI显示在屏幕上。
效果图:
代码实现思路:
1). gui的实现:使用Tkinter GUI相关控件;
2). 线程的实现和运用:网络请求需要在线程中完成;
3). 网络url的请求:使用requests和etree进行数据的获取和解析
# -*- coding: utf-8 -*-
# gui_main.py 文件
import os
import sys
import tkinter as tk
import threading
from gui_logic import logic # 调用b文件中的logic类
from tkinter import messagebox
class GUI:
def __init__(self):
self.root = tk.Tk()
self.root.title('抓取数据')
self.root.geometry("800x600+200+200")
self.interface()
self.status = -1
def interface(self):
""""界面编写位置"""
#url
self.LabelUrl = tk.Label(self.root,text="url")
self.LabelUrl.grid(row=0, column=0, pady=10)
self.EntryUrl = tk.Entry(self.root,width=62)
self.EntryUrl.grid(row=0, column=1, pady=10)
#page
self.LabelPageId = tk.Label(self.root, text="page")
self.LabelPageId.grid(row=1, column=0, pady=4)
self.EntryPageId = tk.Entry(self.root,width=62)
self.EntryPageId.grid(row=1, column=1, pady=4)
self.Button0 = tk.Button(self.root, text="数据抓取", command=self.start_get_data, bg="#7bbfea")
self.Button0.grid(row=3, column=1, pady=10)
self.w1 = tk.Text(self.root, width=100, height=25)
self.w1.grid(row=4, column=0, columnspan=3, padx=60)
#参数check
def check_param(self):
# url: https://app.mi.com/catTopList/0
# page_id:1
url = self.EntryUrl.get()
page_id = self.EntryPageId.get()
print("url",url)
if url == "":
print("url param is space")
return -1
if page_id == "":
print("page param is space")
return -1;
return 0;
print("run logic")
#真正的业务
def getData(self):
'''把b文件的类单独写一个方法'''
url = self.EntryUrl.get()
page_id = self.EntryPageId.get()
w1 = self.w1
logic().get_data(url,page_id, w1)
#1. 获取数据,必须用线程
def start_get_data(self):
'''先进行参数check,再执行线程。子线程无法直接执行b的类,需要把b文件单独写一个方法,然后执行'''
#先删除旧文件
# pwd=os.path.dirname(os.path.abspath(sys.argv[0]))
# delete_old_txt(pwd)
res = self.check_param();
if res<0:
self.showMessage("参数不能为空");
else:
self.status = 0
print("run logic")
'''清空输入框'''
self.w1.delete(1.0, "end")
self.T = threading.Thread(target=self.getData)
self.T.setDaemon(True)
self.T.start()
def showMessage(self,error_msg):
messagebox.showinfo("参数错误",error_msg)
if __name__ == '__main__':
a = GUI()
a.root.mainloop()
代码说明:
1)GUI类用于界面的显示,包括两个Lable,两个Entry,和一个Button;
2)start_get_data:创建线程,该线程执行的方法是getData;
3)getData:调用logic().get_data方法,而logic是另外一个模块gui_logic中的类,在下面的gui_logic.py中会介绍。
# -*- coding: utf-8 -*-
# gui_logic.py 文件
import time
from apps_get import run_main
class logic():
def __init__(self):
pass
def main(self, url,page_id):
print("[logic] url,page_id",url,page_id)
res_list = run_main(url,page_id)
print(res_list)
if len(res_list)<=0:
self.w1.insert(1.0,"error: 调用main时发生错误,可能原因是:已经存在目录")
else:
res_text = ','.join(res_list)
self.w1.insert(1.0,res_text)
def get_data(self, url,page_id,w1):
'''调用main的方法'''
self.w1 = w1
self.main(url,page_id)
代码说明:
1)get_data方法被上面提到的线程调用;self.w1是ui控件,用于显示获取到的数据;
2)语句res_list = run_main(url,page_id):调用apps_get模块的对应的方法,去进行网络请求,将结果返回到res_list中;
3)self.w1.insert:将结果数据插入到gui控件,这样,在界面上就可以看到这个应用名称列表了。
代码:
# -*- coding: utf-8 -*-
import requests
from lxml import etree
# 获取应用列表
def get_app_list(url):
headers = {
#mac os
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
#windows
# 'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
}
res = requests.get(url, headers=headers)
content = res.content.decode()
tree = etree.HTML(content)
a_list = tree.xpath('//ul[@class="applist"]/li/h5/a')
# print(a_list)
app_list = []
for a in a_list:
app_name = a.xpath('./text()') # 应用名称
print(app_name)
print(a.xpath('./@href')) #超链接
app_list.append(app_name[0])
return app_list;
#####################gui(图形界面) 模式相关函数###########
#直接被gui调用
def run_main(url,page_id):
url = url + "?page=" + page_id
return get_app_list(url)
####################main function###############
if __name__ == '__main__':
print("[main] start...");
url = 'https://app.mi.com/catTopList/0?page=1'
get_app_list(url)
#end main
说明:
1)run_main是gui调用接口,即logic中的res_list = run_main(url,page_id);
2)get_app_list是真正的网络请求入口:
(1)requests.get(url, headers=headers):获取网络数据;
(2)etree.HTML(content):将网络数据存放到为etree对象中;
(3)对etree对象进行tree.xpath解析,就能获取到想要的数据了。
再看一下运行结果:
% python3 gui_main.py