diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index 43086fe..9ae94b0 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -84,6 +84,7 @@ encoding//\u754C\u9762\u7F8E\u5316/\u6C34\u6CE2\u7EB9\u8FDB\u5EA6\u6761/TestWidg encoding//\u754C\u9762\u7F8E\u5316/\u8FB9\u6846\u52A8\u753B\u9634\u5F71/AnimationShadowEffect.py=utf-8 encoding//\u754C\u9762\u7F8E\u5316/\u8FB9\u6846\u52A8\u753B\u9634\u5F71/Test.py=utf-8 encoding//\u7A0B\u5E8F\u91CD\u542F/AutoRestart.py=utf-8 +encoding//\u7A97\u53E3\u914D\u5408\u5F02\u6B65Http/AsyncioUiClient.py=utf-8 encoding//\u7A97\u53E3\u91CD\u542F/RestartMainWindow.py=utf-8 encoding//\u7B80\u5355\u7684\u7A97\u53E3\u8D34\u8FB9\u9690\u85CF/WeltHideWindow.py=utf-8 encoding//\u7F51\u7EDC\u64CD\u4F5C/TcpSocket/\u63A7\u5236\u5C0F\u8F66/ControlCar.py=utf-8 diff --git a/README.md b/README.md index 2c83c71..bff976c 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,8 @@ #### 2.3 其他案例 - [ 人脸描点检测](人脸描点检测/) -- [ 网络操作](网络操作/) +- [ 网络操作](网络操作/) +- [ 窗口和异步asyncio http](窗口配合异步Http/) - [ QRC资源文件使用](QRC资源文件使用/) - [ C和C++扩展](C和C++扩展/) - [.1 pyx和c++](C和C++扩展/pyx和c++/) diff --git a/窗口配合异步Http/AsyncioUiClient.py b/窗口配合异步Http/AsyncioUiClient.py new file mode 100644 index 0000000..4885b42 --- /dev/null +++ b/窗口配合异步Http/AsyncioUiClient.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Created on 2018年10月24日 +@author: Irony +@site: https://github.com/892768447 +@email: 892768447@qq.com +@file: AsyncioUiClient +@description: +""" +import asyncio + +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QPixmap, QMovie +from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton,\ + QApplication, QListWidget, QListWidgetItem, QLabel, QMessageBox +import aiohttp +from quamash import QEventLoop + + +__Author__ = """By: Irony +QQ: 892768447 +Email: 892768447@qq.com""" +__Copyright__ = "Copyright (c) 2018 Irony" +__Version__ = "Version 1.0" + +Url = 'https://www.doutula.com/api/search?keyword=%E6%9C%80%E6%96%B0%E8%A1%A8%E6%83%85&mime=0&page={}' +Headers = { + ':authority': 'www.doutula.com', + ':method': 'GET', + ':scheme': 'https', + 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', + 'accept-language': 'zh-CN,zh;q=0.9', + 'cache-control': 'max-age=0', + 'dnt': '1', + 'upgrade-insecure-requests': '1', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6756.400 QQBrowser/10.2.2498.400' +} + + +class Window(QWidget): + + def __init__(self, *args, **kwargs): + super(Window, self).__init__(*args, **kwargs) + layout = QVBoxLayout(self) + self.listWidget = QListWidget(self) + self.listWidget.setSpacing(2) # item直接的间隔 + # 隐藏横向滚动条 + self.listWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) + # 让list 从左到右排列 + self.listWidget.setFlow(self.listWidget.LeftToRight) + # 自动换行 + self.listWidget.setWrapping(True) + self.listWidget.setResizeMode(self.listWidget.Adjust) + + self.buttonMsg = QPushButton('弹出提示框', self, clicked=self.showMessage) + self.buttonDown = QPushButton('下载图片', self, clicked=self.doDownload) + layout.addWidget(self.listWidget) + layout.addWidget(self.buttonMsg) + layout.addWidget(self.buttonDown) + self.currentPage = 0 + self.initSession() # 其实没必要,session主要用在需要登录的网站。缓存cookie用 + + def initSession(self): + async def _initSession(): + # 初始化session + self.session = aiohttp.ClientSession(loop=loop) + print(self.session) + asyncio.ensure_future(_initSession(), loop=loop) + + async def _doDownloadImage(self, url): + # 下载图片并添加到界面 + async with self.session.get(url) as resp: + data = await resp.read() + if not data: + print('下载失败: ', url) + return + path = os.path.join('tmp', os.path.basename(url)) + with open(path, 'wb') as fp: + fp.write(data) + item = QListWidgetItem(url, self.listWidget) + image = QPixmap(path) + item.setSizeHint(image.size()) + label = QLabel(self.listWidget) + label.setPixmap(image) + if path.endswith('.gif'): # 可能是动态图 + label.setMovie(QMovie(path)) + self.listWidget.setItemWidget(item, label) + self.listWidget.scrollToBottom() + + async def _doDownload(self): + # 下载工作 + if self.currentPage == -1: + QMessageBox.information(self, '提示', '已经没有更多了') + return + self.currentPage += 1 + url = Url.format(self.currentPage) + print('get url: ', url) + async with self.session.get(url, headers=Headers) as resp: + data = await resp.json() + if not data: + return + data = data.get('data', None) + if not data: + self.currentPage = -1 + print('已经是最后一页了') + return + # 解析json并生成item添加到界面中 + for entity in data.get('list', []): + url = entity.get('image_url', None) + if not url: + continue + await self._doDownloadImage(url) # 下载图片 + + def doDownload(self): + # 响应按钮点击调用 + asyncio.ensure_future(self._doDownload(), loop=loop) + + def showMessage(self): + # 显示对话框 + app.aboutQt() + + def closeEvent(self, event): + if not self.session.closed: + asyncio.ensure_future(self.session.close(), loop=loop) + super(Window, self).closeEvent(event) + + +if __name__ == '__main__': + import sys + import cgitb + import os + os.makedirs('tmp', exist_ok=True) + sys.excepthook = cgitb.enable(1, None, 5, 'text') + app = QApplication(sys.argv) + loop = QEventLoop(app) + asyncio.set_event_loop(loop) + w = Window() + w.show() + with loop: + loop.run_forever() diff --git a/窗口配合异步Http/README.md b/窗口配合异步Http/README.md new file mode 100644 index 0000000..41ac85e --- /dev/null +++ b/窗口配合异步Http/README.md @@ -0,0 +1,32 @@ +# asyncio结合PyQt例子 + +### [Python3.5][PyQt5] + +依赖库: + quamash(对QT事件循环的封装替换):https://github.com/harvimt/quamash + asyncio:https://docs.python.org/3/library/asyncio.html + aiohttp:https://aiohttp.readthedocs.io/en/stable/ + +1、在创建QApplication后随即设置替换事件循环loop +```python +app = QApplication(sys.argv) +loop = QEventLoop(app) +asyncio.set_event_loop(loop) +w = Window() +``` + +2、通过asyncio.ensure_future(函数(), loop=loop)来执行某个异步函数 + +Window  →→  initSession(初始化session)
+ ↓
+ ↓
+下载按钮  →→  doDownload(执行_doDownload方法)
+           ↓
+           ↓
+          session.get(下载json数据进行解析)
+           ↓
+           ↓
+添加到界面  ←←  _doDownloadImage(对单张图片进行下载) + +# 截图 +![截图1](ScreenShot/1.gif) \ No newline at end of file diff --git a/窗口配合异步Http/ScreenShot/1.gif b/窗口配合异步Http/ScreenShot/1.gif new file mode 100644 index 0000000..48b9c07 Binary files /dev/null and b/窗口配合异步Http/ScreenShot/1.gif differ