Manipulator WorkBench

Info about new community or project announcements, implemented features, classes, modules or APIs. Might get technical!
PLEASE DO NOT POST HELP REQUESTS OR OTHER DISCUSSIONS HERE!
User avatar
easyw-fc
Posts: 2796
Joined: Thu Jul 09, 2015 9:34 am

Re: Manipulator WorkBench

Postby easyw-fc » Tue Feb 04, 2020 5:33 pm

Zolko wrote:
Sun Feb 02, 2020 11:36 am
attached. When you measure between 2 links, it actually returns the value of the measurement between the 2 original parts.
it should be now fine ...
could you please test the hdmi branch of the repo?
https://github.com/easyw/Manipulator/tree/hdpi
User avatar
Zolko
Posts: 709
Joined: Mon Dec 17, 2018 10:02 am

Re: Manipulator WorkBench

Postby Zolko » Tue Feb 04, 2020 10:18 pm

easyw-fc wrote:
Tue Feb 04, 2020 5:33 pm
Zolko wrote:
Sun Feb 02, 2020 11:36 am
attached. When you measure between 2 links, it actually returns the value of the measurement between the 2 original parts.
it should be now fine ...
yes it works, well done.

But I definitively don't like the dock window.
try the Assembly4 workbench for FreCAD v0.19
install with Tools > Addon Manager > Assembly4 — tutorials here and here
User avatar
f3nix
Posts: 330
Joined: Sat May 30, 2015 11:58 am

Re: Manipulator WorkBench

Postby f3nix » Thu Feb 06, 2020 5:40 am

easyw-fc wrote:
Tue Feb 04, 2020 2:13 pm
I should have fixed both Aligner and Mover
Could you please test the three widgets?
https://github.com/easyw/Manipulator/tree/hdpi
Hi Maurice.
Everything looks to be much better now.
There are some cosmetic problems I was able to spot:
1. When resized to the smallest size the controls overlap the icons in the Aligner.
2. When resized to the smallest size the labels are not visible in the Aligner and Mover.
3. You have to resize quite a bit horizontally to see full labels.
4. Aligner and Mover stretch its contents too when resized horizontally.

Thanks! :)
Have a good one.

Cheers,
Mateusz
Attachments
a_m_c_resize.png
a_m_c_resize.png (112.19 KiB) Viewed 490 times
a_m_c_min_size.png
a_m_c_min_size.png (97.7 KiB) Viewed 490 times
mario52
Posts: 2847
Joined: Wed May 16, 2012 2:13 pm

Re: Manipulator WorkBench

Postby mario52 » Sat Feb 08, 2020 8:22 pm

hi

example with other organisation (without restriction)

only GUI (ALIGN TOOLS)

Code: Select all

# -*- coding: utf-8 -*-]
#08/02/2020
#mario52 -rmu
#https://forum.freecadweb.org/viewtopic.php?f=9&t=24742&start=120

