0

My research for this issue returned answers that confirmed that FreeCAD GUI (or Qt) does not allow multiple activeDialog instances and that while multiple dialogs could be implemented I do not need that, I only want to load one activeDialog.

As I have tried to call from a new empty document, I believe that there should be no existing control (e.i. activeDialog) conflicting with the instance I am trying to create. I am not aware of multiple calls in the code and I don't know of a method to show an existing activeDialog in a document.

In this project I am learning to use FreeCAD and pySide so am not familiar with all conventions, anomalies etc. I am using FreeCAD, pySide and python (3.10 for freeCAD) Macos 10.14. I have created UI's both with code and in Qt Designer and consistently get the same behavior. I have cut and pasted multiple examples and have gotten the same behavior. I know it's something simple, I simply haven't found it yet.

The code is being developed so is not pretty, I can refactor as I learn and can go further.

Error occurs at : FreeCADGui.Control.showDialog(panel)

with: <class 'RuntimeError'>:Active task dialog found

from PySide import QtGui, QtCore
import Part, PartGui
import FreeCAD as App

class OffsetCalc(QtGui.QDialog):
    
    def __init__(self):
        super(OffsetCalc, self).__init__()
        self.initUI()
    def __str__(self):
        return "OffsetCalc([])"
    def __str__(self):
        return "intUI([])"


    def initUI(self):
        self.result = userCancelled

    
        # setting font and size
        # create our window
        # define window     xLoc,yLoc,xDim,yDim
        self.setGeometry(   850, 550, 250, 250)
        self.setWindowTitle("Ship Offset Calculator")
        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        # creating a label widget
                # by default label will display at top left corner
 
        # The beginning of the coordinate system is at the left top corner. 
        # The x values grow from left to right. The y values grow from top to bottom.
        self.lSta = QtGui.QLabel("Station", self)
        self.lSta.setFont('Ariel') # set to a non-proportional font
        self.lSta.move(20, 20)

        
        self.lSta = QtGui.QLabel("H.B/W.L.", self)
        self.lSta.setFont('Ariel') # set to a non-proportional font
        self.lSta.move(20, 50)


        self.lSta = QtGui.QLabel("Feet", self)
        self.lSta.setFont('Ariel') # set to a non-proportional font
        self.lSta.move(20, 80)


        self.lSta = QtGui.QLabel("Inches", self)
        self.lSta.setFont('Ariel') # set to a non-proportional font
        self.lSta.move(20, 110)


        self.lSta = QtGui.QLabel("Eights", self)
        self.lSta.setFont('Ariel') # set to a non-proportional font
        self.lSta.move(20, 140)


        # numeric input field
        self.ista = QtGui.QLineEdit("Station", self)
        self.ista.setInputMask("999")
        #self.ista.setText("000")
        self.ista.setFixedWidth(50)
        self.ista.move(100, 20)

        self.iwlht = QtGui.QLineEdit(self)
        self.iwlht.setInputMask("999")
        #self.iwlht.setText("000")
        self.iwlht.setFixedWidth(50)
        self.iwlht.move(100, 50)

        self.ifeet = QtGui.QLineEdit(self)
        self.ifeet.setInputMask("999")
        #self.ifeet.setText("000")
        self.ifeet.setFixedWidth(50)
        self.ifeet.move(100, 80)

        self.iinch = QtGui.QLineEdit(self)
        self.iinch.setInputMask("999")
        #self.iinch.setText("000")
        self.iinch.setFixedWidth(50)
        self.iinch.move(100, 110)

        self.ieight = QtGui.QLineEdit(self)
        self.ieight.setInputMask("999")
        #self.ieight.setText("000")
        self.ieight.setFixedWidth(50)
        self.ieight.move(100, 140)


        self.bok = QtGui.QPushButton("OK", self)
        self.bok.clicked.connect(self.onbok)
        self.bok.move(20, 200)
                
        self.hbht = QtGui.QRadioButton("Calc H.B", self)
        self.hbht.move(150, 205)

        self.show()


    def onbok(self):
        sta = float(self.ista.text())
        wlht = float(self.iwlht.text())
        feet = float(self.ifeet.text())
        inches = float(self.iinch.text())
        eights = float(self.ieight.text())
        inches8 = inches*8 # number of 1/8's in Inches column
        dec_ft = (inches8 + eights)/96
        total_ft = feet + dec_ft

        # doc = App.activeDocument() 
        #p = Part.Point
        p = App.ActiveDocument.addObject("Part::Vertex", "p1")
        p.Y = sta # Station is always Y
        if self.hbht.isChecked:     #True =hb / False =ht
            # use calced X
            print("Using calc X")
            p.X = total_ft
            p.Z = wlht
        else:
            # use calced Z
            print("Using calced Z")
            p.X =  wlht 
            p.Z = total_ft
            
        App.ActiveDocument.recompute()

        # print("Station = ", sta, "Height = ", wlht, "Feet = ", feet, "Inches = ", inches, "Eights + ", eights)
        # print("Eights of Inches = ", inches8, "Dec Ft. = ", dec_ft, "Total = ", total_ft)
        self.result         = userOK
        self.close()

        doc=App.activeDocument() 
        p = Part.Point()
        p.Y = sta # Station is always Y
        if self.hbht.isChecked:     #True =hb / False =ht
            # use calced X
            print("Using calc X")
            p.X = total_ft
            p.Z = wlht
        else:
            # use calced Z
            print("Using calced Z")
            p.X =  wlht 
            p.Z = total_ft
            
        doc.recompute()

    def add_X_Point(self):
        doc=App.activeDocument() 
        p = Part.Point
        p.Y = Sta
        p.X = hb
        p.Z = total_ft 
        doc.recompute()
    

    def onCancel(self):
        self.result         = userCancelled
        self.close()
    def onOk(self):
        self.result         = userOK
        self.close()
    def mousePressEvent(self, event):
        # print mouse position, X & Y
        print("X = ", event.pos().x())
        print("Y = ", event.pos().y())
        #
