qtawesome icon indicating copy to clipboard operation
qtawesome copied to clipboard

Need a way to stop animation icon from calling _update

Open paljsingh opened this issue 2 years ago • 7 comments

Once a spin icon is added, there does not seem to be an easy way to stop it from calling icon update. With the default interval of 10ms, it starts consuming a lot of cpu if there are more than a few such icons a page.

In my use case, I need spin icons temporarily to show items being processed, and later these are replaced with non-spin icons, however the spin icons do not get garbage collected and keep calling Spin._update every 10 ms.

Attaching a sample code to show the impact on cpu usage.

In idle case, the CPU usage is close to 0, and that remains close to 0 even after setting the icons to non spin ones. However, once the button icons are set to spinner, CPU usage shoots up to 70% or above, and remains at the same level even if the buttons are later set to another icon.

import sys
from functools import partial

import qtawesome as qta
from PySide2.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton, QVBoxLayout


class SpinIconTest(QWidget):

    def __init__(self):
        super().__init__()
        self.spin_buttons = list()
        self.setup_ui()

    def setup_ui(self):

        # layout..
        hbox = QHBoxLayout()
        vbox = QVBoxLayout()

        num_buttons = 10

        for i in range(num_buttons):
            button = QPushButton('button {}'.format(i), self)
            vbox.addWidget(button)
            self.spin_buttons.append(button)

        self.button1 = QPushButton('set spin icon!', self)
        self.button1.clicked.connect(partial(self.set_spin_icon))

        self.button2 = QPushButton('set to regular icon!', self)
        self.button2.clicked.connect(partial(self.set_regular_icon))

        hbox.addWidget(self.button1)
        hbox.addWidget(self.button2)

        container_widget = QWidget()
        container_widget.setLayout(vbox)
        hbox.addWidget(container_widget)
        self.setLayout(hbox)

        self.show()

    def set_spin_icon(self):
        for button in self.spin_buttons:
            button.setIcon(qta.icon("fa5s.spinner", animation=qta.Spin(button)))

    def set_regular_icon(self):
        for button in self.spin_buttons:
            button.setIcon(qta.icon("fa5s.check-circle"))


def main():

    app = QApplication([])
    ex = SpinIconTest()

    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

paljsingh avatar Jul 12 '21 13:07 paljsingh

At Idle

idle-case

After setting to Spin Icons...

spin-icon

Switching to another icon does not reduce the CPU usage.

non-spin-icon

paljsingh avatar Jul 12 '21 13:07 paljsingh

Hi @paljsingh thanks for the feedback! Maybe providing something like a stop_timer method for the Spin class could help?

dalthviz avatar Jul 21 '21 18:07 dalthviz

Yes, that would be great. Thanks.

paljsingh avatar Jul 21 '21 18:07 paljsingh

@paljsingh would you like to help us checking the implementation of this method?

dalthviz avatar Jul 22 '21 16:07 dalthviz

@paljsingh would you like to help us checking the implementation of this method?

Sure, please let me know once a fix is available for testing.

paljsingh avatar Jul 22 '21 16:07 paljsingh

I meant to say that you could help us doing the implementation and submitting a PR (sorry for the confusion there 😅 ) I think you already worked in some logic when doing a workaround for this here (which is taking the timer reference and calling stop() on it) so maybe you would like to help us doing the implementation here to have a cleaner solution in your side.

dalthviz avatar Jul 22 '21 18:07 dalthviz

No worries, I'll try to implement a solution and raise a pull request in a few days.

paljsingh avatar Jul 22 '21 18:07 paljsingh