Jump to content

Subprocess rendering feedback


csp

Recommended Posts

Hi,

 

I have a button for local rendering which runs a python script like the following:

hip = hou.hipFile.path()
node = hou.pwd()
script = hou.findFile('scripts/rundorender')
path = os.path.split(script)[0]
subprocess.Popen([script,path,hip,node])

This will call rundorender bash script which in other process will load hipfile and start rendering the given node.

 

This works great.

 

I want be able to update an pyqt progress bar based on the progress of the rendering.

The Alfred Style Progress is enabled which prints on the terminal which used to open Houdini the progress of the rendering and looks like that:

ALF_PROGRESS 100%

I can use that update the value to an pyqt QprogressBar. But my question is how to get a live feedback of each new line in the outout?

Edited by cparliaros
Link to comment
Share on other sites

The output of whatever you call can be piped back in. An example is below. Whether or not this works if one script calls another script calls something else I'm not sure but it's worth a try.

p = subprocess.Popen(["ls"], stdout=subprocess.PIPE)
while True:
    line = p.stdout.readline()
    if not line:
        break
    print line

I found the example here.

 

http://stackoverflow.com/questions/4951099/getting-progress-message-from-subprocess-in-python

Link to comment
Share on other sites

Thanks for the reply Luke.

The code you posted works. But now I have some problems with the pyqt progressBar and I am not sure if its related to the above code.

The first time I run the script I had the window with the progress bar working perfectly, but when I closed the window, houdini also closed. Never had that with my other pyqt GUI.

 

Second time pyqt window never opened but houdini again closed.

 

The error is always the same. :

QPixmap: It is not safe to use pixmaps outside the GUI thread
QObject::installEventFilter(): Cannot filter events for objects in a different thread.

My pyqt script:

import hou, os, subprocess
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.uic import *
import pyqt_houdini

        
app = QApplication.instance()
if app is None:
        app = QApplication(['houdini'])

pwd = os.path.dirname(__file__)

class Render(QWidget):
    def __init__(self, script, path, hip, node, parent=None):
        super(Render, self).__init__(parent)
        
        self.ui = loadUi(pwd+'/ui/progressbar.ui', self)
         
        # get parameters
        self.bar = self.ui.findChild(QProgressBar, 'progressBar')
        
        # initial parameters
        self.bar.setRange(0,100)
        self.bar.setValue(30)
        
        self.ui.setWindowFlags(Qt.WindowStaysOnTopHint)
        self.ui.show()
        
        p = subprocess.Popen([script,path,hip,node],stdout=subprocess.PIPE)
        while True:
         output = p.stdout.readline()
         if not output:
         break
         elif '%' in output:
         value = int(output[13:-2])
         self.bar.setValue(value)
         
def runApp(script,path,hip,node):
    dialog = Render(script,path,hip,node)
    pyqt_houdini.exec_(app, dialog)

Searching on google, found that the error has to do with the GUI is updating from another thread. But I thought the pyqt_houdini script helps to run the gui in an different thread that the one Houdini is.

 

UPDATE:

In a new hip file worked perfect many times, even when I was closing the pyqt progress bar Houdini didn't closed but when I tried to resize the pyqt window then I got the error and houdini crashed.

Edited by cparliaros
Link to comment
Share on other sites

By the way, how is possible to update QprogressBar's value in another thread in order to be able to use the interface while rendering?

For example I have new version of the code where there is an interrupt button but I can't click it while rendering because this thread which running pyqt is busy inside the While loop.

Link to comment
Share on other sites

By the way, how is possible to update QprogressBar's value in another thread in order to be able to use the interface while rendering?

For example I have new version of the code where there is an interrupt button but I can't click it while rendering because this thread which running pyqt is busy inside the While loop.

You need to do all your time consuming computations is other QThread, while main thread of your application will update your widgets. To make things easier, you can use Qt signals mechanism. The thread, which is doing work, emits signals, which are connected to slots in your main UI class.

 

I've made a simple working example:

http://pastebin.com/JRDADi5c

  • Like 2
Link to comment
Share on other sites

You need to do all your time consuming computations is other QThread, while main thread of your application will update your widgets. To make things easier, you can use Qt signals mechanism. The thread, which is doing work, emits signals, which are connected to slots in your main UI class.

 

I've made a simple working example:

http://pastebin.com/JRDADi5c

 

is it working? because I get an error:

Traceback (most recent call last):
  File "test.py", line 8, in <module>
    class PrintSignal(QObject):
  File "test.py", line 9, in PrintSignal
    printer = Signal(str)
NameError: name 'Signal' is not defined

UPDATE:

 

never mind, I found how QThead works and I am trying to implement it on my code.

You error has to do with that I am using PyQt4 and not PySide where Signal() is pyqtSignal().

Edited by cparliaros
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...