Can you reorder a .ui file in a function?

29 views
Skip to first unread message

kiteh

unread,
Nov 28, 2018, 9:29:06 PM11/28/18
to Python Programming for Autodesk Maya
Hi all, I have a .ui file in which I have created some widgets using qt-designer in a specific order.

Eg.
QFrame
|- horLayout_01
|-|- buttonA
|- horLayout_02
|-|- LabelB
|-|- buttonB
|- horLayout_03
|-|- buttonC
|-|- buttonC

And later on, this particular UI is being called and use together with a QObject (which is also another UI, but created in pythonic terms), such that the code looks something like this:
# `mainInfoPanel` is the file that uses .ui file for setting all the signals within..
# `BasePanel` is the GUI created pythonically

import mainInfoPanel as mainInfoWidget

class infoPanel(BasePanel):
    def _build_ui(self, parent):
        self._widget = mainInfoWidget(parent)
        super(infoPanel, self)._build_ui(parent)

And so, my question here is - will it be possible to reorder the layout of the .ui file it is reading from under the `_build_ui`?

Eg. to this:
QFrame
|- horLayout_01
|-|- buttonA
|- horLayout_03
|-|- buttonC
|-|- buttonC
|- horLayout_02
|-|- LabelB
|-|- buttonB


Justin Israel

unread,
Nov 28, 2018, 10:47:58 PM11/28/18
to python_in...@googlegroups.com
You can programatically reorder a layout after it has been read in from the ui file into QObjects:

class Widget(QtGui.QWidget):

    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        layout = QtGui.QVBoxLayout(self)

        self.b1 = QtGui.QPushButton("one", self)
        self.b2 = QtGui.QPushButton("two", self)

        self.l1 = QtGui.QHBoxLayout()
        self.l1.addWidget(self.b1)

        self.l2 = QtGui.QHBoxLayout()
        self.l2.addWidget(self.b2)

        layout.addLayout(self.l1)
        layout.addLayout(self.l2)

        self.b1.clicked.connect(self.reorder)
        self.b2.clicked.connect(self.reorder)

    def reorder(self):
        item = self.layout().takeAt(1)
        self.layout().insertItem(0, item)


Justin


--
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/ee8c06f0-9627-4060-993b-80b9959926ac%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

kiteh

unread,
Nov 29, 2018, 12:05:42 PM11/29/18
to Python Programming for Autodesk Maya
Hi Justin, thank you for the example.

Perhaps I have not phrase my question properly (was being bad at putting in words)
Using the example you have given, the reordering only happens if you click on either buttons.. But I am trying to achieve the ui setup as the code/tool is being called, and is it possible to set which layout to be at which particular order?

Justin Israel

unread,
Nov 29, 2018, 1:10:37 PM11/29/18
to python_in...@googlegroups.com
I don't think we have misunderstood each other, actually. My example only used button clicks to illustrate the before and after effect. Is it not clear how you could apply this example to your build method to swap the ordering of layouts once before the widget is shown? UI created with Qt Designer will end up saving a reference to every widget and layout that it creates, as fields on the top level widget. So it should be pretty easy to move them around. 

--
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.

kiteh

unread,
Nov 29, 2018, 1:52:42 PM11/29/18
to Python Programming for Autodesk Maya
After tinkering some more with my code, using your example as a basis, I sort of get it to work... My bad on this :)

I do have a question though.. My company is using qt designer version 4.8.5 which is pretty old, I guess?
Even so, when I was trying to get the list of widgets and its position within using the following code:
for i in range(self.layout().count()):
    item_name = self.layout().itemAt(i).objectName()
  print "Name - {}, Position - {}".format(item_name, i)

It seems to works for all other widgets with the exception of QHorizontalLayout and QVerticalLayout in which in the designer version I am using, it does not have a "objectName" field and hence it errors out for me as there are 2 instances where I am using the above mentioned layout each.

Luckily, while these 2 layouts are the top 2 widgets, I can use `self.layout().takeAt(0)` or `self.layout().takeAt(1)` and re-insert them to be the last second and third in position.

Even so, is there a better way that I can query the index?



Justin Israel

unread,
Nov 29, 2018, 2:32:06 PM11/29/18
to python_in...@googlegroups.com


On Fri, Nov 30, 2018, 7:52 AM kiteh <kiteh...@gmail.com> wrote:
After tinkering some more with my code, using your example as a basis, I sort of get it to work... My bad on this :)

I do have a question though.. My company is using qt designer version 4.8.5 which is pretty old, I guess?
Even so, when I was trying to get the list of widgets and its position within using the following code:
for i in range(self.layout().count()):
    item_name = self.layout().itemAt(i).objectName()
  print "Name - {}, Position - {}".format(item_name, i)

It seems to works for all other widgets with the exception of QHorizontalLayout and QVerticalLayout in which in the designer version I am using, it does not have a "objectName" field and hence it errors out for me as there are 2 instances where I am using the above mentioned layout each.

You would need to account for the fact that itemAt() returns a QLayoutItem, which wraps the actual layout object (in order to get its object name) 


Luckily, while these 2 layouts are the top 2 widgets, I can use `self.layout().takeAt(0)` or `self.layout().takeAt(1)` and re-insert them to be the last second and third in position.

Even so, is there a better way that I can query the index?

Since indexOf() only tells you the index of widgets in the layout, you would have to loop over each item the way you are doing and compare the item to a particular layout to get its index. This could be made into a method like self._layoutIndexOf(layout, item) 
If item is an instance of QWidget then you can call layout.indexOf(item)
Otherwise you have to loop over all the items and if the loop item is a QLayoutItem then you have to do currentItem.layout() == item




--
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.

kiteh

unread,
Nov 29, 2018, 6:55:27 PM11/29/18
to Python Programming for Autodesk Maya
It seems that these layouts and the spacerItem are returning me as None when I tried using `.widget()`

Justin Israel

unread,
Nov 29, 2018, 8:01:22 PM11/29/18
to python_in...@googlegroups.com


On Fri, Nov 30, 2018, 12:55 PM kiteh <kiteh...@gmail.com> wrote:
It seems that these layouts and the spacerItem are returning me as None when I tried using `.widget()`

That is expected right? 
widget() returns widget
layout() returns layout 
spacerItem() returns a spacer item 


--
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.
Reply all
Reply to author
Forward
0 new messages