Macro Unfold Box

From FreeCAD Documentation
Jump to navigation Jump to search
Other languages:
Deutsch • ‎English • ‎français • ‎italiano • ‎čeština

Macro Unfold Box.png Macro Unfold Box

Description
The macro allows to unfold the surfaces of a box of any shape and to draw them on a page.


Macro version: 1.0.1
Last modified: 2020-03-10
Download: ToolBar Icon
Author
Hervé B.
Download
ToolBar Icon
Links
Macro Version
1.0.1
Date last modified
2020-03-10
FreeCAD Version(s)
Default shortcut
None
See also
None


Description

The macro allows to unfold the surfaces of a box of any shape and to draw them on a page.

Macro unfoldBox1.png

Macro_unfoldBox


Installation

Copy the code file of the macro in the directory :

  • Linux & Mac : $home/.Freecad/Mod/unfoldBox.
  • Windows : C:\Program Files\FreeCAD0.13

Add templates : A3_Landscape_Empty.svg A3_Landscape.svg A4_Landscape_Empty.svg A4_Landscape.svg
Cf Macro for unfolding box surfaces

Options

  1. Scale manual or automatic
  2. Page format: a3/a4, cartridge (cf FreeCAD templates)
  3. Group drawings in the same page as possible.
  4. Sew or not the edges of the pieces.

Instruction for use

  1. Select a box made with Part::Loft tool for example.
  2. Explode it (cf Draft menu) into plan pieces
  3. Select the surfaces
  4. Execute the macro

Script

ToolBar icon Macro Unfold Box.png

Macro_unfoldBox.FCMacro

'''FreeCAD Macro unfoldBox.

Unroll of a ruled surface
'''
#####################################
# SEE https://wiki.freecadweb.org/Macro_Unfold_Box.
# ***************************************************************************
# *                                                                         *
# *   Copyright (c) 2013 - DoNovae/Herve BAILLY <hbl13@donovae.com>         *
# *                                                                         *
# *   This program is free software; you can redistribute it and/or modify  *
# *   it under the terms of the GNU Lesser General Public License (LGPL)    *
# *   as published by the Free Software Foundation; either version 2 of     *
# *   the License, or (at your option) any later version.                   *
# *   for detail see the LICENCE text file.                                 *
# *                                                                         *
# *   This program is distributed in the hope that it will be useful,       *
# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
# *   GNU Library General Public License for more details.                  *
# *                                                                         *
# *   You should have received a copy of the GNU Library General Public     *
# *   License along with this program; if not, write to the Free Software   *
# *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
# *   USA                                                                   *
# *                                                                         *
# ***************************************************************************

import os
import math

import FreeCAD, FreeCADGui, Draft
from PySide import QtGui, QtCore
from FreeCAD import Base
fields_l = []
unroll_l = []

#####################################
# Functions
#####################################


def errorDialog(msg):
    diag = QtGui.QMessageBox(QtGui.QMessageBox.Critical, u'Error Message',msg)
    diag.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
    diag.exec_()


