returning an IF statment without closing a loop event filter pyqt5
Question:
I have a number of frames that are made depending on the number of items in a list. I want to click on this frame to expand it to have more options. I have installed an event filter on the frame. I have been making the frames like this:
for num, i in enumerate(self.data):
exec(f"self.frame_user_{num} = QFrame(self.frame_user_frame)")
getattr(self, f"frame_user_{num}").setMouseTracking(True)
getattr(self, f"frame_user_{num}").installEventFilter(self)
and it works fine.
when it comes to the event filter
def eventFilter(self, object, event):
loop_length = len(self.data)
z = 0
if event.type() == QEvent.MouseButtonPress:
while z < loop_length:
if object == getattr(self, f"frame_user_{z}"):
self.expand_buttons(z)
else:
return False
z += 1
else:
return False
The problem I have is I need to close the if statement in the loop with an else: return False otherwise I get the error:
a ‘bool’ is expected not ‘NoneType’
but if I put the else: return false it ends the loop and doesn’t go through the rest of the frames.
How would I write the event filter so It goes through each frame without closing the loop and not giving an error?
or is there another better way?
Answers:
If you get to the end of the while
loop without executing else: return False
, you’ll exit the function without an explicit return
statement. Put another return
after the loop.
def eventFilter(self, object, event):
loop_length = len(self.data)
if event.type() == QEvent.MouseButtonPress:
for z in range(loop_length):
if object == getattr(self, f"frame_user_{z}"):
self.expand_buttons(z)
else:
return False
return True
else:
return False
I return True
there since all the other paths return False
, so I assume this is considered the successful case.
However, I’m not sure that your loop is doing what you really want. It will return False
immediately if object
is not the same as self.frame_user_0
, so you won’t keep searching for other matching attributes. I suspect what you want is:
for z in range(loop_length):
if object == getattr(self, f"frame_user_{z}"):
self.expand_buttons(z)
return True
return False
This will look for the first frame_user_{z}
attribute that matches object, expand it, and return True
. If none are found, it will return False
.
I have a number of frames that are made depending on the number of items in a list. I want to click on this frame to expand it to have more options. I have installed an event filter on the frame. I have been making the frames like this:
for num, i in enumerate(self.data):
exec(f"self.frame_user_{num} = QFrame(self.frame_user_frame)")
getattr(self, f"frame_user_{num}").setMouseTracking(True)
getattr(self, f"frame_user_{num}").installEventFilter(self)
and it works fine.
when it comes to the event filter
def eventFilter(self, object, event):
loop_length = len(self.data)
z = 0
if event.type() == QEvent.MouseButtonPress:
while z < loop_length:
if object == getattr(self, f"frame_user_{z}"):
self.expand_buttons(z)
else:
return False
z += 1
else:
return False
The problem I have is I need to close the if statement in the loop with an else: return False otherwise I get the error:
a ‘bool’ is expected not ‘NoneType’
but if I put the else: return false it ends the loop and doesn’t go through the rest of the frames.
How would I write the event filter so It goes through each frame without closing the loop and not giving an error?
or is there another better way?
If you get to the end of the while
loop without executing else: return False
, you’ll exit the function without an explicit return
statement. Put another return
after the loop.
def eventFilter(self, object, event):
loop_length = len(self.data)
if event.type() == QEvent.MouseButtonPress:
for z in range(loop_length):
if object == getattr(self, f"frame_user_{z}"):
self.expand_buttons(z)
else:
return False
return True
else:
return False
I return True
there since all the other paths return False
, so I assume this is considered the successful case.
However, I’m not sure that your loop is doing what you really want. It will return False
immediately if object
is not the same as self.frame_user_0
, so you won’t keep searching for other matching attributes. I suspect what you want is:
for z in range(loop_length):
if object == getattr(self, f"frame_user_{z}"):
self.expand_buttons(z)
return True
return False
This will look for the first frame_user_{z}
attribute that matches object, expand it, and return True
. If none are found, it will return False
.