PySide / Python GUI freezes

二次信任 提交于 2019-12-10 18:18:38

问题


I'm currently writing a GUI for rvplayer that shall enable artists to automatically render dailies with slate and burn-in information. The GUI is written with PySide and scripted in Python 2.7. My problem is that upon calling my process and updating my QProgressBar with the stdout the GUI freezes. I know that this is a common problem and that it can probably be solved with processEvents() somehow, but I know far too little about threading and process loops to get my head around this issue. Since my code is a little lengthy already, here's the part that causes the issue:

def rv(self, args):
    p = subprocess.Popen(["C:/Program Files/Tweak/RV-4.0.10-64/bin/rvio_hw.exe"]+[x for x in args], stdout=subprocess.PIPE)
    while True:
        line = p.stdout.readline()
        if line != "":
            progressStr=re.search(r"([0-9]+.[0-9]+%)", line.rstrip())
            if progressStr == None:
                print line.rstrip()
            else:
                progressInt=int(float(re.sub("[^0123456789\.]", "", progressStr.group())))
                self.prog_QProgressBar.setValue(progressInt)
                print progressStr.group()
        else:       
            break

and here is the part that starts my QApplication:

if __name__ == "__main__":

    app = QtGui.QApplication(sys.argv)
    finalForm = MainWindow()
    finalForm.show()
    sys.exit(app.exec_())

I'm calling the function rv upon pressing a button and although the progress bar keeps updating normally, the window starts to get nonresponsive after some time. I do not understand at which point I could use app.processEvents() to tell my QApplication to run the process in a separate thread or in the background.


回答1:


Since it looks like you're not using threads, it may be that all that's required is to call processEvents after updating the progress bar, like this:

    self.prog_QProgressBar.setValue(progressInt)
    QtGui.qApp.processEvents()

However, the effectiveness of this may depend on how long it takes the process to produce the output. All that the processEvents call does is to immediately handle any pending events (e.g. widget painting, mouse clicks, etc) that are currently in the application's event queue. In between those calls, the GUI will continue to freeze (i.e. the executing code is not run in a separate thread or in the background, as you suggested). So the extent to which this technique can keep the GUI responsive depends on how frequently processEvents can be called within the rv() method.




回答2:


The issue is that it's not as if your app is frozen, but Windows thinks that the app is frozen as it's ignoring events (mouse over, click etc etc), so Windows, in its wisdom, gives you that dialogue.

You need to start the thread off after the show() and then run the processEvents function, and obviously only call sys.exit once your thread has finished.



来源:https://stackoverflow.com/questions/27824905/pyside-python-gui-freezes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!