[Solved] Help with macro cancel

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
jfc4120
Posts: 448
Joined: Sat Jul 02, 2022 11:16 pm

[Solved] Help with macro cancel

Post by jfc4120 »

Code: Select all

OS: Windows 10 Version 2009
Word size of FreeCAD: 64-bit
Version: 0.20.29177 (Git)
Build type: Release
Branch: releases/FreeCAD-0-20
Hash: 68e337670e227889217652ddac593c93b5e8dc94
Python 3.8.10, Qt 5.15.2, Coin 4.0.1, Vtk 8.2.0, OCC 7.6.2
Locale: English/United States (en_US)
Installed mods: 
  * Help 1.0.3

I am attempting to adapt an example from pyside examples and have a cancel work.

If I run this, it works and I can draw two lines, and no errors. However on the second loop if I hit cancel I would expect the first line to be there but of course no second line. But nothing is drawn. I am still new to this.

Code:

Code: Select all

import FreeCAD, FreeCADGui
import Draft
from math import cos, sin, radians
from PySide import QtGui

WIRE = True
INPUTININCHES = True
if INPUTININCHES:
    convert = 25.4
else:
    convert = 1.0

getDouble = QtGui.QInputDialog.getDouble
Vector, Placement = App.Vector, App.Placement
doc = App.ActiveDocument

sel = Gui.Selection.getSelectionEx()
start_point = Vector(0, 0, 0)
if sel:
    sel, = sel
    if sel.PickedPoints:
        start_point = sel.PickedPoints[-1]

FLAG = 0
I = 1

while I < 3:
    REPLY = QtGui.QInputDialog.getText(None, "Ouija Central", "Length:")
    if REPLY[1]:
        # user clicked OK
        MYREPLY = float(REPLY[0])
    else:
        # user clicked Cancel
        #MYREPLY = REPLY[0]  # which will be "" if they clicked Cancel
        sys.exit(0)

    ANG = QtGui.QInputDialog.getText(None, "Ouija Central", "Angle:")
    if ANG[1]:
        # user clicked OK
        ANG = float(ANG[0])
    else:
        # user clicked Cancel
        ANG = ANG[0]  # which will be "" if they clicked Cancel

    def line_length(x1=0.0, y1=0.0, z1=0.0, length=10.0, angle=0.0):
        x2 = x1 + (length * cos(radians(angle)))
        y2 = y1 + (length * sin(radians(angle)))
        z2 = z1  # + ()
        Draft.makeWire([FreeCAD.Vector(x1, y1, z1), FreeCAD.Vector(x2, y2, z2)])


    # Example:
    # x1 = 0.0          # Edit coordinate x1 origin
    # y1 = 0.0          # Edit coordinate y1 origin
    # z1 = 0.0          # Edit coordinate z1 origin
    # length = 50.0       # Edit length
    # angle  = 45.0       # Edit angle plane XY

    # line_length(x1, y1, z1, length, angle)

    x1 = 0.0  # Edit coordinate x1 origin
    y1 = 0.0  # Edit coordinate y1 origin
    z1 = 0.0  # Edit coordinate z1 origin
    length = MYREPLY * 25.4  # Edit length
    angle = ANG  # Edit angle plane XY
    line_length(x1, y1, z1, length, angle)
    I = I + 1

Also if I do hit cancel I get:
: <unknown exception data>
Edit:

Found this:
I added:

Code: Select all

        if MYREPLY == 9999:
            return
Seems to work, didn't get any errors. But if there's a better way please let me know
Last edited by jfc4120 on Wed Aug 03, 2022 7:14 pm, edited 1 time in total.
User avatar
Roy_043
Veteran
Posts: 8552
Joined: Thu Dec 27, 2018 12:28 pm

Re: Help with macro cancel

Post by Roy_043 »

Use break instead of sys.exit(0).
heda
Veteran
Posts: 1348
Joined: Sat Dec 12, 2015 5:49 pm

Re: Help with macro cancel

Post by heda »

great, it seems like you are now over the initial hurdle :-) and begin to find your way around things.