###
import PySide2
from PySide2 import QtGui ,QtCore, QtWidgets
from PySide2.QtGui import *
from PySide2.QtCore import *
###

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
#        MainWindow.resize(450, 280)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        ####
        #### Section Gui
        ####
        #### #Command
        self.PB_Expand = QtWidgets.QPushButton()
        self.PB_Expand.setObjectName("PB_Expand")
        
        self.PB_Minimize = QtWidgets.QPushButton()
        self.PB_Minimize.setObjectName("PB_Minimize")
        
        self.PB_Help_Tips = QtWidgets.QPushButton()
        self.PB_Help_Tips.setObjectName("PB_Help_Tips")
        
        self.PB_Close = QtWidgets.QPushButton()
        self.PB_Close.setObjectName("PB_Close")

        self.LA_Selection = QtWidgets.QLabel()
        self.LA_Selection.setObjectName("LA_Selection")

        #### #Reference
        self.GB_Reference = QtWidgets.QGroupBox()
        self.GB_Reference.setObjectName("GB_Reference")
        
        self.frame = QtWidgets.QFrame()
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        
        self.RB_Reference_1 = QtWidgets.QRadioButton()
        self.RB_Reference_1.setObjectName("RB_Reference_1")
        
        self.RB_Reference_11 = QtWidgets.QRadioButton()
        self.RB_Reference_11.setObjectName("RB_Reference_11")
        
        ##
        self.frame_2 = QtWidgets.QFrame()
        self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_2.setObjectName("frame_2")
        
        self.RB_Reference_2 = QtWidgets.QRadioButton()
        self.RB_Reference_2.setObjectName("RB_Reference_2")
        
        self.RB_Reference_22 = QtWidgets.QRadioButton()
        self.RB_Reference_22.setObjectName("RB_Reference_22")
        
        #### #Align
        self.GB_Align_On = QtWidgets.QGroupBox()
        self.GB_Align_On.setObjectName("GB_Align_On")
        
        self.RB_Align_3 = QtWidgets.QRadioButton()
        self.RB_Align_3.setObjectName("RB_Align_3")
        
        self.RB_Align_33 = QtWidgets.QRadioButton()
        self.RB_Align_33.setObjectName("RB_Align_33")
        
        self.RB_Align_333 = QtWidgets.QRadioButton()
        self.RB_Align_333.setObjectName("RB_Align_333")
        
        self.CB_Align_1 = QtWidgets.QCheckBox()
        self.CB_Align_1.setObjectName("CB_Align_1")
        
        self.CB_Align_2 = QtWidgets.QCheckBox()
        self.CB_Align_2.setObjectName("CB_Align_2")
        
        self.CB_Align_3 = QtWidgets.QCheckBox()
        self.CB_Align_3.setObjectName("CB_Align_3")

        #### #Controls
        self.GB_Controls = QtWidgets.QGroupBox()
        self.GB_Controls.setObjectName("GB_Controls")
        
        self.PB_Control_1 = QtWidgets.QPushButton()
        self.PB_Control_1.setObjectName("PB_Control_1")
        
        self.PB_Control_2 = QtWidgets.QPushButton()
        self.PB_Control_2.setObjectName("PB_Control_2")
        
        self.PB_Control_3 = QtWidgets.QPushButton()
        self.PB_Control_3.setObjectName("PB_Control_3")
        
        self.CB_Control_1 = QtWidgets.QCheckBox()
        self.CB_Control_1.setObjectName("CB_Control_1")
        
        self.PB_Control_4 = QtWidgets.QPushButton()
        self.PB_Control_4.setObjectName("PB_Control_4")
        
        self.PB_Control_5 = QtWidgets.QPushButton()
        self.PB_Control_5.setObjectName("PB_Control_5")

        ####
        #### creation positions in the Widget begin
        ####
        self.widget = QtWidgets.QWidget(self.centralwidget)
        self.widget.setObjectName("widget")

        grid = QtWidgets.QGridLayout(self.centralwidget)
        grid.addWidget(self.widget)
        
        #### Commande
        grid.addWidget(self.widget, 0, 0, 1 , 2)       #ligne, colonne, ligne case, nombre de cases) = 2 colonnes (Bouton in Widget)
        gridCom = QtWidgets.QGridLayout(self.widget)
        gridCom.addWidget(self.widget, 0, 0)           #ligne, colonne) frame in QGroupBox
        gridCom.addWidget(self.PB_Expand, 0, 0)
        gridCom.addWidget(self.PB_Minimize, 0, 1)
        gridCom.addWidget(self.PB_Help_Tips, 0, 2)
        gridCom.addWidget(self.PB_Close, 0, 3)
        gridCom.addWidget(self.LA_Selection, 0, 4)

        #### Reference
        grid.addWidget(self.GB_Reference, 1, 0)        #ligne, colonne) QGroupBox in Widget
        grid_ = QtWidgets.QGridLayout(self.GB_Reference)
        grid_.addWidget(self.frame, 0, 0)              #ligne, colonne) frame in QGroupBox
        frame_01 = QtWidgets.QGridLayout(self.frame)
        frame_01.addWidget(self.RB_Reference_1, 0, 0)
        frame_01.addWidget(self.RB_Reference_11, 1, 0)

        grid_.addWidget(self.frame_2, 0, 1)            #ligne, colonne) frame in QGroupBox
        frame_02 = QtWidgets.QGridLayout(self.frame_2)
        frame_02.addWidget(self.RB_Reference_2, 0, 0)
        frame_02.addWidget(self.RB_Reference_22, 1, 0)

        #### Align
        grid.addWidget(self.GB_Align_On, 1, 1)         #ligne, colonne) QGroupBox in Widget
        gridAlign = QtWidgets.QGridLayout(self.GB_Align_On)
        gridAlign.addWidget(self.RB_Align_3, 0, 0)
        gridAlign.addWidget(self.RB_Align_33, 1, 0)
        gridAlign.addWidget(self.RB_Align_333, 2, 0)
        gridAlign.addWidget(self.CB_Align_1, 0, 1)
        gridAlign.addWidget(self.CB_Align_2, 1, 1)
        gridAlign.addWidget(self.CB_Align_3, 2, 1)
        gridAlign.addWidget(self.GB_Align_On, 0, 1)

        #### Controls
        grid.addWidget(self.GB_Controls, 2, 0, 1, 2)   #ligne, colonne, ligne case, nombre de cases) = 2 colonnes
        grid1 = QtWidgets.QGridLayout(self.GB_Controls)
        grid1.addWidget(self.PB_Control_1, 0, 0)
        grid1.addWidget(self.PB_Control_2, 0, 1)
        grid1.addWidget(self.PB_Control_3, 0, 2)
        grid1.addWidget(self.PB_Control_4, 0, 4)
        grid1.addWidget(self.PB_Control_5, 1, 0)
        grid1.addWidget(self.CB_Control_1, 0, 3)
        ####
        #### creation position in the Widget end
        ####

        MainWindow.setCentralWidget(self.centralwidget)
        
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 341, 20))
        self.menubar.setObjectName("menubar")
        
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Align Tools"))

        self.GB_Reference.setTitle(_translate("MainWindow", "Reference"))
        self.RB_Reference_1.setText(_translate("MainWindow", "RB_1"))
        self.RB_Reference_11.setText(_translate("MainWindow", "RB_11"))
        self.RB_Reference_2.setText(_translate("MainWindow", "RB_2"))
        self.RB_Reference_22.setText(_translate("MainWindow", "RB_22"))

        self.GB_Align_On.setTitle(_translate("MainWindow", "Align On"))
        self.RB_Align_3.setText(_translate("MainWindow", "RB_3"))
        self.RB_Align_33.setText(_translate("MainWindow", "RB_33"))
        self.RB_Align_333.setText(_translate("MainWindow", "RB_333"))
        self.CB_Align_1.setText(_translate("MainWindow", "CB_1"))
        self.CB_Align_2.setText(_translate("MainWindow", "CB_2"))
        self.CB_Align_3.setText(_translate("MainWindow", "CB_3"))

        self.GB_Controls.setTitle(_translate("MainWindow", "Controls"))
        self.PB_Control_1.setText(_translate("MainWindow", "Control_1"))
        self.PB_Control_2.setText(_translate("MainWindow", "Control_2"))
        self.PB_Control_3.setText(_translate("MainWindow", "Control_3"))
        self.CB_Control_1.setText(_translate("MainWindow", "CB_Control_1"))
        self.PB_Control_4.setText(_translate("MainWindow", "Control_4"))
        self.PB_Control_5.setText(_translate("MainWindow", "Control_5"))

        self.PB_Expand.setText(_translate("MainWindow", "Expand"))
        self.PB_Minimize.setText(_translate("MainWindow", "Minimize"))
        self.PB_Help_Tips.setText(_translate("MainWindow", "Help_Tips"))
        self.PB_Close.setText(_translate("MainWindow", "Close"))
        self.LA_Selection.setText(_translate("MainWindow", "Selection"))


