Reload UI, Rather Than Recreating

948 Views Asked by At
import sys
import webbrowser
import hou
from PySide2 import QtCore, QtUiTools, QtWidgets, QtGui

# Calling UI File & Some Modification
class someWidget(QtWidgets.QWidget):
    def __init__(self):
        super(someWidget,self).__init__()
        ui_file = 'C:/Users/XY_Ab/Documents/houdini18.5/Folder_CGI/someUI.ui'
        self.ui = QtUiTools.QUiLoader().load(ui_file, parentWidget=self)
        self.setParent(hou.qt.mainWindow(), QtCore.Qt.Window)
        self.setFixedSize(437, 42)
        self.setWindowTitle("Requesting For Help")

window_C = someWidget()
window_C.show()

So, I have created this small script that shows the UI, I have connected this to Houdini Menu Bar. Now The Problem is if I click the menu item multiple times it will create another instance of the same UI & the previous one stays back, What I want is something called "If Window Exist Delete It, Crate New One" sort of thing. Can someone guide me? I am fairly new to python in Houdini and Qt so a little explanation will be hugely helpful. Also, why can't I use from PySide6 import?? Why do I have to use from PySide2?? Because otherwise Houdini is throwing errors.

For the same thing what used to do in maya is

# Check To See If Window Exists
if cmds.window(winID, exists=True):
    cmds.deleteUI(winID)

Trying to do the same thing inside Houdini.

1

There are 1 best solutions below

2
On

I don't have Maya or Houdini, so I can't help you too much.

According to https://www.sidefx.com/docs/houdini/hom/cb/qt.html It looks like you can access Houdini's main window. The main reason the window is duplicated or deleted is how python retains the reference to window_C. You might be able to retain the reference to just show the same widget over and over again by accessing the main Houdini window.

In the examples below we are using references a different way. You probably do not need your code that has

self.setParent(hou.qt.mainWindow(), QtCore.Qt.Window)

Create the widget once and keep showing the same widget over and over.

import hou

# Create the widget class
class someWidget(QtWidgets.QWidget):
    def __init__(self, parent=None, flags=QtCore.Qt.Window):  # Note: added parent as an option
        super(someWidget,self).__init__(parent, flags)
        ...

MAIN_WINDOW = hou.ui.mainQtWindow()
try:
    MAIN_WINDOW.window_C.show()
except AttributeError:
    # Widget has not been created yet!
    # Save the widget reference to an object that will always exist and is accessible
    # parent shouldn't really matter, because we are saving the reference to an object 
    # that will exist the life of the application
    MAIN_WINDOW.window_C = someWidget(parent=MAIN_WINDOW)  
    MAIN_WINDOW.window_C.show()

To delete the previous window and create a new window.

import hou

# Create the widget class
class someWidget(QtWidgets.QWidget):
    def __init__(self, parent=None, flags=QtCore.Qt.Window):  # Note: added parent as an option
        super(someWidget,self).__init__(parent, flags)
        ...

MAIN_WINDOW = hou.ui.mainQtWindow()

# Hide the previous window
try:
    MAIN_WINDOW.window_C.close()
    MAIN_WINDOW.window_C.deleteLater()  # This is needed if you parent the widget
except AttributeError:
    pass

# Create the new Widget and override the previous widget's reference
# Python's garbage collection should automatically delete the previous widget.
# You do not need to have a parent! 
# If you do have a parent then deleteLater above is needed!
MAIN_WINDOW.window_C = someWidget()  # Note: We do not parent this widget!
MAIN_WINDOW.window_C.show()

Another resource shows you can access the previous widget from the page level variable. https://echopraxia.co.uk/blog/pyqt-in-houdinimaya-basic This is possible, but seems odd to me. The module should only be imported once, so the page level variable "my_window" should never exist. However, it sounds like the Houdini plugin system either reloads the python script or re-runs the import. If that is the case every time you show a new window from the import of the script, you are creating a new window. If the previous window is not closed and deleted properly, Houdini could have an ever growing memory issue.

try:
    my_window.close()
except (NameError, Exception):
    pass  # Normal python would always throw a NameError, because my_window is never defined

my_window = MyWindow()
#This is optional you can resize the window if youd like.
my_window.resize(471,577)
my_window.show()

PySide6

https://www.sidefx.com/docs/houdini/hom/cb/qt.html

The bottom of the page shows how to use PyQt5. The same would apply for PySide6. Houdini just happens to come with PySide2.