def proceed():
    QtGui.qApp.setOverrideCursor(QtCore.Qt.WaitCursor)

    FreeCAD.Console.PrintMessage('===========================================\n')
    FreeCAD.Console.PrintMessage('unfoldBox: start.\n')
    try:
        file_name = fields_l[0].text()
        scale = float(fields_l[1].text())
        scale_auto = scale_check.isChecked()
        a3 = a3_check.isChecked()
        cartridge = cartridge_check.isChecked()
        onedrawing = onedrawing_check.isChecked()
        sewed = sewed_check.isChecked()
        FreeCAD.Console.PrintMessage('unfoldBox.file_name: '+file_name+'\n')
        FreeCAD.Console.PrintMessage('unfoldBox.scale: '+str(scale)+'\n')
        FreeCAD.Console.PrintMessage('unfoldBox.scale_check: '+str(scale_auto)+'\n')
        FreeCAD.Console.PrintMessage('unfoldBox.a3_check: '+str(a3)+'\n')
        FreeCAD.Console.PrintMessage('unfoldBox.cartridge: '+str(cartridge)+'\n')
        FreeCAD.Console.PrintMessage('unfoldBox.onedrawing: '+str(onedrawing)+'\n')
        FreeCAD.Console.PrintMessage('unfoldBox.sewed: '+str(sewed)+'\n')
    except:
        msg = 'unfoldBox: wrong inputs...\n'
        FreeCAD.Console.PrintError(msg)
        errorDialog(msg)

    QtGui.qApp.restoreOverrideCursor()
    DialogBox.hide()
    #
    # Get selection
    #
    sel = FreeCADGui.Selection.getSelection()
    objnames_l=[]
    grp = FreeCAD.activeDocument().addObject('App::DocumentObjectGroup', str(file_name))
    for objid in range(sel.__len__()):
        obj = Draft.clone(sel[objid])
        grp.addObject(obj)
        objnames_l.append([ obj, sel[objid].Name ])

    unfold = unfoldBox()
    if sewed :
        objnames_l = unfold.done(objnames_l)
        grp.addObject(objnames_l[0][0])
    else:
        for objid in range(objnames_l.__len__()):
            unfold.moveXY(objnames_l[objid][0])

    id_ = 0
    while objnames_l.__len__() > 0:
        draw = Drawing2d(scale, scale_auto, a3, cartridge, onedrawing, FreeCAD.activeDocument().Name, 'Page'+str(id_))
        objnames_l = draw.all_(objnames_l)
        id_ = id_+1
        FreeCAD.Console.PrintMessage('unfoldBox: obj_l= '+str(objnames_l.__len__())+'\n')

    FreeCAD.Console.PrintMessage('unfoldBox: end.\n')
    FreeCAD.Console.PrintMessage('===========================================\n')


def close():
    DialogBox.hide()