###
if __name__ == "__main__":
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()


mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Dialog creation. My macros on Gist.github.
User avatar
easyw-fc
Posts: 2796
Joined: Thu Jul 09, 2015 9:34 am

Re: Manipulator WorkBench

Postby easyw-fc » Sun Feb 09, 2020 12:57 pm

mario52 wrote:
Sat Feb 08, 2020 8:22 pm
hi

example with other organisation (without restriction)

only GUI (ALIGN TOOLS)

....

mario
Hi Mario
would you mind to share the ui source file?
mario52
Posts: 2847
Joined: Wed May 16, 2012 2:13 pm

Re: Manipulator WorkBench

Postby mario52 » Sun Feb 09, 2020 2:00 pm

hi

but no search the comparaison i have write the code totally handmade (as rmu75 ) much easier(-fc)

QtCreator and the layout my give problem

untitled.ui
(7.82 KiB) Downloaded 13 times
untitled.py
(9.57 KiB) Downloaded 5 times

mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Dialog creation. My macros on Gist.github.
User avatar
Zolko
Posts: 709
Joined: Mon Dec 17, 2018 10:02 am

Re: Manipulator WorkBench

Postby Zolko » Mon Feb 10, 2020 12:35 pm

mario52 wrote:
Sat Feb 08, 2020 8:22 pm
example with other organisation (without restriction)
easyw-fc wrote:
Sun Feb 09, 2020 12:57 pm
would you mind to share the ui source file?
For the simple layout of this tool, is it worth to have a separate UI file ? May-be that's what mario52 had in mind, that the window be drawn directly from the Python file. If you switched to a plain Python-Qt ui, without a separate QtDesigner UI file, we could help you improve this promising tool. In the current state of affairs — with binary icons embedded in the Python file ! — it's not possible.

