[SOLVED] Open UI panel in standalone window

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
karim.achaibou
Posts: 62
Joined: Tue Oct 26, 2021 5:39 pm

[SOLVED] Open UI panel in standalone window

Post by karim.achaibou »

Hello,

When I load my QT UI file created in QT designer into FreeCAD it opens in the Tasks panel of the Combo View with the code below.

Code: Select all

self.form = Gui.PySideUic.loadUi(path_to_ui)
Is it possible to open it as a standalone window which is also then movable?
Last edited by karim.achaibou on Sat Dec 25, 2021 4:43 pm, edited 2 times in total.
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: Open UI panel in standalone window

Post by openBrain »

Please give full code. The line you show probably isn't the culprit.
karim.achaibou
Posts: 62
Joined: Tue Oct 26, 2021 5:39 pm

Re: Open UI panel in standalone window

Post by karim.achaibou »

to create my object I use code below which creates my feature python object and calls the panel

Code: Select all

def create(obj_name):
    obj = App.ActiveDocument.addObject("Part::FeaturePython", obj_name)
    box(obj)
    print(str(obj.Lengte) + "-" + str(obj.Binnendiameter) + "-" + str(obj.Diktebuis))

    panel = BoxTaskPanel(obj)
    Gui.Control.showDialog(panel)

    ViewProviderBox(obj.ViewObject)

    return obj
then my panel class

Code: Select all

class BoxTaskPanel():
    def __init__(self, obj):
        self.form = Gui.PySideUic.loadUi(path_to_ui)
        self.fp = obj

        """ set the values of the taskpanel with the current object values"""
        self.form.TubeLength.setValue(obj.Lengte)
        self.form.TubeThickness.setValue(obj.Diktebuis)
        self.form.TubeInnerDia.setValue(obj.Binnendiameter)
        ...
        
     def accept(self):
        d = self.pipeDictList[self.form.sizeList.currentRow()]
        self.fp.Lengte = self.form.TubeLength.value()
        self.fp.Diktebuis = self.form.TubeThickness.value()
        self.fp.Binnendiameter = self.form.TubeInnerDia.value()
        if (self.fp.Lengte == 0) or (self.fp.Diktebuis == 0) or (self.fp.Binnendiameter == 0):
            print("error, values have to be > 0")
            return
        Gui.Control.closeDialog()
        App.ActiveDocument.recompute()
        return self.fp
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: Open UI panel in standalone window

Post by openBrain »

This line specifically shows in the Task panel.

Code: Select all

Gui.Control.showDialog(panel)
If you want a dedicated panel, you have to open your UI in a QDialog or QDockWidget whose parent is Gui.getMainWindow()
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: Open UI panel in standalone window

Post by openBrain »

You can find example of non modal QDialog here : https://github.com/0penBrain/FreeCAD-ma ... og.FCMacro
karim.achaibou
Posts: 62
Joined: Tue Oct 26, 2021 5:39 pm

Re: Open UI panel in standalone window

Post by karim.achaibou »

openBrain wrote: Sat Nov 20, 2021 10:32 am This line specifically shows in the Task panel.

Code: Select all

Gui.Control.showDialog(panel)
When I disable code above, it solves my problem but now my connections don't work anymore which are in my init def from my panel.

Code: Select all

# signal/connection
self.form.typeWidget.itemClicked.connect(self.changeRating)
self.form.lineEdit_filter_sizeList.textEdited.connect(self.updateSizelist)
self.form.sizeList.itemClicked.connect(self.updateSpinbox)
If you want a dedicated panel, you have to open your UI in a QDialog or QDockWidget whose parent is Gui.getMainWindow()
your suggestion above is probably the correct way to do it, but looking at your example doesn't give ME a lot of clues ...
karim.achaibou
Posts: 62
Joined: Tue Oct 26, 2021 5:39 pm

Re: Open UI panel in standalone window

Post by karim.achaibou »

Solved by looking again at your code example
openBrain wrote: Sat Nov 20, 2021 10:34 am You can find example of non modal QDialog here : https://github.com/0penBrain/FreeCAD-ma ... og.FCMacro
relevant code in link:

Code: Select all

def __init__(self, parent=Gui.getMainWindow()): # Important for widgets to handle kinship to get consistent behavior
        super().__init__(parent, QtCore.Qt.Tool) # Using the Tool flag will keep widget on top of parent while not locking operation
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True) # So widget object is deleted when closed, not just hidden (memory friendly)
        self.setAttribute(QtCore.Qt.WA_WindowPropagation, True) # So font is propagated from parent to self (needed for windowed widgets)
        self.setObjectName("MyDialog") # Always a good idea to set an object name if one need to find the widget programatically

implemented in my code:
  • I got my dialog class inherit from QtWidgets.QDialog (from PySide2) - the container which you mentioned

Code: Select all

class BoxTaskPanel(QtWidgets.QDialog):

    def __init__(self, obj, parent=Gui.getMainWindow()):
        super().__init__(parent)
        self.form = Gui.PySideUic.loadUi(path_to_ui)
        self.form.setWindowTitle("Choose Tube")
        self.form.setModal(False)
        self.form.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        self.fp = obj
        ....

    def show(self):
        self.form.show()
  • make object from dialog class and call show() on form

Code: Select all

    panel = BoxTaskPanel(obj)
    panel.show()
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: SOLVED: Open UI panel in standalone window

Post by openBrain »

Works but not really optimal. :) Will come back on this in the coming days.
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: Open UI panel in standalone window

Post by openBrain »

karim.achaibou wrote: Sat Nov 20, 2021 1:52 pm implemented in my code:
Actually nothing so bad, just you should use 'QtCore.Qt.Tool' flag rather than 'StaysOnTopHint'.
Also yu don't need to redefine the 'show' method.
I don't have your UI file, thus following is just a example, it may work or fail depending on your file but here is the idea.

Code: Select all

class BoxTaskPanel(QtWidgets.QDialog):

    def __init__(self, obj, parent=Gui.getMainWindow()):
        super().__init__(parent, QtCore.Qt.Tool)
        self.form = Gui.PySideUic.loadUi(path_to_ui)
        self.form.setWindowTitle("Choose Tube")
        self.form.setParent(self)
        self.fp = obj
        ....
karim.achaibou
Posts: 62
Joined: Tue Oct 26, 2021 5:39 pm

Re: SOLVED: Open UI panel in standalone window

Post by karim.achaibou »

Actually nothing so bad, just you should use 'QtCore.Qt.Tool' flag rather than 'StaysOnTopHint'.
Works like a charm thanks.
Also yu don't need to redefine the 'show' method.
When I call the show function on my object without overwriting it, I get a blank dialog

Code: Select all

    panel = BoxTaskPanel(obj)
    panel.show()
Post Reply