You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySide6中await前设置按钮文本不生效的解决方案

问题原因

你的代码里fetch_request方法使用了同步的requests.get,这个操作会阻塞QtAsyncio的事件循环——事件循环被卡住时,UI更新操作(比如按钮文本修改)会被暂时搁置,必须等同步请求完成后才能执行,所以按钮文本要到API请求结束才会变化。

解决方法

有两种可靠的修复方式,核心都是避免阻塞事件循环:

方案1:使用异步HTTP客户端(推荐)

改用异步IO的aiohttp库替代同步的requests,完全贴合asyncio的设计逻辑,不会阻塞事件循环。

步骤:

  1. 先安装依赖:pip install aiohttp
  2. 修改代码如下:
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QLineEdit
from PySide6.QtGui import QIcon, QFont, QValidator
from PySide6.QtCore import QSize, QPoint, Qt

import PySide6.QtAsyncio as QtAsyncio

import asyncio
import aiohttp  # 替换为异步HTTP客户端

class AppWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle('METAR Tool')
        self.setWindowIcon(QIcon('cloud.ico'))
        self.setFixedSize(QSize(500, 300))
        self.setStyleSheet("""
            QPushButton {
                color: white;
                background-color: #42baff;
                border-radius: 5px;
            }
            QPushButton:hover, QPushButton:disabled {
                background-color: #3ca8e6;
            }
            QPushButton:pressed {
                background-color: #005180;                
            }
        """)

        self.main_font = QFont('Aptos', 18)
        self.main_font.setLetterSpacing(QFont.SpacingType(1), 1)

        self.input = QLineEdit(parent=self)
        self.input.setFont(self.main_font)
        self.input.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.input.setFixedSize(QSize(400, 60))
        self.input.setPlaceholderText('ICAO')
        self.input.move(QPoint(50, 60))
        
        self.button = QPushButton(parent=self, text='Fetch METAR')
        self.button.setFont(self.main_font)
        self.button.setFixedSize(QSize(400, 60))
        self.button.move(QPoint(50, 180))
        self.button.clicked.connect(lambda: asyncio.ensure_future(self.fetch_process('LKPR')))

    async def fetch_process(self, icao):
        self.setDisabled(True)
        self.button.setText('Fetching...')
        # 强制触发UI刷新,确保文本立即更新(可选,异步方案下可省略)
        QApplication.processEvents()
        self.response = await self.fetch_request(icao)
        # 请求完成后恢复按钮文本
        self.button.setText('Fetch METAR')
        self.setDisabled(False)

    async def fetch_request(self, icao):
        async with aiohttp.ClientSession() as session:
            async with session.get(f'https://aviationweather.gov/api/data/metar?ids={icao}&format=json&taf=false&hours=0.5') as resp:
                return await resp.json()

class AppCore():
    def __init__(self):
        self.app = QApplication([])
        self.app.setStyle('Breeze')

        self.window = AppWindow()
        self.window.show()

    def run(self):
        QtAsyncio.run(handle_sigint=True)

AppCore().run()

方案2:用线程包装同步请求

如果不想更换HTTP库,可以用asyncio.to_thread把同步的requests.get放到后台线程执行,避免阻塞事件循环:

仅修改fetch_request方法即可:

async def fetch_request(self, icao):
    import requests
    # 将同步请求委托给后台线程
    resp = await asyncio.to_thread(
        requests.get,
        f'https://aviationweather.gov/api/data/metar?ids={icao}&format=json&taf=false&hours=0.5'
    )
    return resp.json()

内容的提问来源于stack exchange,提问作者Person

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 19:47:06