3ds max 2019 Qt Dock widget

3ds max 2019 Qt Dock widget

malcomarmstrong
Advocate Advocate
2,118 Views
5 Replies
Message 1 of 6

3ds max 2019 Qt Dock widget

malcomarmstrong
Advocate
Advocate

Now that we have PySide2 and the load ui function, has anyone figured out how to dock a qtwidget inside Maxs interface?

I looked at the cui functionality, but so far, what I have tried does not work. I saw the Chris Diggins post relating to c++ in max 2015, but surely it should not be too difficult to create a ui file, import it and register it as a dockable item, just like you can in Maya, using python only.

Im still playing around TBH, but just was hoping to find others doing the same. If I figure oout a decent way, I will post back.

 

regards

0 Likes
2,119 Views
5 Replies
Replies (5)
Message 2 of 6

malcomarmstrong
Advocate
Advocate

I may have found it. Pending..........

0 Likes
Message 3 of 6

malcomarmstrong
Advocate
Advocate

contrived max qt attachment 

unhelpful Qt info in max docs

 

Why is the documentation so bad? Year upon year, the same awful format churned out with poor examples, info buried on multiple pages and a feedback system that apparently goes nowhere. I would have like a pymxs version, but since the docs for that are STILL non existent, I dont see why I should bother using it and go back to Maya where this stuff was sorted out almost 10 years ago. It really is galling to continually be up against poor docs, missing or non existent info and implementations that currently are not worth the hassle of researching as invariably, what you want is unavailable.

 

0 Likes
Message 4 of 6

malcomarmstrong
Advocate
Advocate

Here is an Autodesk "example" file. Run it and see that the module is not importable. Marvelous. How are you supposed to do anything when the supplied info lets you down at virtually every opportunity? Might help that they are consistent with the use of PySide2 as the message statement on line 54 is still PySide and not PySide2.

'''
UI platform which demostrate the PySide2 ui loading and 
display  object tree on explorer.
-Feng Du
'''
import os, sys
from PySide2 import QtCore, QtWidgets
import MaxPlus
import pymxs
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from maxDataModels import mxTreeNode
from qtViewModels import vmodelMaxObjects
 
rt = pymxs.runtime
uitype, basetype = MaxPlus.LoadUiType(os.path.join(os.path.dirname(__file__),'mainUI.ui'))

class PyMaxExplorer(basetype,uitype):
    def __init__(self, parent=None):
      super(PyMaxExplorer,self).__init__(parent)
      self.setupUi(self)
      self.buildViewModel()
      self.connectActions()
      self.setupMaxCallbacks()

    def setupMaxCallbacks(self):
      self._callbackItem = rt.NodeEventCallback(all=self.cbNodeEvent)
        
    def teardownMaxCallbacks(self):
      self._callbackItem = None

    def buildViewModel(self):
      self._rootNode = self.buildTree(rt.rootNode)
      self._proxyModel = QtCore.QSortFilterProxyModel()
      self._model = vmodelMaxObjects(self._rootNode)
      self._proxyModel.setSourceModel(self._model)
      self._proxyModel.setDynamicSortFilter(True)
      self._proxyModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
      self.treeView_objects.setModel(self._proxyModel)
      self.treeView_objects.setSortingEnabled(True)      
      QtCore.QObject.connect(self.uiGraphFilter, QtCore.SIGNAL("textChanged(QString)"), self._proxyModel.setFilterRegExp)

    def connectActions(self):
      self.connect(self.actionWatch, QtCore.SIGNAL('triggered()'),self.actWatch)
      self.connect(self.actionAbout, QtCore.SIGNAL('triggered()'),self.actAbout)
      self.connect(self.actionRefresh, QtCore.SIGNAL('triggered()'),self.actRefresh)
      self.connect(self.actionExit, QtCore.SIGNAL('triggered()'),self.actExit)
      self.connect(self.actionUndo, QtCore.SIGNAL('triggered()'),self.actUndo)
      self.connect(self.actionRedo, QtCore.SIGNAL('triggered()'),self.actRedo)

    def actWatch(self):
      self.Watcher.show()

    def actAbout(self):
      QtWidgets.QMessageBox.about(self, "PyMaxExplorer 1.0", "PyMaxExplorer is a demo for pymxs and PySide usage on 3ds Max")

    def actRefresh(self):
        self.buildViewModel()

    def actExit(self):
      self.close()

    def actUndo(self):
      pymxs.run_undo()

    def actRedo(self):
      pymxs.run_redo()
        
    def cbNodeEvent(self, event, node):
      self.buildViewModel()

    def buildTree(self, mxObj, parent = None, userName = ''):
      nodeName = mxObj.name
      if userName:
        nodeName = userName
      newNode = mxTreeNode(nodeName, parent)
      for c in mxObj.children:
        self.buildTree(c, newNode)
      return newNode

Gets you this:

Import Error: No module named maxDataModels

Seriously poor. Makes no mention of appending sys.path or any other way to ensure that (what I assume is a built in module) gets loaded.

 

0 Likes
Message 5 of 6

malcomarmstrong
Advocate
Advocate

Trawling through docs for another example. Pending.........

0 Likes
Message 6 of 6

malcomarmstrong
Advocate
Advocate

So, found a file that creates a basic sidebar widget, but its not very well explained and you would already have to know certain requirements for Max and Python. Its not a "How to learn"  as much as it is, "Well, there it is, work it out".

This file runs from the Max (python) directory where it is stored (if you chose to install the files), but if you have it elsewhere, you will need to ensure that your folders have __init__.py files and that the location is appended to the sys.path.

 

python and packages

 

dockWidgetExample

But the above is not great and not very well explained, it just...is.

 

I am putting together an example that has more controls etc. and is documented, post back soon.

 

Rant, moan, moan, rant, anger, cry. Beer. Ahhh, thats better. hahahahaha Robot LOL

0 Likes