Macro View Rotation/es: Difference between revisions

From FreeCAD Documentation
mNo edit summary
(Updating to match new version of source page)
 
(21 intermediate revisions by 3 users not shown)
Line 1: Line 1:
<languages/>
{{Macro/es|Name=View Rotation|Name/es=View Rotation|Description=Esta macro proporciona un interfaz gráfico para girar la vista.|Author=Joe Dowsett|Version=1.0|Date=2012-01-04}}


<div class="mw-translate-fuzzy">
Esta GUI permite girar la vista con mayor precisión que el ratón. La rotación es de acuerdo a los ejes fijados con respecto al usuario y no los objetos, aunque la intención es que los objetos giren aproximadamente sobre sus centros en lugar del centro de la vista.
{{Macro/es
|Name=View Rotation
|Icon=Macro_View_Rotation.png
|Description=Esta macro proporciona un interfaz gráfico para girar la vista.<br />Download the [http://forum.freecadweb.org/download/file.php?id=453 Icon] of the macro.<br />
|Author=Joe Dowsett
|Version=1.0
|Date=2012-01-04
|FCVersion=All
|Download=[http://forum.freecadweb.org/download/file.php?id=453 Icons Package]<br />[https://www.freecadweb.org/wiki/images/a/af/Macro_View_Rotation.png Icon ToolBar]
|SeeAlso=[[Macro_Rotate_View/es|Macro Rotate View]]<br />[[Macro_FCCamera/es|Macro FCCamera]]
}}
</div>


==Description==


<div class="mw-translate-fuzzy">
==Descripción==
Esta GUI permite girar la vista con mayor precisión que el ratón. La rotación es de acuerdo a los ejes fijados con respecto al usuario y no los objetos, aunque la intención es que los objetos giren aproximadamente sobre sus centros en lugar del centro de la vista.<br />
La GUI se muestra en la parte superior derecha de la pantalla, este comportamiento se puede modificar editando
La GUI se muestra en la parte superior derecha de la pantalla, este comportamiento se puede modificar editando
</div>


The GUI defaults to the top right of the screen, this behaviour can be changed by editing.


{{Codeextralink|https://raw.githubusercontent.com/FreeCAD/FreeCAD-macros/master/PureGui/ViewRotation.FCMacro}}

<div class="mw-translate-fuzzy">
[[File:Macro View Rotation 00.png|left|480px|Rotate view]]
[[File:Macro View Rotation 00.png|left|480px|Rotate view]]
{{clear}}
{{clear}}
Se hace referencia a tres iconos para simbolizar las direcciones de rotación. Se puede encontrar un archivo zip que contiene estos iconos [http://forum.freecadweb.org/download/file.php?id=453 here], the images should be placed in the folder containing your macros. Por favor, siéntase libre de contribuir mejores!
{{Code|code=
</div>


<div class="mw-translate-fuzzy">
a = QtGui.QDesktopWidget()
==Script==
right = a.availableGeometry().width()
</div>
self.setGeometry(right-300, 0, 300, 150)
}}


<div class="mw-translate-fuzzy">
La última versión de la macro se encuentra en [https://github.com/FreeCAD/FreeCAD-macros/blob/master/PureGui/ViewRotation.FCMacro ViewRotation.FCMacro] Pero la forma más fácil de instalar esta macro es a través de la [[Std AddonMgr/es|Addon Manager]].
</div>


ToolBar Icon [[Image:Macro_View_Rotation.png]]
al final de la función 'initUI'. Los dos primeros argumentos (derecha-300, 0) proporcionan la posición de la esquina superior izquierda de la ventana - mi experiencia es que el comportamiento es intencionado en Ubuntu pero Vista posiciona la ventana demasiado alta y el 0 necesita cambiarse a ~30.


'''Macro View Rotation.FCMacro'''
{{MacroCode|code=
# -*- coding: utf-8 -*-
#
# FreeCAD macro ViewRotation.
# This GUI allows the view to be rotated with more precision than when using
# the mouse. Rotation is according to axes fixed with respect to the user and
# not the objects, though the aim is that the objects rotate about their
# approximate shared centre rather than the view centre.
# The GUI defaults to the top right of the screen, this behaviour can be
# changed by editing.
# [http://forum.freecadweb.org/viewtopic.php?f=3&t=1784&hilit=View+Rotation#p12012 View+Rotation]


from __future__ import division
Se utilizan tres iconos para representar las direcciones de rotación. Un archivo zip que contiene los tres iconos puede encontrarse [http://forum.freecadweb.org/download/file.php?id=453 aquí], las imágenes deberían estar situadas en la carpeta que contiene las macros. Por favor, eres libre de contribuir con mejoras!


__Name__ = 'View Rotation'
__Comment__ = 'This GUI allows the view to be rotated precisely'
__Author__ = 'Joe Dowsett'
__Version__ = '1.0'
__License__ = 'CC-BY-3.0'
__Web__ = 'https://www.freecadweb.org/wiki/Macro_View_Rotation'
__Wiki__ = 'https://www.freecadweb.org/wiki/Macro_View_Rotation'
__Icon__ = ''
__Help__ = 'Rotation is according to axes fixed with respect to the user.'
__Status__ = ''
__Requires__ = ''
__Files__ = 'ViewRotationOut.png,ViewRotationRight.png,ViewRotationUp.png'


from math import pi
{{Code|code=
import os


import PySide
from PySide import QtCore
from PySide import QtGui, QtCore
from PySide import QtGui
from pivy import coin
from pivy import coin

from math import pi
import FreeCAD as app
import FreeCADGui as gui


def get_macro_dir():
"""Return the directory where macros are located"""
default_macro_dir = os.path.join(app.ConfigGet('UserAppData'), 'Macro')
return app.ParamGet('User parameter:BaseApp/Preferences/Macro').GetString('MacroPath', default_macro_dir)




def find_centre():
def find_centre():
doc = app.activeDocument()
xmax = xmin = ymax = ymin = zmax = zmin = 0
if doc is None:
for obj in App.ActiveDocument.Objects:
return app.Vector(0, 0, 0)
if obj.TypeId[:4] == "Mesh":
box = obj.Mesh.BoundBox
elif obj.TypeId[:6] == "Points":
box = obj.Points.BoundBox
elif obj.TypeId[:4] == "Part":
box = obj.Shape.BoundBox
else:
continue
xmax = max(xmax, box.XMax)
xmin = min(xmin, box.XMin)
ymax = max(ymax, box.YMax)
ymin = min(ymin, box.YMin)
zmax = max(zmax, box.ZMax)
zmin = min(zmin, box.ZMin)


xmax = 0
centre = FreeCAD.Vector((xmax+xmin)/2.0, (ymax+ymin)/2.0, (zmax+zmin)/2.0)
xmin = 0
return centre
ymax = 0
ymin = 0
zmax = 0
zmin = 0
for obj in doc.Objects:
try:
if obj.TypeId[:4] == 'Mesh':
box = obj.Mesh.BoundBox
elif obj.TypeId[:6] == 'Points':
box = obj.Points.BoundBox
elif obj.TypeId[:4] == 'Part':
box = obj.Shape.BoundBox
else:
continue
except AttributeError:
continue
xmax = max(xmax, box.XMax)
xmin = min(xmin, box.XMin)
ymax = max(ymax, box.YMax)
ymin = min(ymin, box.YMin)
zmax = max(zmax, box.ZMax)
zmin = min(zmin, box.ZMin)


return app.Vector((xmax + xmin) / 2, (ymax + ymin) / 2, (zmax + zmin) / 2)




class rotate_gui(QtGui.QWidget):
class RotateGui(QtGui.QWidget):
def __init__(self):
def __init__(self):
super(rotate_gui, self).__init__()
super(RotateGui, self).__init__()
self.initUI()
self.init_ui()
self.initRotate()
self.init_rotate()


def init_ui(self):
macro_dir = get_macro_dir()
self.sliders = []
self.line_edits = []


vbox = QtGui.QVBoxLayout()
def initUI(self):
self.sld = [0,1,2]
self.tbox = [0,1,2]
path = FreeCAD.ConfigGet("UserAppData")
icon = [0,1,2]
icons = ('right.png', 'up.png', 'out.png')


icons = ('ViewRotationRight.png', 'ViewRotationUp.png', 'ViewRotationOut.png')
for i in range(3):
for icon in icons:
self.sld[i] = QtGui.QSlider(QtCore.Qt.Horizontal, self)
slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
self.sld[i].setFocusPolicy(QtCore.Qt.NoFocus)
slider.setFocusPolicy(QtCore.Qt.NoFocus)
self.sld[i].setSingleStep(5)
slider.setSingleStep(5)
self.sld[i].setPageStep(15)
slider.setPageStep(15)
self.sld[i].setValue(0)
slider.setValue(0)
self.sld[i].setMaximum(180)
slider.setMaximum(180)
self.sld[i].setMinimum(-180)
slider.setMinimum(-180)
self.tbox[i] = QtGui.QLineEdit(self)
slider.valueChanged[int].connect(self.valueChange)
self.tbox[i].setText("0")
self.sliders.append(slider)
self.tbox[i].setAlignment(QtCore.Qt.AlignRight)
icon[i] = QtGui.QLabel(self)
icon[i].setPixmap(QtGui.QPixmap(path + icons[i]))
self.sld[i].valueChanged[int].connect(self.valueChange)
self.tbox[i].returnPressed.connect(self.valueEntered)


resetButton = QtGui.QPushButton("Reset")
line_edit = QtGui.QLineEdit(self)
line_edit.setText('0')
resetButton.clicked.connect(self.reset)
line_edit.setAlignment(QtCore.Qt.AlignRight)
line_edit.returnPressed.connect(self.valueEntered)
self.line_edits.append(line_edit)


okButton = QtGui.QPushButton("OK")
label = QtGui.QLabel(self)
label.setPixmap(QtGui.QPixmap(os.path.join(macro_dir, icon)))
okButton.clicked.connect(self.close)


cancelButton = QtGui.QPushButton("Cancel")
hbox = QtGui.QHBoxLayout()
hbox.addWidget(label, 1, QtCore.Qt.AlignCenter)
cancelButton.clicked.connect(self.cancel)
hbox.addWidget(slider, 4)
hbox.addWidget(line_edit, 1)
vbox.addLayout(hbox)


reset_button = QtGui.QPushButton('Reset')
hbox = [0,1,2,3]
reset_button.clicked.connect(self.reset)
vbox = QtGui.QVBoxLayout()


ok_button = QtGui.QPushButton('OK')
for i in range(3):
ok_button.clicked.connect(self.close)
hbox[i] = QtGui.QHBoxLayout()
hbox[i].addWidget(icon[i],1, QtCore.Qt.AlignCenter)
hbox[i].addWidget(self.sld[i],4)
hbox[i].addWidget(self.tbox[i],1)
vbox.addLayout(hbox[i])


hbox[3] = QtGui.QHBoxLayout()
cancel_button = QtGui.QPushButton('Cancel')
cancel_button.clicked.connect(self.cancel)
hbox[3].addWidget(resetButton,1)
hbox[3].addWidget(okButton,1)
hbox[3].addWidget(cancelButton,1)
vbox.addStretch(1)
vbox.addLayout(hbox[3])


hbox = QtGui.QHBoxLayout()
self.setLayout(vbox)
hbox.addWidget(reset_button, 1)
hbox.addWidget(ok_button, 1)
hbox.addWidget(cancel_button, 1)
vbox.addStretch(1)
vbox.addLayout(hbox)


self.setLayout(vbox)
a = QtGui.QDesktopWidget()
right = a.availableGeometry().width()


desktop_widget = QtGui.QDesktopWidget()
self.setGeometry(right-300, 0, 300, 150)
right = desktop_widget.availableGeometry().width()
self.setWindowTitle('Rotate view...')
self.show()


self.setGeometry(right - 300, 0, 300, 150)
self.setWindowTitle('Rotate view')
self.show()


def initRotate(self):
def init_rotate(self):
self.internal = False
self.internal = False
self.current = 0
self.current = 0


self.cam = Gui.ActiveDocument.ActiveView.getCameraNode()
self.cam = gui.activeDocument().ActiveView.getCameraNode()
self.centre = coin.SbVec3f(find_centre())
self.centre = coin.SbVec3f(find_centre())
self.view = self.cam.orientation.getValue()
self.view = self.cam.orientation.getValue()
self.pos = self.cam.position.getValue()
self.pos = self.cam.position.getValue()


#store a copy of the original view to be restored in the case of user selecting Reset or Cancel
# Store a copy of the original view to be restored in the case of user
# selecting Reset or Cancel.
self.original_view = coin.SbRotation(self.view.getValue())
self.original_pos = coin.SbVec3f(self.pos.getValue())
self.original_view = coin.SbRotation(self.view.getValue())
self.original_pos = coin.SbVec3f(self.pos.getValue())


self.config_direction(0)
self.config_direction(0)




def reset(self):
def reset(self):
#reset the view to the original one
# Reset the view to the original one.
self.cam.orientation = self.original_view
self.cam.orientation = self.original_view
self.cam.position = self.original_pos
self.cam.position = self.original_pos
self.internal = True
self.internal = True
for sld in self.sld:
for sld in self.sliders:
sld.setValue(0)
sld.setValue(0)
self.internal = False
self.internal = False
for tbox in self.tbox:
for tbox in self.line_edits:
tbox.setText("0")
tbox.setText("0")
self.config_direction(0)
self.config_direction(0)


def cancel(self):
self.reset()
self.close()


def cancel(self):
self.reset()
self.close()


def config_direction(self, i):
# Evaluate the vectors corresponding to the three directions for the
# current view, and assign the i-th one to self.direction.
self.view = self.cam.orientation.getValue()
self.view = coin.SbRotation(self.view.getValue())
self.pos = self.cam.position.getValue()
self.pos = coin.SbVec3f(self.pos.getValue())


up = coin.SbVec3f(0,1,0)
def config_direction(self, i):
self.up = self.view.multVec(up)
#evaluate the vectors corresponding to the three directions for the current view, and assign the i-th one to self.direction
out = coin.SbVec3f(0,0,1)
self.view = self.cam.orientation.getValue()
self.view = coin.SbRotation(self.view.getValue())
self.out = self.view.multVec(out)
self.pos = self.cam.position.getValue()
u = self.up.getValue()
self.pos = coin.SbVec3f(self.pos.getValue())
o = self.out.getValue()
r = (u[1]*o[2]-u[2]*o[1], u[2]*o[0]-u[0]*o[2], u[0]*o[1]-u[1]*o[0])
self.right = coin.SbVec3f(r)


self.direction = [self.right, self.up, self.out][i]
up = coin.SbVec3f(0,1,0)
self.up = self.view.multVec(up)
out = coin.SbVec3f(0,0,1)
self.out = self.view.multVec(out)
u = self.up.getValue()
o = self.out.getValue()
r = (u[1]*o[2]-u[2]*o[1], u[2]*o[0]-u[0]*o[2], u[0]*o[1]-u[1]*o[0])
self.right = coin.SbVec3f(r)


def check(self, i):
self.direction = [self.right, self.up, self.out][i]
# Check if the direction of rotation has changed, if so then set
# previous slider & textbox to zero, and setup the new direction.
if i != self.current:
self.internal = True
self.sliders[self.current].setValue(0)
self.line_edits[self.current].setText("0")
self.internal = False
self.current = i
self.config_direction(i)


def check(self, i):
def rotate(self, value):
# Carry out the desired rotation about self.direction.
#check if the direction of rotation has changed, if so then set previous slider & textbox to zero, and setup the new direction
val = value*pi/180.0
if i <> self.current:
rot = coin.SbRotation(self.direction, -val)
self.internal = True
nrot = self.view*rot
self.sld[self.current].setValue(0)
prot = rot.multVec(self.pos - self.centre) + self.centre
self.tbox[self.current].setText("0")
self.internal = False
self.cam.orientation = nrot
self.current = i
self.cam.position = prot
self.config_direction(i)


def valueChange(self, value):
# Respond to the change in value of a slider, update the corresponding
# text box, check for a direction change then rotate
# if the value was changed internally, ignore event.
if self.internal:
return


sender = self.sender()
def rotate(self, value):
for i in range(3):
#carry out the desired rotation about self.direction
if sender == self.sliders[i]:
val = value*pi/180.0
break
rot = coin.SbRotation(self.direction, -val)
self.line_edits[i].setText(str(value))
nrot = self.view*rot
self.check(i)
prot = rot.multVec(self.pos - self.centre) + self.centre
self.rotate(value)
self.cam.orientation = nrot
self.cam.position = prot


def valueEntered(self):
# Respond to a value being entered in a text box, updating the
# corresponding slider, check for direction change then rotate.
sender = self.sender()
for i in range(3):
if sender == self.line_edits[i]:
break
value = int(self.line_edits[i].text())
self.internal = True
self.sliders[i].setValue(value)
self.internal = False
self.check(i)
self.rotate(value)


if __name__ == '__main__':
def valueChange(self, value):
# We need to set a variable, otherwise, the dialog doesn't appear.
#respond to the change in value of a slider, update the corresponding text box, check for a direction change then rotate
rotate = RotateGui()
#if the value was changed internally, ignore event.
if self.internal:
return


}}
sender = self.sender()
for i in range(3):
if sender == self.sld[i]:
break
self.tbox[i].setText(str(value))
self.check(i)
self.rotate(value)




==Option==
def valueEntered(self):
#respond to a value being entered in a text box, updating the corresponding slider, check for direction change then rotate
sender = self.sender()
for i in range(3):
if sender == self.tbox[i]:
break
value = int(self.tbox[i].text())
self.internal = True
self.sld[i].setValue(value)
self.internal = False
self.check(i)
self.rotate(value)


<div class="mw-translate-fuzzy">
rotate = rotate_gui()
==Option==
al final de la función 'initUI'. Los dos primeros argumentos (derecha-300, 0) proporcionan la posición de la esquina superior izquierda de la ventana - mi experiencia es que el comportamiento es intencionado en Ubuntu pero Vista posiciona la ventana demasiado alta y el 0 necesita cambiarse a ~30.
</div>


{{Code|code=
self.setGeometry(right-300, 0, 300, 150)
}}
}}
{{clear}}


==Discussion page==
==Forum==
[http://forum.freecadweb.org/viewtopic.php?f=3&t=1784&hilit=View+Rotation#p12012 View+Rotation]


<div class="mw-translate-fuzzy">
<languages/>
==Página de discusión==
[http://forum.freecadweb.org/viewtopic.php?f=3&t=1784&hilit=View+Rotation#p12012 View+Rotation]
</div>

Latest revision as of 16:15, 30 December 2023

View Rotation

Descripción
Esta macro proporciona un interfaz gráfico para girar la vista.
Download the Icon of the macro.


Versión macro : 1.0
Fecha última modificación : 2012-01-04
Versión FreeCAD : All
Descargar : Icons Package
Icon ToolBar
Autor : Joe Dowsett
Autor
Joe Dowsett
Descargar
Icons Package
Icon ToolBar
Enlace
Versión Macro
1.0
Fecha última modificación
2012-01-04
Versión(es) FreeCAD
All
Acceso directo predeterminado
None
Ver también
Macro Rotate View
Macro FCCamera

Description

Descripción

Esta GUI permite girar la vista con mayor precisión que el ratón. La rotación es de acuerdo a los ejes fijados con respecto al usuario y no los objetos, aunque la intención es que los objetos giren aproximadamente sobre sus centros en lugar del centro de la vista.
La GUI se muestra en la parte superior derecha de la pantalla, este comportamiento se puede modificar editando

The GUI defaults to the top right of the screen, this behaviour can be changed by editing.

Temporary code for external macro link. Do not use this code. This code is used exclusively by Addon Manager. Link for optional manual installation: Macro


# This code is copied instead of the original macro code
# to guide the user to the online download page.
# Use it if the code of the macro is larger than 64 KB and cannot be included in the wiki
# or if the RAW code URL is somewhere else in the wiki.

from PySide import QtGui, QtCore

diag = QtGui.QMessageBox(QtGui.QMessageBox.Information,
    "Information",
    "This macro must be downloaded from this link\n"
    "\n"
    "https://raw.githubusercontent.com/FreeCAD/FreeCAD-macros/master/PureGui/ViewRotation.FCMacro" + "\n"
    "\n"
    "Quit this window to access the download page")

diag.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
diag.setWindowModality(QtCore.Qt.ApplicationModal)
diag.exec_()

import webbrowser 
webbrowser.open("https://raw.githubusercontent.com/FreeCAD/FreeCAD-macros/master/PureGui/ViewRotation.FCMacro")


Rotate view
Rotate view

Se hace referencia a tres iconos para simbolizar las direcciones de rotación. Se puede encontrar un archivo zip que contiene estos iconos here, the images should be placed in the folder containing your macros. Por favor, siéntase libre de contribuir mejores!

Script

La última versión de la macro se encuentra en ViewRotation.FCMacro Pero la forma más fácil de instalar esta macro es a través de la Addon Manager.

ToolBar Icon

Macro View Rotation.FCMacro

# -*- coding: utf-8 -*-
#
# FreeCAD macro ViewRotation.
# This GUI allows the view to be rotated with more precision than when using
# the mouse. Rotation is according to axes fixed with respect to the user and
# not the objects, though the aim is that the objects rotate about their
# approximate shared centre rather than the view centre.
# The GUI defaults to the top right of the screen, this behaviour can be
# changed by editing.
# [http://forum.freecadweb.org/viewtopic.php?f=3&t=1784&hilit=View+Rotation#p12012 View+Rotation]

from __future__ import division

__Name__ = 'View Rotation'
__Comment__ = 'This GUI allows the view to be rotated precisely'
__Author__ = 'Joe Dowsett'
__Version__ = '1.0'
__License__ = 'CC-BY-3.0'
__Web__ = 'https://www.freecadweb.org/wiki/Macro_View_Rotation'
__Wiki__ = 'https://www.freecadweb.org/wiki/Macro_View_Rotation'
__Icon__ = ''
__Help__ = 'Rotation is according to axes fixed with respect to the user.'
__Status__ = ''
__Requires__ = ''
__Files__ = 'ViewRotationOut.png,ViewRotationRight.png,ViewRotationUp.png'

from math import pi
import os

from PySide import QtCore
from PySide import QtGui
from pivy import coin

import FreeCAD as app
import FreeCADGui as gui


def get_macro_dir():
    """Return the directory where macros are located"""
    default_macro_dir = os.path.join(app.ConfigGet('UserAppData'), 'Macro')
    return app.ParamGet('User parameter:BaseApp/Preferences/Macro').GetString('MacroPath', default_macro_dir)


def find_centre():
    doc = app.activeDocument()
    if doc is None:
        return app.Vector(0, 0, 0)

    xmax = 0
    xmin = 0
    ymax = 0
    ymin = 0
    zmax = 0
    zmin = 0
    for obj in doc.Objects:
        try:
            if obj.TypeId[:4] == 'Mesh':
                box = obj.Mesh.BoundBox
            elif obj.TypeId[:6] == 'Points':
                box = obj.Points.BoundBox
            elif obj.TypeId[:4] == 'Part':
                box = obj.Shape.BoundBox
            else:
                continue
        except AttributeError:
            continue
        xmax = max(xmax, box.XMax)
        xmin = min(xmin, box.XMin)
        ymax = max(ymax, box.YMax)
        ymin = min(ymin, box.YMin)
        zmax = max(zmax, box.ZMax)
        zmin = min(zmin, box.ZMin)

    return app.Vector((xmax + xmin) / 2, (ymax + ymin) / 2, (zmax + zmin) / 2)


class RotateGui(QtGui.QWidget):
    def __init__(self):
        super(RotateGui, self).__init__()
        self.init_ui()
        self.init_rotate()

    def init_ui(self):
        macro_dir = get_macro_dir()
        self.sliders = []
        self.line_edits = []

        vbox = QtGui.QVBoxLayout()

        icons = ('ViewRotationRight.png', 'ViewRotationUp.png', 'ViewRotationOut.png')
        for icon in icons:
            slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
            slider.setFocusPolicy(QtCore.Qt.NoFocus)
            slider.setSingleStep(5)
            slider.setPageStep(15)
            slider.setValue(0)
            slider.setMaximum(180)
            slider.setMinimum(-180)
            slider.valueChanged[int].connect(self.valueChange)
            self.sliders.append(slider)

            line_edit = QtGui.QLineEdit(self)
            line_edit.setText('0')
            line_edit.setAlignment(QtCore.Qt.AlignRight)
            line_edit.returnPressed.connect(self.valueEntered)
            self.line_edits.append(line_edit)

            label = QtGui.QLabel(self)
            label.setPixmap(QtGui.QPixmap(os.path.join(macro_dir, icon)))

            hbox = QtGui.QHBoxLayout()
            hbox.addWidget(label, 1, QtCore.Qt.AlignCenter)
            hbox.addWidget(slider, 4)
            hbox.addWidget(line_edit, 1)
            vbox.addLayout(hbox)

        reset_button = QtGui.QPushButton('Reset')
        reset_button.clicked.connect(self.reset)

        ok_button = QtGui.QPushButton('OK')
        ok_button.clicked.connect(self.close)

        cancel_button = QtGui.QPushButton('Cancel')
        cancel_button.clicked.connect(self.cancel)

        hbox = QtGui.QHBoxLayout()
        hbox.addWidget(reset_button, 1)
        hbox.addWidget(ok_button, 1)
        hbox.addWidget(cancel_button, 1)
        vbox.addStretch(1)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

        desktop_widget = QtGui.QDesktopWidget()
        right = desktop_widget.availableGeometry().width()

        self.setGeometry(right - 300, 0, 300, 150)
        self.setWindowTitle('Rotate view')
        self.show()

    def init_rotate(self):
        self.internal = False
        self.current = 0

        self.cam = gui.activeDocument().ActiveView.getCameraNode()
        self.centre = coin.SbVec3f(find_centre())
        self.view = self.cam.orientation.getValue()
        self.pos = self.cam.position.getValue()

        # Store a copy of the original view to be restored in the case of user
        # selecting Reset or Cancel.
        self.original_view = coin.SbRotation(self.view.getValue())
        self.original_pos = coin.SbVec3f(self.pos.getValue())

        self.config_direction(0)


    def reset(self):
        # Reset the view to the original one.
        self.cam.orientation = self.original_view
        self.cam.position = self.original_pos
        self.internal = True
        for sld in self.sliders:
            sld.setValue(0)
        self.internal = False
        for tbox in self.line_edits:
            tbox.setText("0")
        self.config_direction(0)

    def cancel(self):
        self.reset()
        self.close()


    def config_direction(self, i):
        # Evaluate the vectors corresponding to the three directions for the
        # current view, and assign the i-th one to self.direction.
        self.view = self.cam.orientation.getValue()
        self.view = coin.SbRotation(self.view.getValue())
        self.pos = self.cam.position.getValue()
        self.pos = coin.SbVec3f(self.pos.getValue())

        up = coin.SbVec3f(0,1,0)
        self.up = self.view.multVec(up)
        out = coin.SbVec3f(0,0,1)
        self.out = self.view.multVec(out)
        u = self.up.getValue()
        o = self.out.getValue()
        r = (u[1]*o[2]-u[2]*o[1], u[2]*o[0]-u[0]*o[2], u[0]*o[1]-u[1]*o[0])
        self.right = coin.SbVec3f(r)

        self.direction = [self.right, self.up, self.out][i]

    def check(self, i):
        # Check if the direction of rotation has changed, if so then set
        # previous slider & textbox to zero, and setup the new direction.
        if i != self.current:
            self.internal = True
            self.sliders[self.current].setValue(0)
            self.line_edits[self.current].setText("0")
            self.internal = False
            self.current = i
            self.config_direction(i)

    def rotate(self, value):
        # Carry out the desired rotation about self.direction.
        val = value*pi/180.0
        rot = coin.SbRotation(self.direction, -val)
        nrot = self.view*rot
        prot = rot.multVec(self.pos - self.centre) + self.centre
        self.cam.orientation = nrot
        self.cam.position = prot

    def valueChange(self, value):
        # Respond to the change in value of a slider, update the corresponding
        # text box, check for a direction change then rotate
        # if the value was changed internally, ignore event.
        if self.internal:
            return

        sender = self.sender()
        for i in range(3):
            if sender == self.sliders[i]:
                break
        self.line_edits[i].setText(str(value))
        self.check(i)
        self.rotate(value)

    def valueEntered(self):
        # Respond to a value being entered in a text box, updating the
        # corresponding slider, check for direction change then rotate.
        sender = self.sender()
        for i in range(3):
            if sender == self.line_edits[i]:
                break
        value = int(self.line_edits[i].text())
        self.internal = True
        self.sliders[i].setValue(value)
        self.internal = False
        self.check(i)
        self.rotate(value)

if __name__ == '__main__':
    # We need to set a variable, otherwise, the dialog doesn't appear.
    rotate = RotateGui()


Option

Option

al final de la función 'initUI'. Los dos primeros argumentos (derecha-300, 0) proporcionan la posición de la esquina superior izquierda de la ventana - mi experiencia es que el comportamiento es intencionado en Ubuntu pero Vista posiciona la ventana demasiado alta y el 0 necesita cambiarse a ~30.

self.setGeometry(right-300, 0, 300, 150)

Forum

Página de discusión

View+Rotation