Also, currently, the measured dimensions are printed to the "Report View", which is quite annoying. Would it be possible to add a text field in the measurement window and print the measured values there ? Like a QtGui.QTextEdit().
try the Assembly4 workbench for FreCAD v0.19
install with Tools > Addon Manager > Assembly4 — tutorials here and here
User avatar
easyw-fc
Posts: 2796
Joined: Thu Jul 09, 2015 9:34 am

Re: Manipulator WorkBench

Postby easyw-fc » Mon Feb 10, 2020 8:47 pm

Zolko wrote:
Mon Feb 10, 2020 12:35 pm
For the simple layout of this tool, is it worth to have a separate UI file ?
The external ui file is just the Gui and it is converted to .py, before it is inserted inside the python code.
Zolko wrote:
Mon Feb 10, 2020 12:35 pm
May-be that's what mario52 had in mind, that the window be drawn directly from the Python file.
Mario is suggesting to code directly the Gui in python to avoid possibly QtDesigner/QtCreator converting issue.. he does not rely much on the quality of QtCreator ...
Zolko wrote:
Mon Feb 10, 2020 12:35 pm
If you switched to a plain Python-Qt ui, without a separate QtDesigner UI file, we could help you improve this promising tool.
It is already in this state... my Tools are just a single python file each, within all the python source inside.
The 'ui' source code is just an helper in creating the Gui with graphical aids.
Zolko wrote:
Mon Feb 10, 2020 12:35 pm
In the current state of affairs — with binary icons embedded in the Python file ! — it's not possible.
Which is the issue in having the svg icons embedded inside the code?
They are just referred as an internal name, so this is not even touching the ui tools code...
Zolko wrote:
Mon Feb 10, 2020 12:35 pm
Also, currently, the measured dimensions are printed to the "Report View", which is quite annoying. Would it be possible to add a text field in the measurement window and print the measured values there ? Like a QtGui.QTextEdit().
This is a point of view... IMO it is much cluttering adding a measure window to the tools ... The Report View can just be maintained closed (hidden) by the user choice...
User avatar
Zolko
Posts: 709
Joined: Mon Dec 17, 2018 10:02 am

Re: Manipulator WorkBench

Postby Zolko » Mon Feb 10, 2020 9:23 pm