class unfoldBox:
    def __init__(self):
        FreeCAD.Console.PrintMessage('unfoldBox.unfoldBox\n')
        self.LIMIT = 0.0001

    def done(self, objnames_l):
        tree_l = self.makeTree(objnames_l)
        for id_ in range(objnames_l.__len__()):
            face = objnames_l[id_]
            self.moveXY(face[0])
        self.sew(objnames_l, tree_l)
        return self.fusion(objnames_l)

    def makeTree(self, objnames_l):
        # Initialisation of tree_l.
        tree_l = []
        for k in range(objnames_l.__len__()):
            facek = objnames_l[k][0]
            facek_l = []
            for i in range(facek.Shape.Edges.__len__()):
                if False and type(facek.Shape.Edges[i].Curve).__name__ != 'GeomLineSegment':
                    facek_l.append([-1, -1])
                else:
                    # Search face link to the ith edge
                    vki0 = facek.Shape.Edges[i].Curve.StartPoint
                    vki1 = facek.Shape.Edges[i].Curve.EndPoint
                    found = False
                    for l in range(k+1, objnames_l.__len__()):
                        facel = objnames_l[l][0]
                        for j in range(facel.Shape.Edges.__len__()):
                            vlj0 = facel.Shape.Edges[j].Curve.StartPoint
                            vlj1 = facel.Shape.Edges[j].Curve.EndPoint
                            if vki0.__eq__(vlj0) and vki1.__eq__(vlj1):
                                arelinked = False
                                isfacek = False
                                isfacel = False
                                for kk in range(k-1):
                                    for ii in range(tree_l[kk].__len__()):
                                        if tree_l[kk][ii][0] == k:
                                            isfacek = True
                                        if tree_l[kk][ii][0] == l:
                                            isfacel = True
                                    if isfacek and isfacel:
                                        arelinked = True
                                        break
                                if not arelinked:
                                    facek_l.append([l, j])
                                    found = True
                                    break
                            if found:
                                break
                if not found:
                    facek_l.append([-1, -1])
            tree_l.append(facek_l)
        return tree_l

    def sew(self, objnames_l, tree_l):
        placed_l = []
        for k in range(tree_l.__len__()):
            iskplaced = False
            for p in range(placed_l.__len__()):
                if placed_l[p] == k:
                    iskplaced = True
            if not iskplaced:
                placed_l.append(k)
            facek = tree_l[k]
            objk = objnames_l[k][0]
            for i in range(facek.__len__()):
                edgeki = facek[i]
                l = edgeki[0]
                j = edgeki[1]
                islplaced = False
                for p in range(placed_l.__len__()):
                    if placed_l[p] == l:
                        islplaced = True
                        break
                if not islplaced:
                    placed_l.append(l)
                if l >= 0 and not (islplaced and iskplaced):
                    iskplaced = True
                    # Move facel.edgelj to facek.edgeki.
                    objl = objnames_l[l][0]
                    vki0 = objk.Shape.Edges[i].Curve.StartPoint
                    vki1 = objk.Shape.Edges[i].Curve.EndPoint
                    vlj0 = objl.Shape.Edges[j].Curve.StartPoint
                    vlj1 = objl.Shape.Edges[j].Curve.EndPoint
                    vk = vki1.sub(vki0)
                    vl = vlj1.sub(vlj0)
                    alpk = vk.getAngle(vl)*180/math.pi
                    alpl = vl.getAngle(vk)*180/math.pi
                    self.isPlanZ(objk)
                    if islplaced:
                        Draft.move(objk, vlj0.sub(vki0))
                    else:
                        Draft.move(objl, vki0.sub(vlj0))
                    self.isPlanZ(objk)

                    if math.fabs(vk.dot(FreeCAD.Base.Vector(-vl.y, vl.x, 0))) > self.LIMIT:
                        if islplaced:
                            Draft.rotate(objk, -alpl, vlj0, self.vecto(vl, vk))
                        else:
                            Draft.rotate(objl, -alpk, vki0, self.vecto(vk, vl))
                    elif vk.dot(vl) < 0:
                        if islplaced:
                            Draft.rotate(objk, 180, vlj0, self.vecto(vl, FreeCAD.Base.Vector(-vl.y, vl.x, 0)))
                        else:
                            Draft.rotate(objl, 180, vki0, self.vecto(vk, FreeCAD.Base.Vector(-vk.y, vk.x, 0)))
                    # Verifications.
                    vki0 = objk.Shape.Edges[i].Curve.StartPoint
                    vki1 = objk.Shape.Edges[i].Curve.EndPoint
                    vlj0 = objl.Shape.Edges[j].Curve.StartPoint
                    vlj1 = objl.Shape.Edges[j].Curve.EndPoint
                    vk = vki1.sub(vki0)
                    vl = vlj1.sub(vlj0)
                    self.isPlanZ(objk)

                    # Flip or not.
                    L = max(objl.Shape.BoundBox.XMax, objk.Shape.BoundBox.XMax) - min(objl.Shape.BoundBox.XMin, objk.Shape.BoundBox.XMin)
                    W = max(objl.Shape.BoundBox.YMax, objk.Shape.BoundBox.YMax) - min(objl.Shape.BoundBox.YMin, objk.Shape.BoundBox.YMin)
                    S1 = L*W
                    if islplaced:
                        Draft.rotate(objk, 180, vlj0, vl)
                    else:
                        Draft.rotate(objl, 180, vki0, vk)
                    L = max(objl.Shape.BoundBox.XMax, objk.Shape.BoundBox.XMax) - min(objl.Shape.BoundBox.XMin, objk.Shape.BoundBox.XMin)
                    W = max(objl.Shape.BoundBox.YMax, objk.Shape.BoundBox.YMax) - min(objl.Shape.BoundBox.YMin, objk.Shape.BoundBox.YMin)
                    S2 = L * W
                    if (S2 <= S1):
                        if islplaced:
                            Draft.rotate(objk, 180, vlj0, vl)
                        else:
                            Draft.rotate(objl, 180, vki0, vk)
                    self.isPlanZ(objk)

    def isPlanZ(self, obj):
        L = obj.Shape.BoundBox.XMax - obj.Shape.BoundBox.XMin
        W = obj.Shape.BoundBox.YMax - obj.Shape.BoundBox.YMin
        H = obj.Shape.BoundBox.ZMax - obj.Shape.BoundBox.ZMin
        if H < self.LIMIT:
            return True
        else:
            return False


    def fusion(self, objnames_l):
        # Init.
        obj_l=[]
        objna_l=[]
        obj0 = objnames_l[0][0];name=objnames_l[0][1]
        objfuse = FreeCAD.activeDocument().addObject('Part::MultiFuse','Unfolding')
        for k in range(objnames_l.__len__()):
            objk = objnames_l[k][0]
            obj_l.append(objk)
        objfuse.Shapes = obj_l
        FreeCAD.activeDocument().recompute()
        objna_l.append([objfuse, name])
        return objna_l

    def get2Vectors(self, shape):
        v0 = FreeCAD.Base.Vector(0, 0, 0)
        v1 = FreeCAD.Base.Vector(0, 0, 0)

        edges= shape.Edges
        for id_ in range(edges.__len__()-1):
            va = edges[id_].Curve.EndPoint.sub(edges[id_].Curve.StartPoint)
            vb = edges[id_+1].Curve.EndPoint.sub(edges[id_+1].Curve.StartPoint)
            if vb.sub(va).Length > v1.sub(v0).Length:
                v0 = self.vect_copy(va);v1=self.vect_copy(vb)
        return [v0, v1]

    def vecto(self, vect1, vect2):
        '''Function vecto.'''
        v= FreeCAD.Base.Vector(0, 0, 0)
        v.x = vect1.y*vect2.z-vect1.z*vect2.y
        v.y = vect1.z*vect2.x-vect1.x*vect2.z
        v.z = vect1.x*vect2.y-vect1.y*vect2.x
        return v

    def vect_copy(self, vect):
        '''Return a copy of vector.'''
        v = vect.add(FreeCAD.Base.Vector(0, 0, 0))
        return v

    def moveXY(self, obj):
        # Move to origin
        Draft.move(obj, FreeCAD.Base.Vector(-obj.Shape.BoundBox.XMin, -obj.Shape.BoundBox.YMin, -obj.Shape.BoundBox.ZMin))

        # Find 2 vectors defining the plan of surface
        tab = self.get2Vectors(obj.Shape)
        v0 = tab[0]
        v1 = tab[1]
        norm = self.vecto(v0, v1)
        norm.normalize()

        # Rotate.
        if math.fabs(norm.x) < self.LIMIT and math.fabs(norm.z) < self.LIMIT:
            Draft.rotate(obj, 90, FreeCAD.Base.Vector(0, 0, 0), FreeCAD.Base.Vector(1, 0, 0))
        elif math.fabs(norm.y) < self.LIMIT and math.fabs(norm.z) < self.LIMIT:
            Draft.rotate(obj, 90, FreeCAD.Base.Vector(0, 0, 0), FreeCAD.Base.Vector(0, 1, 0))
        else:
            # Rotate following the angle to the normal direction of the plan.
            oz= FreeCAD.Base.Vector(0, 0, 1)
            alp = oz.getAngle(norm)*180/math.pi
            Draft.rotate(obj, -alp, FreeCAD.Base.Vector(0, 0, 0), self.vecto(oz, norm))

        # Move to z = 0.
        Draft.move(obj, FreeCAD.Base.Vector(0, 0, -obj.Shape.BoundBox.ZMin))