userCancelled = "Cancelled"
userOK = "OK"

form = OffsetCalc()
form.exec_()

musicamante
  • 41,230
  • 6
  • 33
  • 58
beachboy
  • 41
  • 7
  • I'm not familiar with freecad, how is the code above used? – musicamante Feb 07 '23 at 23:19
  • The code will, ideally, allow a user to enter values from a ships table of offsets, which is basically a 3D model of the hull. The tables are expressed in Feet, Inches and eights of inches. Code converts to decimal feet, which could be out put to a "point cloud" for import into Freecad, or in the version above create the points sort of interactively. – beachboy Feb 08 '23 at 01:10
  • Sorry, I wasn't clear. How is the code *programmatically* used? Is there a plugin interface that detects files/modules? Are they installed from the UI? – musicamante Feb 08 '23 at 01:13
  • Ah. that makes sense,sorry! The goal is to have an interactive tool that will add points based on user input. I would like to use it in the graphic window to. see the results on screen. I tried running a macro with the code. I tried several iterations and will have to recall any nuances. – beachboy Feb 08 '23 at 07:30
  • It may be my confusion is based on not being familiar with how to implement in general. – beachboy Feb 08 '23 at 07:42
  • No, you're not understanding my question. I'm not interested on what your tool does or its purpose. I want to know how you can make freecad use *that specific code or file* that you're writing. – musicamante Feb 08 '23 at 14:36
  • Got it thanks. I am, un-fortunatly, still in the process of learning how to do what you asked. I am using this Freecad documentation :https://wiki.freecad.org/Manual:Creating_interface_tools and, for example, tried the samples and got the errors. I will try to create a bare bones "hello world" thing to eliminate as much as possible and see if that narrows the possibilities. Thanks for your interest and i am sorry if I'm not being helping. – beachboy Feb 09 '23 at 00:06
  • Well, it seems that FreeCad uses its own way to show dialogs, which means that you need to implement a standard class that includes a `self.form` widget (not a dialog!) that it will include in a dialog that it will create on its own, using the `showDialog()` function. I would recommend you to let your learning process take its time: learn how freeCad works starting with the base tutorial you linked (which you have to follow closely at first), then slowly and carefully try to implement what you want but still following the concepts of that tutorial as a main reference. – musicamante Feb 09 '23 at 00:37
  • I believe you are correct that freecad handles this differently. I stumbled on to a way to call the .py file with code for both ui and logic as an input form in an active drawing. Freecad doc suggested opening .py as a file which opened the code in an editor. By opening the .py file in the "Macros" menu the form is displayed in an active drawing window. I will keep working with the ui as it is very helpful. – beachboy Feb 09 '23 at 03:52

0 Answers0