easyw-fc wrote:
Mon Feb 10, 2020 8:47 pm
Zolko wrote:
Mon Feb 10, 2020 12:35 pm
May-be that's what mario52 had in mind, that the window be drawn directly from the Python file.
Mario is suggesting to code directly the Gui in python to avoid possibly QtDesigner/QtCreator converting issue.. he does not rely much on the quality of QtCreator ...
I agree with him. See, we're 2 to be of that opinion. May-be it's worth considering ?

Zolko wrote:
Mon Feb 10, 2020 12:35 pm
If you switched to a plain Python-Qt ui, without a separate QtDesigner UI file, we could help you improve this promising tool.
It is already in this state
...
The 'ui' source code is just an helper in creating the Gui with graphical aids.
...
Which is the issue in having the svg icons embedded inside the code?
how do you generate the embedded icons ?

The Report View can just be maintained closed (hidden) by the user choice...
...and needs to be closed each time the user has finished measuring. It's illogical, messy, difficult to read, error-prone... An embedded text field that serves only that purpose — the UNIX way-of-life — is what all other CAD systems do. The report view should only serve for error messages. Not even for warnings. And certainly not as a regular user interface. There is plenty of empty space in the dock window, why not make use of it ? You might want to look at the attached example.

As I said: you have done the most difficult, technical, part, why not listen to other users for the user interactivity part ?
Measure_T-Flex.png
Measure_T-Flex.png (258.26 KiB) Viewed 183 times
try the Assembly4 workbench for FreCAD v0.19
install with Tools > Addon Manager > Assembly4 — tutorials here and here
User avatar
easyw-fc
Posts: 2796
Joined: Thu Jul 09, 2015 9:34 am

Re: Manipulator WorkBench

Postby easyw-fc » Mon Feb 10, 2020 9:57 pm

Zolko wrote:
Mon Feb 10, 2020 9:23 pm
easyw-fc wrote:
Mon Feb 10, 2020 8:47 pm
Mario is suggesting to code directly the Gui in python to avoid possibly QtDesigner/QtCreator converting issue.. he does not rely much on the quality of QtCreator ...
I agree with him. See, we're 2 to be of that opinion. May-be it's worth considering ?
May be, but writing the Gui directly in python is much more time consuming compared to designing it directly in a graphical environment ... like OSX vs DOS ... IMO... :D
Zolko wrote:
Mon Feb 10, 2020 9:23 pm
easyw-fc wrote:
Mon Feb 10, 2020 8:47 pm
It is already in this state
...
The 'ui' source code is just an helper in creating the Gui with graphical aids.
...
Which is the issue in having the svg icons embedded inside the code?
how do you generate the embedded icons ?
you can get a tip from the tools code:

Code: Select all

####################################
# embedded button images
import base64
# "b64_data" is a variable containing your base64 encoded jpeg/svg
and from G
https://www.google.com/search?&q=python ... +svg+image
i.e.
https://stackoverflow.com/questions/637 ... a-css-file

Code: Select all

import base64
encoded = base64.b64encode(open("filename.png", "rb").read())
and in my previous post the decode option
The Report View can just be maintained closed (hidden) by the user choice...
Zolko wrote:
Mon Feb 10, 2020 9:23 pm
...and needs to be closed each time the user has finished measuring. It's illogical, messy, difficult to read, error-prone... An embedded text field that serves only that purpose — the UNIX way-of-life — is what all other CAD systems do. The report view should only serve for error messages. Not even for warnings. And certainly not as a regular user interface. There is plenty of empty space in the dock window, why not make use of it ? You might want to look at the attached example.
You miss two points:
1) Caliper already adds new objects to the FC files a) the dimensions with a value related to the measure b) an optional Label with all the three values dx, dy, dz...
2) Report View message is only mirroring what is already offered in the FC file, and it is a friendly helper IMO (i.e. to directly copy values to a calculator or a file).
Zolko wrote:
Mon Feb 10, 2020 9:23 pm
As I said: you have done the most difficult, technical, part, why not listen to other users for the user interactivity part ?
do you really think I'm not listening to users? Even looking at the 13 pages of this thread?