Dynamic Interface not working in PyQt

219 views
Skip to first unread message

Joe Weidenbach

unread,
Oct 7, 2013, 3:46:42 AM10/7/13
to python_in...@googlegroups.com
Hey all,

I'm running into an issue with my conversion into PyQt when I work with dynamically loaded classes.  I'm using a QListView to display a list of modules, and when the user clicks on them the content pane of my layout should update to use the selected module's UI. Here's the code that runs on currentChanged() for the QListView:

for child in self.contentPanel.children():
            child.deleteLater()

holder =  self.settingsListModel.getHolder(current)

modClass = getattr(holder.module, holder.className)
modClass.UI(self.contentPanel)

holder is a simple class for the model being managed--module is a reference to the module, and className is the class name., and self.contentPanel is a QFrame.

Here's the relevant code from a module being called:

class NameSettings(settings.Settings):

    @staticmethod
    def UI(parent):
        print "Loading Naming GUI"
        layout = QtGui.QVBoxLayout()

        topLabel = QtGui.QLabel("Naming")
        layout.addWidget(topLabel)

        parent.setLayout(layout)

    def __init__(self):
        super(NameSettings, self).__init__()

The switching itself works fine.  The correct print statement runs when I change my selection, so UI() is being called from the correct modules.

What happens when it runs is this:  Whichever module loads first loads up it's UI beatifully.  All other modules clear the content pane and leave it blank.  If I reselect the first module in the list, it's UI loads right back up.  I should note that right now all of my modules have nearly identical code (the only thing that changes is the metadata (Module Attributes) and the class names (along with the text I'm putting in the QLabel/print statement). Also, if I switch the load order in the system so that my modules are in a different order, it's still always only the first one in the list that loads its UI, whichever module that is; but each module loads its UI correctly when alone or first loaded.

This should be fairly straightforward, I would think.  This methodology worked perfectly in the Maya UI, so I'm hoping that it's just a nuance of Qt that I'm missing.

Any ideas?

Thanks,

Joe

Justin Israel

unread,
Oct 7, 2013, 5:13:47 AM10/7/13
to python_in...@googlegroups.com
I think the problems you are having are related to the approach you are taking to swap the UIs. What you might find to work much better is to design your modular UIs as complete widgets, and your static method (factory method) would return a new instance of the widget.
Instead of trying to set a new layout against the parent and clearing out children, go the other way around. Let the module UIs know nothing of their parents. They are just widgets. Instead, your main UI does the job of taking that new widget instance, and setting it into some container. When the selection changes, you can just delete that single widget, then add a new one.

There are a number of ready-made solutions that can act as your container:
http://qt-project.org/doc/qt-4.8/qvboxlayout.html (slightly more work to clear the single item from the layout each time)

With the former 2, you would just set a single widget into the container. Then retrieve it, deleteLater, and set a new one into the first position.

Generically, it may look something like this:


class MyMainUI:
stackedLayout

def setCurrentWidget
stackLayout.currentWidget.deleteLater()
newWidget = ModularUI()
stackLayout.addWidget(newWidget)

ModularUI(QWidget):
layout
label
text
buttons

Really, when I look at the code examples, it seems like you don't even really need the factory method, since its just acting the exact same as a constructor.


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/525266E2.1080906%40gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.

Joe Weidenbach

unread,
Oct 7, 2013, 5:35:04 PM10/7/13
to python_in...@googlegroups.com
Thanks Justin,  I'll give that a try.  I think I've been staring at the code too long again :).

As to the examples, I've already got the functionality working in my old code, so these are JUST porting the gui system until I get that working.  I went with a factory method on them because the objects themselves have different functionality--which is not there at all right now :).  I'll check this tonight and see how it works!


Joe Weidenbach

unread,
Oct 7, 2013, 9:24:46 PM10/7/13
to python_in...@googlegroups.com
OK, that worked.  For the moment I'm sticking to a QVBoxLayout, as I don't need the functionality (right now) of a scrollarea or a stackwidget (Although I might switch to a scrollarea later this week, we'll see).  I do prefer working this way, it's just hard to break the old maya UI habits :) (especially as a teacher when I have to teach students how to use it).

Thanks again!
Reply all
Reply to author
Forward
0 new messages