PyQt QToolButton 在获得焦点时不更新图标
PyQt QToolButton not updating icon when in focus
我在更新使用 QToolButton
设置的按钮图标时遇到问题。这个想法是将按钮用于电影播放器。要播放,按下按钮,图标变为暂停。再次按下时,播放暂停,图标恢复播放。我有一些工作代码,但问题是图标没有持续更新。如果我将 Qt window 保持在焦点上,则需要按一两次按钮才能将图标更改为预期图像,此时实际图像不是预期图像(交换 play/pause)。
这是一些最小的示例代码:
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_())
在上面我从一个停止图标开始只是为了确保观察到变化(任何点击都应该总是改变图标)。保持 window 聚焦,我得到以下输出:
- 第一次点击:"Button should be set to PAUSE. Press is True"(图标无变化)
- 第二次点击:"Button should be set to PLAY. Press is False"(图标变为暂停)
- 第三次点击:"Button should be set to PAUSE. Press is True"(图标变化播放)
(依此类推,继续按预期交换)
我还注意到,如果每次单击后,我都在 Qt 外部单击 window,或者调整 Qt 的大小 window,按钮图标会更新为正确的图标。我究竟做错了什么?如何强制更新图标?
此行为主要发生在 QToolButton
,但 QPushButton
也会出现问题(在聚焦时有效,但 misbehaves/loses 如果我调整 Qt window 的大小则跟踪正确的状态).在 macOS 上使用 PyQt 5.12.3 和 qt 5.12.5。
这个问题似乎是 macOS 的 Qt 实现中的一个错误。我测试过,它发生在 PyQt5 和 PySide2 上,所以它一定来自 Qt。在 .setIcon()
之后通过调用 .repaint()
强制重绘似乎可以使问题消失:
self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
self.play_button.repaint()
我在更新使用 QToolButton
设置的按钮图标时遇到问题。这个想法是将按钮用于电影播放器。要播放,按下按钮,图标变为暂停。再次按下时,播放暂停,图标恢复播放。我有一些工作代码,但问题是图标没有持续更新。如果我将 Qt window 保持在焦点上,则需要按一两次按钮才能将图标更改为预期图像,此时实际图像不是预期图像(交换 play/pause)。
这是一些最小的示例代码:
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_())
在上面我从一个停止图标开始只是为了确保观察到变化(任何点击都应该总是改变图标)。保持 window 聚焦,我得到以下输出:
- 第一次点击:"Button should be set to PAUSE. Press is True"(图标无变化)
- 第二次点击:"Button should be set to PLAY. Press is False"(图标变为暂停)
- 第三次点击:"Button should be set to PAUSE. Press is True"(图标变化播放) (依此类推,继续按预期交换)
我还注意到,如果每次单击后,我都在 Qt 外部单击 window,或者调整 Qt 的大小 window,按钮图标会更新为正确的图标。我究竟做错了什么?如何强制更新图标?
此行为主要发生在 QToolButton
,但 QPushButton
也会出现问题(在聚焦时有效,但 misbehaves/loses 如果我调整 Qt window 的大小则跟踪正确的状态).在 macOS 上使用 PyQt 5.12.3 和 qt 5.12.5。
这个问题似乎是 macOS 的 Qt 实现中的一个错误。我测试过,它发生在 PyQt5 和 PySide2 上,所以它一定来自 Qt。在 .setIcon()
之后通过调用 .repaint()
强制重绘似乎可以使问题消失:
self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
self.play_button.repaint()