首页 > 解决方案 > PyQt QToolButton在焦点时不更新图标

问题描述

我在更新设置为 的按钮图标时遇到问题QToolButton。这个想法是将按钮用于电影播放器​​。播放时,按下按钮,图标变为暂停。再次按下时,播放暂停,图标恢复播放。我有一些工作代码,但问题是图标没有持续更新。如果我将 Qt 窗口保持在焦点上,则需要按下一两个按钮才能将图标更改为预期图像,此时实际图像不是预期图像(交换播放/暂停)。

这是一些最小的示例代码:

from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QStyle, QToolButton

class Widget(QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent=parent)
        self.play_button = QToolButton(clicked=self.update_button)
        self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaStop))
        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.addWidget(self.play_button)

        self.button_pressed = False

    def update_button(self):
        if self.button_pressed:
            self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
            self.button_pressed = False
            print("Button should be set to PLAY. Press is", self.button_pressed)
        else:
            self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))
            self.button_pressed = True
            print("Button should be set to PAUSE. Press is", self.button_pressed)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

在上面,我从一个停止图标开始,只是为了确保观察到变化(任何点击都应该总是改变图标)。保持窗口聚焦,我得到以下输出:

我还注意到,如果每次单击后,我在 Qt 窗口之外单击,或者调整 Qt 窗口的大小,按钮图标会更新为正确的图标。我究竟做错了什么?如何强制图标更新?

这种行为主要发生在QToolButton,但QPushButton也会产生问题(在专注时工作,但如果我调整 Qt 窗口的大小,则会出现行为不端/丢失正确状态的跟踪)。在 macOS 上使用 PyQt 5.12.3 和 qt 5.12.5。

标签: pythonpyqtpyqt5qtoolbutton

解决方案


似乎这个问题是 macOS 的 Qt 实现中的一个错误。我测试过,它发生在 PyQt5 和 PySide2 上,所以它必须来自 Qt。通过调用.repaint()after强制重绘.setIcon()似乎可以解决问题:

self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
self.play_button.repaint()

推荐阅读