Max 2015, Pyside, Max parent to Qt tool

Good morning variable creators:

We have just started testing Max 2015 and have been looking at the Python/Pyside implementation. We currently use the Blur Python methodology, alongside our own additions to the PyQt4 elements, but we are considering changing the studio to only use the MaxPlus classes etc. as we are (fingers and toes crossed) hoping that Autodesk will actually follow through and realise that the implementation of Python to Max in a proper way, is the way forward. Especially when you look at the benefits it has brought to Maya (an Autodesk product!), someone must have thought it can be used in Max. However, I digress.

The PySide Ui example that ships with the app is a good start, but there is no code that parents the ui to the main Max window, which we believe is a fundamental requirement as it is much better to have any relative ui stay with the Max window when minimizing/maximizing and stays on top of the window unless minimized by choice. Has anyone seen or found any code that supports the parenting of a pyside ui?:curses:

I have looked at the Chris Diggins article but its using a class (qtwinmigrate) that is for PyQt4. We are not looking to complie PyQt4 for use in this way, so a pyside solution is what we need.

Any feedback will be welcome.

Hey there,

this has been discussed here http://tech-artists.org/forum/showthread.php?5162-MaxPlus-parent-PySide-Window-to-Max-Window&highlight=MaxPlus .

I am afraid it will not make you a happy camper though :wink:

Cheers,
Thorsten

Yup, parenting doesn’t quite work with Max due to the screen corruption. We solved this problem the complicated and ugly ™ way, but it works with all versions of Max - we use this to “pair” python programs with Max and some other programs. Basically get the window handle of the main window of an application. We do this by getting the process ID of the paired program. Here’s a short snippet of code that can do this:


def getWindowProcessId(hwnd):
    buff = ctypes.c_uint()
    s = ctypes.windll.user32.GetWindowThreadProcessId(hwnd, ctypes.byref(buff));
    return(buff.value)

def guessMainWindow(pidarg):
    retList=[]
    hwnd=ctypes.windll.user32.GetTopWindow(0 )
    while hwnd!=0:
        pid=getWindowProcessId(hwnd)
        if pid==pidarg:									# we found the right process ID
            phwnd=ctypes.windll.user32.GetParent(hwnd)  # if the window has no parent...
            if phwnd==0:
                gwl_hwndparentResult=ctypes.windll.user32.GetWindowLongW(hwnd,-8)
                gwl_styleResult=ctypes.windll.user32.GetWindowLongW(hwnd,-16)
                if gwl_styleResult & 0x10000000!=0 and gwl_hwndparentResult==0:	# if window shows up in the task bar
                    retList.append(hwnd)
        hwnd=ctypes.windll.user32.GetWindow(hwnd, 2)
    return(retList)

what it returns is a list of window handles of the windows showing up in the windows task bar - these are usually the parent windows. Usually it returns just one. If not, take your best guess, e.g. by querying the Window title.
Next you run a thread which, at a low intervall, polls the hWnd of the parent window. If it minimizes, so does your Qt app. use QtCore.SIGNAL(“signalPromoteEvent”), QtCore.SIGNAL(“signalDemoteEvent”), QtCore.SIGNAL(“signalMakeActiveEvent”). You can do everything with ctypes and built-in Qt functionality, so you don’t have any extra dependencies. Keeping the window in front of the Max window can be a bit tricky though.

Wrap everything into a child class of QMainWindow or QDialog or whatever you’re using and you won’t even notice that hack.

It’s not elegant, but it works pretty well (and it’ll make you wish you’d deal with Maya instead)

Hey RobertKist, you are absolutely right. I do wish I was using Maya instead!

It should not be that the code in question has to be written by non Autodesk coders as I want to concentrate on the tool development, not finishing what Adesk couldn`t. However, I have a solution that works fairly well, one or two loose ends, but I think that will be resolved this week.

Thanks for posting your results, I feel kind of bad now that I was reluctant to let mine be seen, so thanks for showing me that you cannot be precious about what you discover. I am going to write mine up and will post a tut to show others what I did once I can be sure that it will deliver what is required as a fundamental.

Nobody tell Autodesk though. Hahahahah :D:

I have ran into as much issues with maya as i did with max. A lot of the python API (especially the original one) is plain ridiculous. But that’s a different discussion. On my end i definitely prefer PySide over PyQt, PyQt can be licensing hell due to GPL which was one of the main reasons for PySide to be created if i recall right. And as we also do products and license tools out, this is a must for us. In regards to not posting your result: That feels really kind of odd given you came here to ask for a solution but are unwilling to share because you think that hurts AD? That is beyond me.

That said i am not happy at all with the state of MaxPlus, where it is headed and the pace (or lack of) of its progressing. The Blur integration fits our needs a lot better as well, but due to the way it is maintained (or not), the lack of information and documentation etc. it kind of ruled itself out for us. Plus being PyQt based is a licensing issue for us. Actually to be honest it feels like this is one of the main reasons for blur to open source at all: They have to, because of GPL. (Not a licensing specialist here though)

Cheers,
Thorsten

If you read my post, I did not ask for a solution, I asked if anyone had seen or found code to support the ui connection. I did not ask anyone to write it for me, just for pointers to code that supports it. There is a difference in asking for code to be written for you and asking for reference or resources. Its kind of a grey area, but I am not in the habit of asking for code to be written for me as I do not learn that way. Perhaps I should have phrased the comment in a better way. Also, I did say in the same post that I would post my results once I was confident that the process worked. :D:

I didn’t write either that you asked for someone to write code for you, but that you asked for a solution. But i guess i was adding your posts on this topic on other forums to your reply here.

i used the method found in the link by instinct-vfx and it worked well enough in 2015. I couldn’t get it to work well in 2014 at all. That said, there were still screen corruptions happening on the window frames. If everyone complains i’ll probably go the route mr kist suggested.

Ok, so the current state of the development has produced the following:

Qt designer file converted to .py format
import of ui file that is set as child of Max
events set to give focus with keyboard input to the ui or to max (or any other window) when activated

The last thing I am doing is getting the ui to minimize and maximize when max does. I thought this would be inherited from the parent, but apparently not, unless I have overlooked something (very likely)This should not be an issue, so once that is done, I will write up the process as a tutorial and test script for people to try/test. I am confident that others will be able to suggest/add etc to the code or even improve it.

Thanks for the input so far, it has been welcome and good to see so many others looking at this issue.

We shall overcome. :D: