0

Can somebody please explain why both of lists are not equal? I mean output should be True but it's output is False. Why?

    # CASE 1
    list1 = []
    for item in [self.home_btn, self.secret_dir_btn, self.info_btn]:
        list1.append(QPropertyAnimation(item, b"size"))

    # CASE 2
    self.home_btn_anim = QPropertyAnimation(self.home_btn, b"size")
    self.secret_dir_btn_anim = QPropertyAnimation(self.secret_dir_btn, b"size")
    self.info_btn_anim = QPropertyAnimation(self.info_btn, b"size")
    list2 = [self.home_btn_anim, self.secret_dir_btn_anim, self.info_btn_anim]

    # Output
    print(list1 == list2)
    # Further code

Also, if I'm using case 1 to create the list, my further code doesn't work as it should. but using Case 2 to create the list makes the code work correctly. Why? and how can I solve it.

6
  • 1
    Edit the post to fix the typo. Commented Jan 3, 2021 at 16:40
  • Please edit the post to fix the typo, rather than posting a comment. Commented Jan 3, 2021 at 16:40
  • 1
    You create and assign separate instances of QPropertyAnimation. The class likely does not have an __eq__ implemented for it that checks for equality between different instances based on some parameter. So all the objects are different Commented Jan 3, 2021 at 16:44
  • 1
    The QPropertyAnimation class does not appear to implement an __eq__ method. Commented Jan 3, 2021 at 16:45
  • OK thanks , but is there a way I can do it, I mean if I'm using case one to create QPropertyAnimation objects, then my further code is not working, but on using case 2, it's working fine Commented Jan 3, 2021 at 16:47

2 Answers 2

2

As they have already pointed out to you, the comparison between sequences is given element by element, considering that what you are trying to do is compare the QPropertyAnimation.

On the other hand, for design reasons, QObjects are not comparable since they handle many internal states that imply that even though they have the same properties, they will not behave in the same way. And the QPropertyAnimation are QObject so they inherit that limitation as well.

Considering this, it is not recommended to implement the __eq__ method since it contradicts the predefined design, instead if you want to compare some properties then create a method that compares property by property:

def compare_animations(animation1, animation2):
    return (
        animation1.target() is animation2.target()
        and animation1.propertyName() == animation2.propertyName()
    )
equals = all([compare_animations(anim1, anim2) for anim1, anim2 in zip(list1, list2)])
print(equals)
Sign up to request clarification or add additional context in comments.

Comments

1

First, a refresher on how python compares sequences.

Sequences of the same type also support comparisons. In particular, tuples and lists are compared lexicographically by comparing corresponding elements. This means that to compare equal, every element must compare equal and the two sequences must be of the same type and have the same length.

So every element must be equal to its corresponding element from the other sequence. How is equality for objects checked? If an object does not implement __eq__, comparison between 2 of objects of that type only checks if both objects are the exact same. As in, references to the same object - this is what the is operator does.

class Foo():
    pass

a = Foo()
b = Foo()

print(a is a)
# prints true
print(a is b)
# prints false

Since QPropertyAnimation does not implement __eq__, only the is check can be performed. Which obviously results in false for different object references.

If you want to, you can extend QPropertyAnimation and implement your own __eq__-

class MyQPropertyAnimation(QPropertyAnimation):
    def __eq__(self, other):
        if not isinstance(other, QPropertyAnimation):
            # Don't compare against other types
            return NotImplemented
        # Check if the properties `target` and `propertyName` are equal for both objects
        return self.target == other.target and self.propertyName == other.propertyName

But please note that, implementing equality for an animation object probably isn't ideal. But if you strictly want equality based on those properties for your usecase, then this may be fine.

1 Comment

I believe the comparison is wrong: the target should be targetObject and both must use the callable: return self.targetObject() == other.targetObject() and self.propertyName() == other.propertyName(). Also, in order to correctly compare them, all other properties should be checked (start value, end value, duration, easing curve, etc).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.