a couple of pointers (any code that works is good enough code, so this is largely style...)
- if you know the amount of iterations, use a for-loop instead of while (in this case you can set a high number, since the bailing with cancel seems to work decently)
- unpacking... using "ok" to me seems more clear for any reader than "REPLY[1]"
- using alias makes code more readable... (Vector = FreeCAD.Vector or App, which happens to be App = FreeCAD and is always available for use in a gui-session)
- function definitions generally go in zero indent (when you have it in the loop you will create it twice)
- in a "normal" python session, sys.exit kills the python session, now we are in fc python, not sure how fc deals with a sys.exit,
regardless, quitting loops is done with "break"
- python in itself does not care if you mix integers and floats, so do not have to bother about those things as long as you are in python, it could however be that when calling some fc-functions (which under the hood is c) it can be that calling it with an int does not work, so one has to convert the ints to a float in the calling (Vector for example takes both ints and floats, underlying type in a Vector is always float).

could it be that the reason for you not seeing the first edge after a cancel is that there was no .recompute?
oh, and used getDouble, since your intention is to get a float, not text... (i presume)

and the code

Code: Select all

import FreeCAD, FreeCADGui
import Draft
from math import cos, sin, radians
from PySide import QtGui

WIRE = True
INPUTININCHES = True
convert = 25.4 if INPUTININCHES else 1.0

getDouble = QtGui.QInputDialog.getDouble
Vector, Placement = App.Vector, App.Placement
doc = App.ActiveDocument

sel = Gui.Selection.getSelectionEx()
start_point = Vector(0, 0, 0)

if sel:
    sel, = sel
    if sel.PickedPoints:
        start_point = sel.PickedPoints[-1]


def line_length(x1=0, y1=0, z1=0, length=10, angle=0):
    x2 = x1 + length * cos(radians(angle))
    y2 = y1 + length * sin(radians(angle))
    z2 = z1
    Draft.makeWire([Vector(x1, y1, z1), Vector(x2, y2, z2)])


for i in range(2):
    length, ok = getDouble(None, "Ouija Central", "Length:")
    if not ok:
        break
        if i == 0:
            break

    angle, ok = getDouble(None, "Ouija Central", "Angle:")
    if not ok:
        break
    
    x1 = y1 = z1 = 0  # Edit coordinate origin
    length *= convert
    line_length(x1, y1, z1, length, angle)

doc.recompute()
jfc4120
Posts: 448
Joined: Sat Jul 02, 2022 11:16 pm

Re: Help with macro cancel

Post by jfc4120 »

@heda the only thing I notice is:

Code: Select all

    length, ok = getDouble(None, "Ouija Central", "Length:")
    if not ok:
        break
        if i == 0:
            break
Only allows one decimal place. But:

Code: Select all

   REPLY = QtGui.QInputDialog.getText(None, "Ouija Central", "Length:")
Allows more decimal places. Why does double not allow more, like 5.75? I can only enter 5.7.
heda
Veteran
Posts: 1348
Joined: Sat Dec 12, 2015 5:49 pm

Re: Help with macro cancel

Post by heda »

qt-docs:
def getDouble (parent, title, label[, value=0[, minValue=-2147483647[, maxValue=2147483647[, decimals=1[, flags=0]]]]])

so

Code: Select all

length, ok = getDouble(None, "Ouija Central", "Length:", decimals=3)
jfc4120
Posts: 448
Joined: Sat Jul 02, 2022 11:16 pm

Re: Help with macro cancel

Post by jfc4120 »

Thanks, where is the documentation for get double? The one I found uses float.
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: Help with macro cancel

Post by openBrain »

jfc4120 wrote: Wed Aug 03, 2022 6:10 pm Thanks, where is the documentation for get double? The one I found uses float.
https://doc-snapshots.qt.io/qtforpython ... .getDouble
heda
Veteran
Posts: 1348
Joined: Sat Dec 12, 2015 5:49 pm

Re: [Solved] Help with macro cancel

Post by heda »

hm, or maybe you are too literal when reading things...
python only has floats, no doubles, however qt is c (and pyside is the py-wrapper around that c), so i guess the function name comes from c-double
in short, anything with a dot is a float in the python world (think one can count on that it's a f64), what the wrapper then translates that to, well, one very seldom needs to bother about that... (unless you want to code in c as well)
Post Reply