PyQt QToolButton在焦点时不更新图标
问题描述
我在更新使用 QToolButton
设置的按钮的图标时遇到问题.这个想法是将按钮用于电影播放器.播放时,按下按钮,图标变为暂停.再次按下时,播放暂停,图标恢复播放.我有一些工作代码,但问题是图标没有持续更新.如果我将 Qt 窗口保持在焦点上,则需要按下一两个按钮才能将图标更改为预期图像,此时实际图像不是预期图像(交换播放/暂停).
I'm having a problem updating the icon of a button set with QToolButton
. The idea is to use the button for a movie player. To play, one presses the button and the icon changes to pause. When pressed again, play is paused and the icon reverts to play. I have some working code, but the problem is that the icon is not updating consistently. If I keep the Qt window in focus, it takes one or two button presses to change the icon to the intended image, by which time the actual image is not the intended image (swapped play/pause).
这是一些最小的示例代码:
Here is some minimal example code:
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_())
在上面我从一个停止图标开始只是为了确保观察到变化(任何点击都应该总是改变图标).保持窗口聚焦,我得到以下输出:
In the above I start with a stop icon just to be sure to observe a change (any click should always change the icon). Keeping the window focused, I get the following output:
- 第一次点击:按钮应设置为暂停.按下为真"(图标没有变化)
- 第二次点击:按钮应设置为播放.按下为假"(图标变为暂停)
- 第三次点击:按钮应设置为暂停.按下为真"(图标变为播放)(依此类推,继续按预期交换)
我还注意到,如果每次单击后,我在 Qt 窗口之外单击,或者调整 Qt 窗口的大小,按钮图标会更新为正确的图标.我究竟做错了什么?如何强制更新图标?
I've also noticed that if after each click, I click outside the Qt window, or resize the Qt window, the button icon updates to the correct one. What am I doing wrong? How do I force the icon to update?
这种行为主要发生在 QToolButton
中,但 QPushButton
也会产生问题(在聚焦时有效,但如果我调整 Qt 窗口大小,则会出现错误行为/丢失正确状态的跟踪).在 macOS 上使用 PyQt 5.12.3 和 qt 5.12.5.
This behaviour happens mostly with QToolButton
, but QPushButton
also give issues (works when focused, but misbehaves/loses track of correct status if I resize the Qt window). Using PyQt 5.12.3 and qt 5.12.5 on macOS.
解决方案
似乎这个问题是 macOS 的 Qt 实现中的一个错误.我测试过,它发生在 PyQt5 和 PySide2 上,所以它必须来自 Qt.在 .setIcon()
之后调用 .repaint()
强制重绘似乎可以解决问题:
Seems like this issue is a bug in the Qt implementation for macOS. I tested and it happens with both PyQt5 and PySide2, so it must come from Qt. Forcing a redraw with a call to .repaint()
after .setIcon()
seems to make the problem go away:
self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
self.play_button.repaint()
相关文章