Issue
I'm writing a Python program that has a GUI using PyQt5 and that also calls a MATLAB file using os.system(). However, one of the functions I have decides to not execute any PyQt-related statement Before os.system is called. Normal functions like 'print' run before os.system but the others won't. However, it runs them after os.system is called just fine
Ex)
def button_clicked(self):
print("Button Clicked") #works
self.label.hide() #does nothing
os.system() #MATLAB called. works
self.label.hide() #now works
I have absolutely no idea why this is happening. The really odd things is that the program just seems to ignore everything PyQt-related in the function before os.system, because even if I do the following:
def myFunction(self):
self.label.hide()
self.label2.hide()
print("myFunction Called")
def button_clicked(self):
self.label.hide() #does nothing
self.label2.hide() #does nothing
print("Button Clicked") #works
self.myFunction() #does everything in the function unless it's PyQt-related, in this instance, it prints "myFunction Called" and nothing else
os.system() #MATLAB called. Works
self.label.hide() #now works
self.label2.hide() #now works
Is os.system always executed first in a function or something? But then that wouldn't explain why things like 'print' are working.
Solution
os.system()
is blocking. This means that it will not return until the command that it called actually returns (eg.: the program quits).
In terms of event driven systems like Qt, this is a terrible mistake, because a blocking function prevents the event loop to process all events: not only those that come from the system (such as keyboard or mouse interaction) but also its own events, most importantly the drawing of widgets.
Your labels are actually hidden to the point of view of Qt (you could try a print(self.label.isVisible())
), but since you're calling os.system
right after that, Qt has had no time to visually update the widgets in order to reflect that.
While normally threading (with python's own modules or Qt's QThread, depending on the requirements, or even QRunnable) is a preferred choice for potentially blocking operations, since you actually want to start a new program, the simplest solution is to use QProcess, maybe with its own static method startDetached()
.
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.