QPushButton点击后禁用自身存在短暂延迟,求解决方案
问题
Windows 10下用PyQt写的按钮,点击后禁用自身会有短暂延迟,但禁用另一个按钮无此问题。测试UI和代码如下:

测试代码:
import sys from PyQt5.QtWidgets import QtWidgets, QUiLoader def pba(): mainWindow.pushButtonA.setEnabled(False) mainWindow.pushButtonB.setEnabled(True) def pbb(): mainWindow.pushButtonB.setEnabled(False) mainWindow.pushButtonA.setEnabled(True) app = QtWidgets.QApplication(sys.argv) loader = QUiLoader() mainWindow = loader.load("Derp.ui", None) mainWindow.pushButtonA.clicked.connect(pba) mainWindow.pushButtonB.clicked.connect(pbb) mainWindow.show() app.exec()
问题根源是QPushButton点击后,会优先处理按下状态的视觉更新(比如按钮凹陷效果),禁用自身的操作被排在这个更新事件之后,因此出现延迟。开启新线程无效,因为UI操作必须在主线程执行,最终还是会进入事件队列排队。
解决办法
- 强制刷新事件队列:禁用按钮后调用
processEvents(),让UI立即处理所有待执行的GUI事件
def pba(): mainWindow.pushButtonA.setEnabled(False) QtWidgets.QApplication.processEvents() mainWindow.pushButtonB.setEnabled(True) def pbb(): mainWindow.pushButtonB.setEnabled(False) QtWidgets.QApplication.processEvents() mainWindow.pushButtonA.setEnabled(True)
- 取消按钮按下状态再禁用:手动取消按钮的按下视觉效果,再执行禁用操作
def pba(): mainWindow.pushButtonA.setDown(False) mainWindow.pushButtonA.setEnabled(False) mainWindow.pushButtonB.setEnabled(True) def pbb(): mainWindow.pushButtonB.setDown(False) mainWindow.pushButtonB.setEnabled(False) mainWindow.pushButtonA.setEnabled(True)
- 用定时器延迟执行禁用:将禁用操作放到事件循环的下一轮,确保按钮先完成点击视觉更新
from PyQt5.QtCore import QTimer def disable_btn(btn): btn.setEnabled(False) def pba(): QTimer.singleShot(0, lambda: disable_btn(mainWindow.pushButtonA)) mainWindow.pushButtonB.setEnabled(True) def pbb(): QTimer.singleShot(0, lambda: disable_btn(mainWindow.pushButtonB)) mainWindow.pushButtonA.setEnabled(True)
前两种方法即时性更优,任选其一即可。
内容的提问来源于stack exchange,提问作者Marshall Eubanks
相关产品推荐
相关产品推荐

