Beschreibung |
---|
Verwende dieses Makro, um Bildschirmfotos im FreeCAD-Forum zu veröffentlichen. Am besten füge dieses Makro zu deiner globalen benutzerdefinierten Makro-Werkzeugleiste hinzu, damit du schnell und einfach darauf zugreifen kannst. Wenn du im FreeCAD-Forum veröffentlichst, ist es oft nützlich, Bildschirmfotos einbinden zu können. Das Problem ist, dass dies eine etwas mühsame Aufgabe ist. Dieses Makro soll diese Aufgabe etwas erleichtern. Das Makro kann Bildschirmfotos machen oder es kann vorhandene Bildschirmfotos verwenden, die bereits in die Zwischenablage des Systems kopiert wurden. Um das bereits in der Zwischenablage befindliche Bild zu umgehen, drücke die Umschalttaste, während du das Makro aufrufst. Um das Makro zur Aufnahme des Bildschirmfotos zu verwenden, passe die Größe und Platzierung des eingeblendeten Dialogfelds an, und klicke dann auf OK. Wenn du auf OK klickst, versucht das Makro, ein Bildschirmfoto des vom Dialogfeld abgedeckten Bildschirmbereichs zu erstellen. Das Dialogfeld selbst ist halbtransparent, so dass du den Inhalt darunter sehen kannst. Versionsmakro : 1.3 Datum der letzten Änderung : 2024.07.23 FreeCAD version : Alle Herunterladen : ToolBar Icon Autor: TheMarkster |
Autor |
TheMarkster |
Herunterladen |
ToolBar Icon |
Links |
Makros Rezepte Wie installiere ich Makros So passen Sie Symbolleisten an |
Macro-Version |
1.3 |
Datum der letzten Änderung |
2024.07.23 |
FreeCAD-Version(s) |
Alle |
Standardverknüpfung |
Unter Windows: Windows Key + Shift + S Unter Mac: Command + Shift + 4 |
Siehe auch |
Macro Copy3DViewToClipboard, Macro Screen Wiki |
Verwende dieses Makro, um Bildschirmfotos auf einfache Weise im FreeCAD Forum zu veröffentlichen.
Am besten füge dieses Makro zu deiner globalen benutzerdefinierten Makro Werkzeugleiste hinzu, damit du schnell und einfach darauf zugreifen kannst.
Beim Veröffentlichen im FreeCAD-Forum ist es oft nützlich, Bildschirmfotos beifügen zu können. Das Problem ist, dass dies eine etwas mühsame Aufgabe ist. Dieses Makro soll diese Aufgabe daher etwas erleichtern.
Das Makro kann Bildschirmfotos erstellen oder vorhandene Bildschirmfotos verwenden, die bereits in die Zwischenablage des Systems kopiert wurden. Um das bereits in der Zwischenablage befindliche Bild zu umgehen, drücke die Taste Umschalten, während du das Makro aufrufst. Um das Makro zur Aufnahme des Bildschirmfotos zu verwenden, passe die Größe und Platzierung des eingeblendeten Dialogfelds an und klicke dann auf OK. Wenn du auf OK klickst, versucht das Makro, ein Bildschirmfoto des vom Dialogfeld abgedeckten Bildschirmbereichs zu erstellen. Das Dialogfeld selbst ist halbtransparent, so dass du den Inhalt darunter sehen kannst.
Beachte den halbtransparenten Dialog. Es wird nur der Bildschirminhalt unterhalb des Dialogs erfasst.
Nach dem Klicken auf OK erstellt das Makro dann das Bildschirmfoto und speichert es in einer temporären Datei. Am Speicherort der Datei wird dann ein Datei Öffnen Dialogfeld geöffnet. Du kannst die Datei von dort in das Forum ziehen und loslassen im Textbereich, wo du deinen Text für deinen Forumsbeitrag eingibst. Bei Abbruch des Dialogs wird die temporäre Bildschirmfoto-Datei automatisch gelöscht. Du könntest die Bildschirmfotodatei auch in deiner Standardanwendung öffnen, die zum Öffnen von .png-Dateien installiert ist (unter Windows ist dies typischerweise Paint). Dies kann nützlich sein, wenn du dem Bildschirmfoto einige Anmerkungen hinzufügen oder vielleicht zusätzliche Bearbeitungen, wie z.B. Zuschneiden, vornehmen möchtest.
Dies ist der Dateiöffnungsdialog, der nach der Aufnahme des Bildschirmfotos automatisch aufklappt. Das Bild kann in das Forum gezogen und losgelassen werden oder es kann zur weiteren Bearbeitung in deiner System-Standardanwendung zum Öffnen von .png-Dateien geöffnet werden. Alternativ dazu kannst du auf das Bild rechtsklicken und Öffnen mit.. mit einer anderen Anwendung deiner Wahl öffnen.
Wenn das Makro auf deinem System nicht funktioniert, um Bildschirmfotos zu erstellen, kann es trotzdem nützlich sein für Bildschirmfotos, die du mit anderen Werkzeugen erstellt hast. Kopiere das Bildschirmfoto einfach in die Zwischenablage und führe dann das Makro aus. Das Makro erstellt die temporäre Datei und öffnet das Verzeichnis der Datei in einem Datei Öffnen Dialog für dich. Einige andere Werkzeuge zum Erstellen von Bildschirmfotos:
Das Makro unterstützt Benutzerparameter, die mit Werkzeuge → Parameter bearbeiten... → Plugins → Snip_Macro
LastX
, LastY
, LastWidth
, LastHight
: Lage und Größe des zuletzt verwendeten Snip-RahmensWindowOpacity
(0.85): ein Wert zwischen 0.0 (weniger durchsichtig) und 1.0 (durchsichtiger)SnipDelay
(0.5): Zeitverzögerung (in Sekunden) zwischen schliessen des Snip-Rahmens und der AufnahmeDesiredWidth
(0): gewünschte Breite (in Pixeln), wird ignoriert, wenn 0 -- skaliert die Aufnahme auf die gewünschte Größe unter Beibehaltung des Seitenverhältnisses.ScaleFactor
(1.0): gewünschter Größenfaktor, (überschreibt die gewünsche Breite, wenn der ScaleFactor nicht 1.0 ist) -- skaliert die Aufnahme dem Größenfaktor entsprechendDie Last
-Parameter werden von dem Makro bei jeder Ausführung zurückgesetzt. So wird festgehalten, wo das Snip-Fenster zu platzieren ist, d.h. an der Stelle, an der es sich zuletzt befand, als der Benutzer ein Bildschirmfoto gemacht hat.
Der Parameter WindowOpacity
ist die Durchsichtigkeit des Snip-Rahmens.
Der Parameter SnipDelay
(Aufnahmeverzögerung) kann angepasst werden, um die Dinge etwas zu beschleunigen, aber wenn der Wert zu klein ist, könnte das aufgenommene Bildschirmfoto den Snip-Rahmen selbst enthalten, weil vor der Aufnahme des Bildschirmfotos eine gewisse Zeitspanne zum Schließen des Dialogs benötigt wird.
Der Parameter DesiredWidth
(gewünschte Breite) skaliert die Abbildung auf die gewünschte Breite, solange er nicht 0 ist (Standardwert); in dem Falle wird gar nicht skaliert. Wird z.B. die gewünschte Breite auf 800 gesetzt, erhält man Bilder die 800 Pixel breit sind. Die Höhe wird automatisch so angepasst, dass das aktuelle Seitenverhältnis erhalten bleibt. War die originale Abbildung 1600x1200 und DesiredWidth ist 800, wird das resultierende Bild 800x600 sein.
DerParameter ScaleFactor
(Größenfaktor) skaliert die Abbildung auf das gewünscht Verhältnis, z.B. 0,5. Der Standardwert ist 1,0; in diesem Falle wird gar nicht skaliert. Dieser Überschreibt den Parameter DesiredWidth, wenn ScaleFactor nicht 1.0 ist.
Das Skalieren kann übersprungen werden, wenn die Ctrl-Taste gedrückt gehalten wird, während die Schaltfläche OK angeklickt wird, um das Bildschirmfoto aufzunehmen.
Macro_Snip.FCMacro
# -*- coding: utf-8 -*- """ *************************************************************************** * Copyright (c) 2019 <TheMarkster> * * * * This file is a supplement to the FreeCAD CAx development system. * * * * 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. * * * * This software 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 at http://www.gnu.org/licenses * * for more details. * * * * For more information about the GNU Library General Public License * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307 USA * * * *************************************************************************** """ """ Snip Macro This is a macro to make it easier to post screenshots to the FreeCAD forum. The forum supports a drag and drop interface -- just drag and drop an image to the textarea where you type in your post. But it still requires many tedious steps. This macro is to reduce some of those steps. You should add the macro to your custom macro toolbar to save as many clicks as possible. The first thing the macro does is to check if there is an image already saved to the system clipboard, and if so, it uses that one. To bypass the clipboard, press Shift while invoking the macro. """ __title__ = "Snip" __author__ = "TheMarkster" __url__ = "" __Wiki__ = "" __date__ = "2024.07.23" __version__ = 1.3 import FreeCAD from PySide import QtGui,QtCore import uuid import time import tempfile, os, shutil # class SnipBox(QtGui.QDialog): # def __init__(self, scale, desired_width): # QtGui.QDialog.__init__(self) # self.scale = scale # self.desired_width = desired_width # # self.detailsTextEdit = QtGui.QTextEdit("Details") # self.Details = QtGui.QPushButton("Details") # self.Scaling = QtGui.QPushButton("Scaling") # self.Details.clicked.connect(self.onDetailsClicked) # self.Scaling.clicked.connect(self.onScalingClicked) # layout = QtGui.QVBoxLayout() # layout.addWidget(self.detailsTextEdit) # layout.addStretch() # buttons = QtGui.QDialogButtonBox( # QtGui.QDialogButtonBox.Ok, # QtCore.Qt.Horizontal, self) # buttons.accepted.connect(self.accept) # buttons.rejected.connect(self.reject) # buttons.addButton(self.Details, QtGui.QDialogButtonBox.ActionRole) # buttons.addButton(self.Scaling, QtGui.QDialogButtonBox.ActionRole) # buttons.setCenterButtons(True) # layout.addWidget(buttons) # self.setLayout(layout) # self.detailsTextEdit.setVisible(False) # # def setDetailedText(self, txt): # self.detailsTextEdit.setText(txt) # # def setTitle(self, rectwidth, rectheight): # if self.scale != 1.0: # out_width = rect.width()*scale_factor # elif self.desired_width != 0: # out_width = desired_width # self.setWindowTitle(f"Snip macro v{__version__} {rectwidth} x {rectheight} output width {out_width}") # # # def onDetailsClicked(self): # self.detailsTextEdit.setVisible(not self.detailsTextEdit.isVisible()) # # def onScalingClicked(self): # pass # # def event(self, e): #credit serge_gubenko of stackoverflow for this # result = QtGui.QDialog.event(self, e) # self.setMinimumHeight(0) # self.setMaximumHeight(16777215) # self.setMinimumWidth(0) # self.setMaximumWidth(16777215) # self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) # textEdit = self.findChild(QtGui.QTextEdit) # if textEdit != None : # textEdit.setMinimumHeight(0) # textEdit.setMaximumHeight(16777215) # textEdit.setMinimumWidth(0) # textEdit.setMaximumWidth(16777215) # textEdit.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) # #thanks to mario52 for this # if result == True: # try: # rect = mb.frameGeometry() # rectwidth = rect.width() # rectheight = rect.height() # mb.setTitle(rectwidth,rectheight) # # except Exception: # None # ############## # return result class SnipBox(QtGui.QDialog): def __init__(self, scale, desired_width): QtGui.QDialog.__init__(self) self.pg = FreeCAD.ParamGet("User parameter:Plugins/Snip_Macro") self.scale = scale self.desired_width = desired_width self.detailsTextEdit = QtGui.QTextEdit("Details") self.Details = QtGui.QPushButton("Details") self.Scaling = QtGui.QPushButton("Scaling") self.Details.clicked.connect(self.onDetailsClicked) self.Scaling.clicked.connect(self.onScalingClicked) layout = QtGui.QVBoxLayout() layout.addWidget(self.detailsTextEdit) layout.addStretch() # Scaling widgets self.scaleLabel = QtGui.QLabel("Scale:") self.scaleSpinBox = QtGui.QDoubleSpinBox() self.scaleSpinBox.setDecimals(2) self.scaleSpinBox.setSingleStep(0.1) self.scaleSpinBox.setValue(self.scale) self.scaleSpinBox.valueChanged.connect(self.updateScale) self.fixedWidthLabel = QtGui.QLabel("Fixed Width:") self.fixedWidthSpinBox = QtGui.QSpinBox() self.fixedWidthSpinBox.setRange(0, 10000) self.fixedWidthSpinBox.setValue(self.desired_width) self.fixedWidthSpinBox.valueChanged.connect(self.updateDesiredWidth) self.scaleLayout = QtGui.QVBoxLayout() self.scaleText = QtGui.QLabel("Scale values other than 1.0 will override fixed width setting") self.scaleLayout.addWidget(self.scaleText) scaleHBox1 = QtGui.QHBoxLayout() scaleHBox1.addWidget(self.scaleLabel) scaleHBox1.addWidget(self.scaleSpinBox) scaleHBox2 = QtGui.QHBoxLayout() scaleHBox2.addWidget(self.fixedWidthLabel) scaleHBox2.addWidget(self.fixedWidthSpinBox) self.scaleLayout.addLayout(scaleHBox1) self.scaleLayout.addLayout(scaleHBox2) self.scaleWidget = QtGui.QWidget() self.scaleWidget.setLayout(self.scaleLayout) self.scaleWidget.setVisible(False) layout.addWidget(self.scaleWidget) buttons = QtGui.QDialogButtonBox( QtGui.QDialogButtonBox.Ok, QtCore.Qt.Horizontal, self) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) buttons.addButton(self.Details, QtGui.QDialogButtonBox.ActionRole) buttons.addButton(self.Scaling, QtGui.QDialogButtonBox.ActionRole) buttons.setCenterButtons(True) layout.addWidget(buttons) self.setLayout(layout) self.detailsTextEdit.setVisible(False) def setDetailedText(self, txt): self.detailsTextEdit.setText(txt) def setTitle(self, rectwidth, rectheight): if self.scale != 1.0: out_width = rectwidth * self.scale elif self.desired_width != 0: out_width = self.desired_width self.setWindowTitle(f"Snip macro v{__version__} {rectwidth} x {rectheight} output width {out_width}") def onDetailsClicked(self): if self.scaleWidget.isVisible(): self.scaleWidget.setVisible(False) self.detailsTextEdit.setVisible(not self.detailsTextEdit.isVisible()) def onScalingClicked(self): if self.detailsTextEdit.isVisible(): self.detailsTextEdit.setVisible(False) self.scaleWidget.setVisible(not self.scaleWidget.isVisible()) def updateScale(self, value): self.scale = value self.pg.SetFloat("ScaleFactor", self.scale) def updateDesiredWidth(self, value): self.desired_width = value self.pg.SetInt("DesiredWidth", self.desired_width) def event(self, e): #credit serge_gubenko of stackoverflow for this result = QtGui.QDialog.event(self, e) self.setMinimumHeight(0) self.setMaximumHeight(16777215) self.setMinimumWidth(0) self.setMaximumWidth(16777215) self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) textEdit = self.findChild(QtGui.QTextEdit) if textEdit != None : textEdit.setMinimumHeight(0) textEdit.setMaximumHeight(16777215) textEdit.setMinimumWidth(0) textEdit.setMaximumWidth(16777215) textEdit.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) #thanks to mario52 for this if result == True: try: rect = mb.frameGeometry() rectwidth = rect.width() rectheight = rect.height() mb.setTitle(rectwidth,rectheight) except Exception: None ############## return result def get_screen_for_widget(widget): screen_geometry = widget.geometry() for screen in QtGui.QApplication.screens(): if screen.geometry().contains(screen_geometry.center()): return screen def get_widget_screen_coordinates(widget): screen = get_screen_for_widget(widget) widget_geometry = widget.geometry() screen_geometry = screen.geometry() return QtCore.QRect(widget_geometry.x() - screen_geometry.x(), widget_geometry.y() - screen_geometry.y(), widget_geometry.width(), widget_geometry.height()) pg = FreeCAD.ParamGet("User parameter:Plugins/Snip_Macro") #parameters were originally in BaseApp, but should be in Plugins, so relocate if necessary if FreeCAD.ParamGet("User parameter:BaseApp/Preferences").HasGroup("Snip_Macro"): deprecated = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Snip_Macro") pg.SetInt("LastX",deprecated.GetInt("LastX",0)) pg.SetInt("LastY",deprecated.GetInt("LastY",0)) pg.SetInt("LastWidth",deprecated.GetInt("LastWidth",0)) pg.SetInt("LastHeight",deprecated.GetInt("LastHeight",0)) pg.SetFloat("WindowOpacity",deprecated.GetFloat("WindowOpacity",0.85)) pg.SetFloat("SnipDelay",deprecated.GetFloat("SnipDelay",0.5)) FreeCAD.ParamGet("User parameter:BaseApp/Preferences").RemGroup("Snip_Macro") desired_width = pg.GetInt("DesiredWidth",0) #used for scaling to desired width, maintaining aspect ratio pg.SetInt("DesiredWidth", desired_width) scale_factor = pg.GetFloat("ScaleFactor", 1.0) #scale by scale factor instead of desired width pg.SetFloat("ScaleFactor", scale_factor) skipClipboard = False modifiers = QtGui.QApplication.keyboardModifiers() if modifiers == QtCore.Qt.ShiftModifier: skipClipboard = True userCanceled = False fname = "Snip macro screenshot-"+str(uuid.uuid4())[:6]+".png" image = None if not skipClipboard: clip = QtGui.QClipboard() image = clip.image(QtGui.QClipboard.Clipboard) if not image: #use our own screen grabber mb = SnipBox(scale_factor, desired_width) details = """ Move and resize this box to cover the part of the screen you wish to grab. If it succeeds an open file dialog will appear. Drag and drop the file from the open file dialog to the forum. The file will be deleted after you close the dialog. If this fails you can still use this macro to handle screenshots you copied to the clipboard using other tools: Windows snip tool: Window Key + Shift + S Mac snip tool: Command + Shift + 4 Linux: gnome-screenshot utility If the macro finds there is already an image copied to the clipboard it uses that image instead of bringing up this dialog. Press Shift while invoking this macro to bypass the clipboard. Alternatively, you can clear the image from the clipboard by copying some text to it. The Open button will open the file in the system default application for handling png files, e.g. Paint in windows. This can be useful if you wish to annotate the screenshot. But most of the time you will simply want to drag and drop the file to the forum, then Cancel to close the open file dialog afterwards. If you wish to open the screenshot file with another application, right-click the file and select open with... option or drag/drop to that other application. User Parameters: These can be accessed via Tools menu -> Edit Parameters in Plugins -> Snip_Macro: LastX, LastY, LastWidth, LastHeight -- location and size of snip box last use WindowOpacity (0.85) -- value between 0.0 (less opaque) and 1.0 (more opaque) SnipDelay (0.5) -- time (in seconds) delay between snip box close and snip DesiredWidth -- image will be scaled to this width (unless it is 0) maintaining current aspect ratio. ScaleFactor -- float value, e.g. 0.5 -- image will be scaled to that scale factor. Note: ScaleFactor (if not 1.0) will take precedence over DesiredWidth Hold down Ctrl key to ignore scaling. The SnipDelay parameter can be adjusted to speed things up a bit, but if it is too small the screenshot taken might include the snip box itself because we need to wait for it to close before taking the screenshot. """ # mb.setWindowTitle("Snip macro v"+str(__version__)) mb.setDetailedText(details) if pg.GetFloat("WindowOpacity",0.85) == 0.85: pg.SetFloat("WindowOpacity",0.85) mb.setWindowOpacity(pg.GetFloat("WindowOpacity",0.85)) lastX = pg.GetInt("LastX",0) lastY = pg.GetInt("LastY",0) lastWidth = pg.GetInt("LastWidth",100) lastHeight = pg.GetInt("LastHeight",100) mb.setGeometry(lastX, lastY, lastWidth, lastHeight) mb.resize(lastWidth, lastHeight) mb.setWindowFlags(QtCore.Qt.Tool) result = mb.exec_() if not result: userCanceled = True if not userCanceled: clientRect = mb.geometry() scale_factor = mb.scale desired_width = mb.desired_width rect = get_widget_screen_coordinates(mb) diff = rect.height()-clientRect.height() pg.SetInt("LastX", rect.x()) pg.SetInt("LastY", rect.y()) pg.SetInt("LastWidth", rect.width()) pg.SetInt("LastHeight", rect.height()-diff) QtGui.QApplication.processEvents() snipDelay = pg.GetFloat("SnipDelay", 0.5) if snipDelay == 0.5: pg.SetFloat("SnipDelay", 0.5) time.sleep(snipDelay) #give time for dialog to close before taking screenshot QtGui.QApplication.processEvents() if hasattr(QtGui.QApplication,"primaryScreen"): #screen = QtGui.QApplication.primaryScreen() screen = get_screen_for_widget(mb) image = screen.grabWindow(0,rect.x(),rect.y(),rect.width(),rect.height()).toImage() else: long_qdesktop_id = QtGui.QApplication.desktop().winId() image = QtGui.QPixmap.grabWindow(long_qdesktop_id, rect.x(), rect.y(), rect.width(), rect.height()).toImage() if not image: raise Exception("Snip Macro Error: Unable to grab screen image\n") modifiers = QtGui.QApplication.keyboardModifiers() skipScaling = False if modifiers == QtCore.Qt.ControlModifier: skipScaling = True if not skipScaling: if scale_factor != 1.0: image = image.smoothScaled(rect.width()*scale_factor, rect.height()*scale_factor) elif desired_width != 0: image = image.smoothScaled(desired_width, rect.height()*float(desired_width)/float(rect.width())) if not userCanceled: dirPath = tempfile.mkdtemp() filePath = dirPath + os.path.sep + fname image.save(filePath) fileName = QtGui.QFileDialog.getOpenFileName(QtGui.QApplication.activeWindow(), "Drag the image to the forum, then Cancel will delete the temporary file", dirPath, "PNG (*.png)") if fileName[0]: #user selected Open or double-clicked file import subprocess, os, platform if platform.system() == 'Darwin': # macOS subprocess.call(('open', fileName[0])) elif platform.system() == 'Windows': # Windows os.startfile(fileName[0]) else: # linux variants subprocess.call(('xdg-open', fileName[0])) QtGui.QApplication.processEvents() #allow some time for file to open before deleting temp folder and contents time.sleep(1) QtGui.QApplication.processEvents() shutil.rmtree(dirPath)
Die Forumsdiskussion Schnitt Makro