class Drawing2d:
    def __init__(self, scale, scale_auto, a3, cartridge, onedrawing, drawing_name, page_name):
        """Function __init__

        - scale
        - scale_auto
        - a3
        - cartridge
        - onedrawing
        """
        self.TopX_H = 0
        self.TopY_H = 0
        self.TopX_V = 0
        self.TopY_V = 0
        self.TopX_Hmax = 0
        self.TopY_Hmax = 0
        self.TopX_Vmax = 0
        self.TopY_Vmax = 0
        self.a3 = a3
        self.pts_nbr = 100
        self.scale = scale
        self.scale_auto = scale_auto
        self.cartridge = cartridge
        self.onedrawing = onedrawing
        if self.a3:
            self.L = 420
            self.H = 297
            self.marge = 6
        else:
            self.L = 297
            self.H = 210
            self.marge = 6
        self.page_name = page_name
        self.drawing_name = drawing_name

    def newPage(self):
        freecad_dir = os.getenv('HOME') + '/.FreeCAD/Mod/unfoldBox'
        page = FreeCAD.activeDocument().addObject(
            'Drawing::FeaturePage', self.page_name)
        if self.a3:
            if self.cartridge:
                page.Template = freecad_dir+'/A3_Landscape.svg'
            else:
                page.Template = freecad_dir+'/A3_Landscape_Empty.svg'
        else:
            if self.cartridge:
                page.Template = freecad_dir+'/A4_Landscape.svg'
            else:
                page.Template = freecad_dir+'/A4_Landscape_Empty.svg'
        return page

    def all_(self, objnames_l):
        obj_l = []
        for objid in range(objnames_l.__len__()):
            if objid == 0 or not self.onedrawing:
                self.newPage()
            obj_l.extend(self.done(objid, objnames_l[objid]))
        return obj_l

    def done(self, id_, objname):
        # Init.
        obj_l = []
        obj = objname[0]
        objname = objname[1]
        xmax = obj.Shape.BoundBox.XMax-obj.Shape.BoundBox.XMin
        ymax = obj.Shape.BoundBox.YMax-obj.Shape.BoundBox.YMin
        if ymax > xmax:
            Draft.rotate(obj, 90)
        Draft.move(obj,
                   FreeCAD.Base.Vector(
                       -obj.Shape.BoundBox.XMin, -obj.Shape.BoundBox.YMin, 0))
        xmax = obj.Shape.BoundBox.XMax-obj.Shape.BoundBox.XMin
        ymax = obj.Shape.BoundBox.YMax-obj.Shape.BoundBox.YMin

        scale = min((self.L-4*self.marge) / xmax, (self.H-4*self.marge) / ymax)

        if (not self.scale_auto) or (self.onedrawing):
            scale = self.scale

        if id_ == 0 or not self.onedrawing:
            # Init.
            FreeCAD.Console.PrintMessage('Dawing2d: init\n')
            self.TopX_H = self.marge*2
            self.TopY_H = self.marge*2
            TopX = self.TopX_H
            TopY = self.TopY_H
            self.TopX_H = self.TopX_H + xmax * scale + self.marge
            self.TopY_H = self.TopY_H
            self.TopX_Hmax = max(self.TopX_Hmax, self.TopX_H)
            self.TopY_Hmax = max(self.TopY_Hmax, self.TopY_H + ymax*scale + self.marge)
            self.TopX_Vmax = max(self.TopX_Vmax, self.TopX_Hmax)
            self.TopX_V = max(self.TopX_Vmax, self.TopX_V)
            self.TopY_V = self.marge * 2
        elif self.onedrawing:
            if self.TopX_H + xmax * scale < self.L:
                if self.TopY_H + ymax * scale + self.marge*2 < self.H:
                    # H Add at right on same horizontal line.
                    FreeCAD.Console.PrintMessage('Dawing2d: horizontal\n')
                    TopX = self.TopX_H
                    TopY = self.TopY_H
                    self.TopX_H = self.TopX_H + xmax * scale + self.marge
                    self.TopX_Hmax = max(self.TopX_Hmax, self.TopX_H)
                    self.TopY_Hmax = max(self.TopY_Hmax, self.TopY_H + ymax*scale + self.marge)
                    self.TopX_Vmax = max(self.TopX_Hmax, self.TopX_Vmax)
                    self.TopX_Vmax = max(self.TopX_Vmax, self.TopX_Hmax)
                    self.TopX_V = max(self.TopX_Vmax, self.TopX_V)
                else:
                    #
                    # V Add at right on same horizontal line
                    #
                    FreeCAD.Console.PrintMessage('Dawing2d: vertival\n')
                    if self.TopX_V + ymax * scale + 2 * self.marge < self.L and self.TopY_V + xmax * scale + 2*self.marge < self.H:
                        Draft.rotate(obj, 90)
                        Draft.move(obj, FreeCAD.Base.Vector(-obj.BoundBox.XMin, -obj.BoundBox.YMin, 0))
                        self.TopX_V = max(self.TopX_Vmax, self.TopX_V)
                        TopX = self.TopX_V
                        TopY = self.TopY_V
                        self.TopX_V = self.TopX_V + ymax * scale + self.marge
                        self.TopY_Vmax = max(self.TopY_Vmax, self.TopY_V + xmax * scale + self.marge)
                    else:
                        obj_l.append([obj, 'name'])
                        return obj_l
            else:
                # H Carriage return.
                if (self.TopY_Hmax + ymax * scale + self.marge*2 < self.H):
                    FreeCAD.Console.PrintMessage('Dawing2d: carriage return: '+str(self.TopY_H + ymax * scale)+' > '+str(self.H)+'\n')
                    TopX = self.marge*2
                    TopY = self.TopY_Hmax
                    self.TopX_H = TopX + xmax * scale + self.marge
                    self.TopY_H = TopY
                    self.TopX_Hmax = max(self.TopX_Hmax, self.TopX_H)
                    self.TopY_Hmax = self.TopY_Hmax + ymax*scale+self.marge
                    self.TopX_Vmax = max(self.TopX_Vmax, self.TopX_Hmax)
                    self.TopX_V = max(self.TopX_Vmax, self.TopX_V)
                else:
                    # V Add at right on same horizontal line.
                    FreeCAD.Console.PrintMessage('Dawing2d: vertical: ' + str(self.TopX_V) + ', ' + str(self.TopX_Vmax) + '\n')
                    if self.TopX_V + ymax * scale + 2*self.marge < self.L and self.TopY_V + xmax * scale + 2*self.marge < self.H :
                        Draft.rotate(obj, 90)
                        Draft.move(obj, FreeCAD.Base.Vector(-obj.BoundBox.XMin, -obj.BoundBox.YMin, 0))
                        TopX = self.TopX_V
                        TopY = self.TopY_V
                        self.TopX_V = self.TopX_V + ymax * scale + self.marge
                        self.TopY_Vmax = max(self.TopY_Vmax, self.TopY_V + xmax * scale + self.marge)
                    else:
                        obj_l.append([obj, 'name'])
                        return obj_l

        page = FreeCAD.activeDocument().getObject(self.page_name)

        Text = FreeCAD.activeDocument().addObject('Drawing::FeatureViewAnnotation', objname + '_txt')
        Text.Text = objname
        Text.X = TopX + xmax / 2 * scale
        Text.Y = TopY + ymax / 2 * scale
        Text.Scale = 1

        TopView = FreeCAD.activeDocument().addObject('Drawing::FeatureViewPart', 'TopView')
        TopView.Source = obj
        TopView.Direction = (0.0, 0.0, 1)
        TopView.Rotation = 0
        TopView.X = TopX
        TopView.Y = TopY
        TopView.ShowHiddenLines = True
        TopView.Scale = scale
        page.addObject(TopView)
        page.addObject(Text)
        FreeCAD.activeDocument().recompute()
        return obj_l


