简体   繁体   English

使用 asyncio 从 tkinter 切换到 PyQt5

[英]Switching from tkinter to PyQt5 with asyncio

I'm rewriting this Tkinter app to pyqt5.我正在将此 Tkinter 应用程序重写为 pyqt5。 I'm using asyncio for refreshing the Tkinter window every time because Im fetching an url repeatedly, and it requires self.update() to be called every time so the window doesn't freeze. I'm using asyncio for refreshing the Tkinter window every time because Im fetching an url repeatedly, and it requires self.update() to be called every time so the window doesn't freeze.

from tkinter import *
import asyncio
import aiohttp
    
class App(Tk):
    def __init__(self, loop):
        super().__init__()
        self.title("GUI Client")
        self.loop = loop
        self.protocol("WM_DELETE_WINDOW", self.close)
        self.tasks = []
        self.tasks.append(loop.create_task(self.rotator(1/60)))
        self.tasks.append(loop.create_task(self.updater()))

    async def rotator(self, interval):
        while await asyncio.sleep(interval, True):
            self.response = await get()
            print(self.response)
            
    async def updater(self):
        while await asyncio.sleep(0, True):                
            self.update()

    def close(self):
        for task in self.tasks:
            task.cancel()
        self.loop.stop()
        self.destroy()   

async def get ():
    async with aiohttp.ClientSession() as session:
        async with session.post('https://jsonplaceholder.typicode.com/posts', json={
    'title':'foo',
    'body':'bar',
    'userId':1
}, headers = {'Content-type': 'application/json; charset=UTF-8'}) as resp:
            data = await resp.json()
            return data    

loop = asyncio.get_event_loop()
app = App(loop)
loop.run_forever()
loop.close()

This is the pyqt5 gui but it doesn't work, I don't know if I'm using the imports well because I'm getting这是 pyqt5 gui,但它不起作用,我不知道我是否很好地使用了导入,因为我得到了

QWidget: Must construct a QApplication before a QWidget QWidget:必须在 QWidget 之前构造一个 QApplication

from PyQt5 import QtCore, QtGui, QtWidgets
import asyncio

class App(QtWidgets.QMainWindow):

    def __init__(self, loop):
        super().__init__()
        self.setGeometry(50, 50, 500, 300)
        self.setWindowTitle("GUI")
        self.setWindowIcon(QtGui.QIcon('pythonlogo.png'))
        self.show()
        self.loop = loop
        self.protocol("WM_DELETE_WINDOW", self.close)
        self.tasks = []
        self.tasks.append(loop.create_task(self.updater()))

    async def updater(self):
        while await asyncio.sleep(0, True):                
            self.update()
            
    def close(self):
        for task in self.tasks:
            task.cancel()
        self.loop.stop()
        self.destroy() 

loop = asyncio.get_event_loop()
app = App(loop)
loop.run_forever()
loop.close()

I added the quamash package to combine pyQt5 and asyncio.我添加了quamash package 以结合 pyQt5 和 asyncio。

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import quamash
import aiohttp
import asyncio

class App(QWidget):

    run = 0
    response = ''
    def __init__(self, loop):
        super().__init__()

        btn = QPushButton('Start', self)
        btn.resize(btn.sizeHint())
        btn.move(50, 50)
        btn.clicked.connect(self.start)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('GUI')    
        self.show()
        self.loop = loop
        self.tasks = []
        self.tasks.append(loop.create_task(self.rotator()))
        
    async def rotator(self):
        while await asyncio.sleep(0, True):
            if (self.run == 1):
                self.response = await get()
                print(self.response)
                  
    def start (self):
        self.run = 1            
    
async def get ():
    async with aiohttp.ClientSession() as session:
        async with session.post('https://jsonplaceholder.typicode.com/posts', json={
        'title':'foo',
        'body':'bar',
        'userId':1
    }, headers = {'Content-type': 'application/json; charset=UTF-8'}) as resp:
            data = await resp.json()
            return data
      
app = QApplication(sys.argv)
loop = quamash.QEventLoop(app)
asyncio.set_event_loop(loop)

with loop:
    window = App(loop)
    window.show()
    loop.run_forever()

It isn't necessary to update the window in pyQt5 app.无需在 pyQt5 应用程序中更新 window。

Removed below code:删除以下代码:

self.tasks.append(loop.create_task(self.updater()))

    async def updater(self):
        while await asyncio.sleep(0, True):                
            self.update()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM