How to show simple PySide window in Houdini Apprentice?

   6443   14   6
User Avatar
Member
14 posts
Joined: Jan. 2017
Offline
Why does this not work; am I doing something wrong?

I expected a tiny little window to appear saying “Hello World”… but nothing seems to happen.

Cheers,
Fredrik

Attachments:
Screen Shot 2017-04-01 at 09.12.00.png (454.4 KB)

User Avatar
Member
17 posts
Joined: Oct. 2016
Offline
Something like this should work.

from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
class helloWindow(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent, Qt.WindowStaysOnTopHint)        
        label = QLabel("Hello World",self)
        
dialog = helloWindow()
dialog.show()

Rok Andic
www.rokandic.com
User Avatar
Member
14 posts
Joined: Jan. 2017
Offline
That's strange. I think your code should totally also work. No window appears here on my end when running your code.

I wonder if something's up with me running Apprentice and/or being on macOS.
Edited by fredrikaverpil - April 2, 2017 04:15:08
User Avatar
Member
17 posts
Joined: Oct. 2016
Offline
Apprentice shouldn't be an issue. However I put the code on the shelf as a new tool and ran it from there and not from the Python panel. I also tested this on Windows and am not sure if there are any differences regarding the OS.

Rok Andic
www.rokandic.com
User Avatar
Member
446 posts
Joined: Sept. 2013
Offline
Works on Houdini 16.0.504.20 on Mac OS 10.11.6 on my machine.
User Avatar
Member
14 posts
Joined: Jan. 2017
Offline
Thanks guys,

On my Windows 10 workstation, also equipped with Houdini Apprentice (16.0.557) I can run the code from my initial post as well as rokl's code and a window appears but then Houdini freezes up.

Do you normally not run UIs from the Python shell in Houdini?
Edited by fredrikaverpil - April 3, 2017 02:38:29
User Avatar
Staff
1059 posts
Joined: July 2005
Offline
Hello,

The Python Shell runs in a separate thread so you can get unexpected behaviour when executing PySide code from there since PySide/Qt needs to run in the main thread.

My suggestion is to instead create a shelf tool for scratch space and try out PySide code in there. You may have to register the created PySide widget with the hou.session module to avoid Python from cleaning up the widget when the shelf tool's script finishes executing.

For example:
from PySide2 import QtWidgets
label = QtWidgets.QLabel("Hello World")
label.show()
# To prevent Python from garbage collecting the label widget.
hou.session.dummy = label

I hope this helps.

Cheers,
Rob
User Avatar
Member
14 posts
Joined: Jan. 2017
Offline
Hey Rob,

Thanks so much, that was it. Now it works great.

About registering the widget in a session; I'm importing a proprietary Python package which consists of many submodules and each submodule creates numerous widgets to present a user interface. What's the recommended approach in this case?
Should I register each and every widget (or window) with Houdini?
User Avatar
Staff
1059 posts
Joined: July 2005
Offline
You don't need to register every widget, only the root widget.

But check out the Window Lifetimes section in this help page:
http://www.sidefx.com/docs/houdini16.0/hom/cb/qt [sidefx.com]

It mentions another way of keeping the root widget alive by parenting it to the main Houdini window. In most cases this is actually a better approach since it means your PySide interface will persist across .hip file sessions unlike the hou.session method I mentioned earlier.

The section also mentions that the shelf script context is not automatically cleaned up when script execution completes which means your root widget will remain alive even without parenting or registration. So whoops, my bad on that one. You probably don't need to worry about any of this if you are launching the PySide interface from a shelf tool.

Cheers,
Rob
User Avatar
Member
14 posts
Joined: Jan. 2017
Offline
Oh, excellent. Thanks - I was looking to parent the window to Houdini actually. In fact, I'd like to dock it if possible. I'll dig further into this.

By the way, do you know if there is any way I can execute Python code on Houdini startup?
For example with Maya, it looks for a “userSetup.py” file in a specific PATH. If found, it executes it. Anything like that with Houdini?

Cheers!
User Avatar
Staff
1059 posts
Joined: July 2005
Offline
Yup. Create a pythonrc.py script and put it in your $HOME/Library/Preferences/houdini/16.0/python2.7libs directory. You may have to create the python2.7libs subdirectory if it doesn't already exist.

Houdini will execute pythonrc.py on startup.

Here's the help for pythonrc.py and other scripts:
http://www.sidefx.com/docs/houdini/hom/locations [sidefx.com]

Cheers,
Rob
User Avatar
Member
16 posts
Joined: March 2016
Offline
Hi guys, I've got a similar-but-different problem. My ui was built in QtDesigner, and I'm using PySide2's QUiLoader to load the ui. Launching it from the shelf, my code looks something like this:
import hou
from PySide2 import QtCore, QtGui, QtWidgets, QtUiTools
class HDAManager(QtWidgets.QWidget):
    def __init__(self, parent=None)
        super(HDAManager, self).__init__(parent)
        ui_file = QtCore.QFile('/path/to/file.ui')
        ui_file.open(QtCore.QFile.ReadOnly)
        self.ui = QtUiTools.QUiLoader().load(ui_file), parentWidget=self)
        ui_file.close()
        
        # ... some more code ...
def run():
    ui = HDAManager()
    ui.setParent(hou.ui.mainQtWindow(), QtCore.Qt.Window)
    ui.show()

The problem is that the UI shows up as a blank window. If I move the ui.show() line into the class itself (self.ui.show()), then the UI works properly. But this doesn't seem correct, and from there I cannot get the UI to close with any UI buttons using self.ui.buttonName.clicked.connect(self.close), even implementing a closeEvent() method, nothing works to close the window. Any ideas how to get QtDesigner UI files working in H16? Not sure what I'm missing here…

Thanks,

Chris
Edited by VFXLife - April 14, 2017 13:30:42
User Avatar
Member
119 posts
Joined: April 2009
Offline
This should work:

import hou
from PySide2 import QtCore, QtUiTools, QtWidgets
 
class MyWidget(QtWidgets.QWidget):
    def __init__(self, *args, **kwargs):
        super(MyWidget,self).__init__(*args, **kwargs)
        ui_file = '/path/to/file.ui'
        self.ui = QtUiTools.QUiLoader().load(ui_file, parentWidget=self)
        self.setParent(hou.ui.mainQtWindow(), QtCore.Qt.Window)
 
foo = MyWidget()
foo.show()
Edited by blackpixel - April 15, 2017 10:58:08
Mariusz Wesierski
FX Supervisor @ Mackevision
User Avatar
Member
91 posts
Joined: July 2005
Offline
This looks like a really dated thread but was wondering if anyone has tried to launch an interface using “QUiLoader” in 17.5?

BlackPixel's code looks very clean but my interfaces also pop up as a blank window.

Looking to see if anyone has had any recent experience.

Cheers!
User Avatar
Member
91 posts
Joined: July 2005
Offline
I accidentally bumped into this solution that just may be a suitable substitute.
Instead of creating just call to a QT widget in Python shelf tool, I tried to create a Python Panel
and it worked like a charm!

import hou
from PySide2 import QtCore, QtUiTools, QtWidgets
 
def onCreateInterface():
    global theMainWidget
    
    ui_file_path = 'D:/TAHB/images/RTVFX/RTVFX/testInterface.ui'
    loader = QtUiTools.QUiLoader()
    ui_file = QtCore.QFile(ui_file_path)
    ui_file.open(QtCore.QFile.ReadOnly)
    theMainWidget = loader.load(ui_file)
    
    return theMainWidget

Not overly complicated. No comes the complicated part of hooking things up
  • Quick Links