窗口和异步asyncio http
This commit is contained in:
parent
c662f5e436
commit
95c33def42
5 changed files with 177 additions and 1 deletions
|
@ -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/AnimationShadowEffect.py=utf-8
|
||||||
encoding//\u754C\u9762\u7F8E\u5316/\u8FB9\u6846\u52A8\u753B\u9634\u5F71/Test.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//\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//\u7A97\u53E3\u91CD\u542F/RestartMainWindow.py=utf-8
|
||||||
encoding//\u7B80\u5355\u7684\u7A97\u53E3\u8D34\u8FB9\u9690\u85CF/WeltHideWindow.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
|
encoding//\u7F51\u7EDC\u64CD\u4F5C/TcpSocket/\u63A7\u5236\u5C0F\u8F66/ControlCar.py=utf-8
|
||||||
|
|
|
@ -88,6 +88,7 @@
|
||||||
#### 2.3 其他案例
|
#### 2.3 其他案例
|
||||||
- [ 人脸描点检测](人脸描点检测/)
|
- [ 人脸描点检测](人脸描点检测/)
|
||||||
- [ 网络操作](网络操作/)
|
- [ 网络操作](网络操作/)
|
||||||
|
- [ 窗口和异步asyncio http](窗口配合异步Http/)
|
||||||
- [ QRC资源文件使用](QRC资源文件使用/)
|
- [ QRC资源文件使用](QRC资源文件使用/)
|
||||||
- [ C和C++扩展](C和C++扩展/)
|
- [ C和C++扩展](C和C++扩展/)
|
||||||
- [.1 pyx和c++](C和C++扩展/pyx和c++/)
|
- [.1 pyx和c++](C和C++扩展/pyx和c++/)
|
||||||
|
|
142
窗口配合异步Http/AsyncioUiClient.py
Normal file
142
窗口配合异步Http/AsyncioUiClient.py
Normal file
|
@ -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()
|
32
窗口配合异步Http/README.md
Normal file
32
窗口配合异步Http/README.md
Normal file
|
@ -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)<br/>
|
||||||
|
↓<br/>
|
||||||
|
↓<br/>
|
||||||
|
下载按钮 →→ doDownload(执行_doDownload方法)<br/>
|
||||||
|
↓<br/>
|
||||||
|
↓<br/>
|
||||||
|
session.get(下载json数据进行解析)<br/>
|
||||||
|
↓<br/>
|
||||||
|
↓<br/>
|
||||||
|
添加到界面 ←← _doDownloadImage(对单张图片进行下载)
|
||||||
|
|
||||||
|
# 截图
|
||||||
|
![截图1](ScreenShot/1.gif)
|
BIN
窗口配合异步Http/ScreenShot/1.gif
Normal file
BIN
窗口配合异步Http/ScreenShot/1.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 MiB |
Loading…
Reference in a new issue