#####################################
# Dialog Box
#####################################
fields = [['Group Name', 'Unfolding']]
fields.append(['Scale', '1'])

DialogBox = QtGui.QDialog()
DialogBox.resize(250, 250)
DialogBox.setWindowTitle('unfoldBox')
la = QtGui.QVBoxLayout(DialogBox)

# Input fields.
for id_ in range(len(fields)):
    la.addWidget(QtGui.QLabel(fields[id_][0]))
    fields_l.append(QtGui.QLineEdit(fields[id_][1]))
    la.addWidget(fields_l[id_])

scale_check = QtGui.QCheckBox(DialogBox)
scale_check.setObjectName('checkBox')
scale_check.setChecked(True)
la.addWidget(QtGui.QLabel('Scale auto'))
la.addWidget(scale_check)

a3_check = QtGui.QCheckBox(DialogBox)
a3_check.setObjectName('checkBox')
la.addWidget(QtGui.QLabel('A3 Format'))
a3_check.setChecked(False)
la.addWidget(a3_check)

cartridge_check = QtGui.QCheckBox(DialogBox)
cartridge_check.setObjectName('checkBox')
la.addWidget(QtGui.QLabel('Cartridge'))
cartridge_check.setChecked(False)
la.addWidget(cartridge_check)

onedrawing_check = QtGui.QCheckBox(DialogBox)
onedrawing_check.setObjectName('checkBox')
la.addWidget(QtGui.QLabel('Group drawings in page'))
onedrawing_check.setChecked(True)
la.addWidget(onedrawing_check)

sewed_check = QtGui.QCheckBox(DialogBox)
sewed_check.setObjectName('checkBox')
la.addWidget(QtGui.QLabel('Sewed surfaces'))
sewed_check.setChecked(True)
la.addWidget(sewed_check)

box = QtGui.QDialogButtonBox(DialogBox)

box = QtGui.QDialogButtonBox(DialogBox)
box.setOrientation(QtCore.Qt.Horizontal)
box.setStandardButtons(QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok)
la.addWidget(box)

QtCore.QObject.connect(box, QtCore.SIGNAL('accepted()'), proceed)
QtCore.QObject.connect(box, QtCore.SIGNAL('rejected()'), close)
QtCore.QMetaObject.connectSlotsByName(DialogBox)
DialogBox.show()