- FlatCAM can be run in HEADLESS mode now. This node can be selected by using the --headless=1 command line argument or by changing the line headless=False to True in config/configuration.txt file. In this mod the Sys Tray Icon menu will hold only the Run Scrip menu entry and Exit entry.
This commit is contained in:
@@ -81,12 +81,16 @@ class App(QtCore.QObject):
|
|||||||
# Get Cmd Line Options
|
# Get Cmd Line Options
|
||||||
cmd_line_shellfile = ''
|
cmd_line_shellfile = ''
|
||||||
cmd_line_shellvar = ''
|
cmd_line_shellvar = ''
|
||||||
|
cmd_line_headless = None
|
||||||
|
|
||||||
cmd_line_help = "FlatCam.py --shellfile=<cmd_line_shellfile>\nFlatCam.py --shellvar=<1,'C:\\path',23>"
|
cmd_line_help = "FlatCam.py --shellfile=<cmd_line_shellfile>\n" \
|
||||||
|
"FlatCam.py --shellvar=<1,'C:\\path',23>\n" \
|
||||||
|
"FlatCam.py --headless=1"
|
||||||
try:
|
try:
|
||||||
# Multiprocessing pool will spawn additional processes with 'multiprocessing-fork' flag
|
# Multiprocessing pool will spawn additional processes with 'multiprocessing-fork' flag
|
||||||
cmd_line_options, args = getopt.getopt(sys.argv[1:], "h:", ["shellfile=",
|
cmd_line_options, args = getopt.getopt(sys.argv[1:], "h:", ["shellfile=",
|
||||||
"shellvar=",
|
"shellvar=",
|
||||||
|
"headless=",
|
||||||
"multiprocessing-fork="])
|
"multiprocessing-fork="])
|
||||||
except getopt.GetoptError:
|
except getopt.GetoptError:
|
||||||
print(cmd_line_help)
|
print(cmd_line_help)
|
||||||
@@ -99,6 +103,11 @@ class App(QtCore.QObject):
|
|||||||
cmd_line_shellfile = arg
|
cmd_line_shellfile = arg
|
||||||
elif opt == '--shellvar':
|
elif opt == '--shellvar':
|
||||||
cmd_line_shellvar = arg
|
cmd_line_shellvar = arg
|
||||||
|
elif opt == '--headless':
|
||||||
|
try:
|
||||||
|
cmd_line_headless = eval(arg)
|
||||||
|
except NameError:
|
||||||
|
pass
|
||||||
|
|
||||||
# ## Logging ###
|
# ## Logging ###
|
||||||
log = logging.getLogger('base')
|
log = logging.getLogger('base')
|
||||||
@@ -251,20 +260,33 @@ class App(QtCore.QObject):
|
|||||||
# ####### CONFIG FILE WITH PARAMETERS REGARDING PORTABILITY ###############
|
# ####### CONFIG FILE WITH PARAMETERS REGARDING PORTABILITY ###############
|
||||||
# #########################################################################
|
# #########################################################################
|
||||||
config_file = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + '\\config\\configuration.txt'
|
config_file = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + '\\config\\configuration.txt'
|
||||||
|
try:
|
||||||
|
with open(config_file, 'r'):
|
||||||
|
pass
|
||||||
|
except FileNotFoundError:
|
||||||
|
config_file = os.path.dirname(os.path.realpath(__file__)) + '\\config\\configuration.txt'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(config_file, 'r') as f:
|
with open(config_file, 'r') as f:
|
||||||
try:
|
try:
|
||||||
for line in f:
|
for line in f:
|
||||||
param = str(line).rpartition('=')
|
param = str(line).replace('\n', '').rpartition('=')
|
||||||
|
|
||||||
if param[0] == 'portable':
|
if param[0] == 'portable':
|
||||||
try:
|
try:
|
||||||
portable = eval(param[2])
|
portable = eval(param[2])
|
||||||
except NameError:
|
except NameError:
|
||||||
portable = False
|
portable = False
|
||||||
|
if param[0] == 'headless':
|
||||||
|
if param[2].lower() == 'true':
|
||||||
|
self.cmd_line_headless = 1
|
||||||
|
else:
|
||||||
|
self.cmd_line_headless = None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.debug('App.__init__() -->%s' % str(e))
|
log.debug('App.__init__() -->%s' % str(e))
|
||||||
return
|
return
|
||||||
except FileNotFoundError:
|
except FileNotFoundError as e:
|
||||||
|
log.debug(str(e))
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if portable is False:
|
if portable is False:
|
||||||
@@ -365,7 +387,7 @@ class App(QtCore.QObject):
|
|||||||
del settings
|
del settings
|
||||||
show_splash = 1
|
show_splash = 1
|
||||||
|
|
||||||
if show_splash:
|
if show_splash and self.cmd_line_headless != 1:
|
||||||
splash_pix = QtGui.QPixmap('share/splash.png')
|
splash_pix = QtGui.QPixmap('share/splash.png')
|
||||||
self.splash = QtWidgets.QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint)
|
self.splash = QtWidgets.QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint)
|
||||||
# self.splash.setMask(splash_pix.mask())
|
# self.splash.setMask(splash_pix.mask())
|
||||||
@@ -380,6 +402,8 @@ class App(QtCore.QObject):
|
|||||||
self.splash.showMessage(_("FlatCAM is initializing ..."),
|
self.splash.showMessage(_("FlatCAM is initializing ..."),
|
||||||
alignment=Qt.AlignBottom | Qt.AlignLeft,
|
alignment=Qt.AlignBottom | Qt.AlignLeft,
|
||||||
color=QtGui.QColor("gray"))
|
color=QtGui.QColor("gray"))
|
||||||
|
else:
|
||||||
|
show_splash = 0
|
||||||
|
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
# ##################### Initialize GUI ########################################
|
# ##################### Initialize GUI ########################################
|
||||||
@@ -392,6 +416,7 @@ class App(QtCore.QObject):
|
|||||||
self.FC_dark_blue = '#0000ffbf'
|
self.FC_dark_blue = '#0000ffbf'
|
||||||
|
|
||||||
QtCore.QObject.__init__(self)
|
QtCore.QObject.__init__(self)
|
||||||
|
|
||||||
self.ui = FlatCAMGUI(self.version, self.beta, self)
|
self.ui = FlatCAMGUI(self.version, self.beta, self)
|
||||||
|
|
||||||
self.ui.geom_update[int, int, int, int, int].connect(self.save_geometry)
|
self.ui.geom_update[int, int, int, int, int].connect(self.save_geometry)
|
||||||
@@ -1579,6 +1604,12 @@ class App(QtCore.QObject):
|
|||||||
# #################################################################
|
# #################################################################
|
||||||
if self.defaults["global_systray_icon"]:
|
if self.defaults["global_systray_icon"]:
|
||||||
self.parent_w = QtWidgets.QWidget()
|
self.parent_w = QtWidgets.QWidget()
|
||||||
|
|
||||||
|
if self.cmd_line_headless == 1:
|
||||||
|
self.trayIcon = FlatCAMSystemTray(app=self, icon=QtGui.QIcon('share/flatcam_icon32_green.png'),
|
||||||
|
headless=True,
|
||||||
|
parent=self.parent_w)
|
||||||
|
else:
|
||||||
self.trayIcon = FlatCAMSystemTray(app=self, icon=QtGui.QIcon('share/flatcam_icon32_green.png'),
|
self.trayIcon = FlatCAMSystemTray(app=self, icon=QtGui.QIcon('share/flatcam_icon32_green.png'),
|
||||||
parent=self.parent_w)
|
parent=self.parent_w)
|
||||||
|
|
||||||
@@ -2454,6 +2485,8 @@ class App(QtCore.QObject):
|
|||||||
# ########################## SHOW GUI #################################################
|
# ########################## SHOW GUI #################################################
|
||||||
# #####################################################################################
|
# #####################################################################################
|
||||||
|
|
||||||
|
# if the app is not started as headless, show it
|
||||||
|
if self.cmd_line_headless != 1:
|
||||||
# finish the splash
|
# finish the splash
|
||||||
self.splash.finish(self.ui)
|
self.splash.finish(self.ui)
|
||||||
|
|
||||||
@@ -2469,6 +2502,8 @@ class App(QtCore.QObject):
|
|||||||
|
|
||||||
if self.defaults["global_systray_icon"]:
|
if self.defaults["global_systray_icon"]:
|
||||||
self.trayIcon.show()
|
self.trayIcon.show()
|
||||||
|
else:
|
||||||
|
log.warning("******************* RUNNING HEADLESS *******************")
|
||||||
|
|
||||||
# #####################################################################################
|
# #####################################################################################
|
||||||
# ########################## START-UP ARGUMENTS #######################################
|
# ########################## START-UP ARGUMENTS #######################################
|
||||||
@@ -8867,9 +8902,12 @@ class App(QtCore.QObject):
|
|||||||
|
|
||||||
if name:
|
if name:
|
||||||
filename = name
|
filename = name
|
||||||
self.splash.showMessage('%s: %ssec\n%s' % (_("Canvas initialization started.\n"
|
if self.cmd_line_headless != 1:
|
||||||
|
self.splash.showMessage('%s: %ssec\n%s' %
|
||||||
|
(_("Canvas initialization started.\n"
|
||||||
"Canvas initialization finished in"), '%.2f' % self.used_time,
|
"Canvas initialization finished in"), '%.2f' % self.used_time,
|
||||||
_("Executing FlatCAMScript file.")),
|
_("Executing FlatCAMScript file.")
|
||||||
|
),
|
||||||
alignment=Qt.AlignBottom | Qt.AlignLeft,
|
alignment=Qt.AlignBottom | Qt.AlignLeft,
|
||||||
color=QtGui.QColor("gray"))
|
color=QtGui.QColor("gray"))
|
||||||
else:
|
else:
|
||||||
@@ -8890,12 +8928,18 @@ class App(QtCore.QObject):
|
|||||||
self.inform.emit('[WARNING_NOTCL] %s' %
|
self.inform.emit('[WARNING_NOTCL] %s' %
|
||||||
_("Run TCL script cancelled."))
|
_("Run TCL script cancelled."))
|
||||||
else:
|
else:
|
||||||
|
if self.cmd_line_headless != 1:
|
||||||
if self.ui.shell_dock.isHidden():
|
if self.ui.shell_dock.isHidden():
|
||||||
self.ui.shell_dock.show()
|
self.ui.shell_dock.show()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(filename, "r") as tcl_script:
|
with open(filename, "r") as tcl_script:
|
||||||
cmd_line_shellfile_content = tcl_script.read()
|
cmd_line_shellfile_content = tcl_script.read()
|
||||||
|
if self.cmd_line_headless != 1:
|
||||||
self.shell._sysShell.exec_command(cmd_line_shellfile_content)
|
self.shell._sysShell.exec_command(cmd_line_shellfile_content)
|
||||||
|
else:
|
||||||
|
self.shell._sysShell.exec_command(cmd_line_shellfile_content, no_echo=True)
|
||||||
|
|
||||||
if silent is False:
|
if silent is False:
|
||||||
self.inform.emit('[success] %s' %
|
self.inform.emit('[success] %s' %
|
||||||
_("TCL script file opened in Code Editor and executed."))
|
_("TCL script file opened in Code Editor and executed."))
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ CAD program, and create G-Code for Isolation routing.
|
|||||||
- made sure that optionally, when a script is run then it is also loaded into the code editor
|
- made sure that optionally, when a script is run then it is also loaded into the code editor
|
||||||
- added control over the display of Sys Tray Icon in Edit -> Preferences -> General -> GUI Settings -> Sys Tray Icon checkbox
|
- added control over the display of Sys Tray Icon in Edit -> Preferences -> General -> GUI Settings -> Sys Tray Icon checkbox
|
||||||
- updated some of the default values to more reasonable ones
|
- updated some of the default values to more reasonable ones
|
||||||
|
- FlatCAM can be run in HEADLESS mode now. This node can be selected by using the --headless=1 command line argument or by changing the line headless=False to True in config/configuration.txt file. In this mod the Sys Tray Icon menu will hold only the Run Scrip menu entry and Exit entry.
|
||||||
|
|
||||||
18.09.2019
|
18.09.2019
|
||||||
|
|
||||||
|
|||||||
@@ -8212,7 +8212,7 @@ class FlatCAMInfoBar(QtWidgets.QWidget):
|
|||||||
|
|
||||||
class FlatCAMSystemTray(QtWidgets.QSystemTrayIcon):
|
class FlatCAMSystemTray(QtWidgets.QSystemTrayIcon):
|
||||||
|
|
||||||
def __init__(self, app, icon, parent=None):
|
def __init__(self, app, icon, headless=None, parent=None):
|
||||||
# QtWidgets.QSystemTrayIcon.__init__(self, icon, parent)
|
# QtWidgets.QSystemTrayIcon.__init__(self, icon, parent)
|
||||||
super().__init__(icon, parent=parent)
|
super().__init__(icon, parent=parent)
|
||||||
self.app = app
|
self.app = app
|
||||||
@@ -8229,39 +8229,42 @@ class FlatCAMSystemTray(QtWidgets.QSystemTrayIcon):
|
|||||||
|
|
||||||
menu.addSeparator()
|
menu.addSeparator()
|
||||||
|
|
||||||
menu_open = menu.addMenu(QtGui.QIcon('share/folder32_bis.png'), _('Open'))
|
if headless is None:
|
||||||
|
self.menu_open = menu.addMenu(QtGui.QIcon('share/folder32_bis.png'), _('Open'))
|
||||||
|
|
||||||
# Open Project ...
|
# Open Project ...
|
||||||
menu_openproject = QtWidgets.QAction(QtGui.QIcon('share/folder16.png'), _('Open Project ...'), self)
|
menu_openproject = QtWidgets.QAction(QtGui.QIcon('share/folder16.png'), _('Open Project ...'), self)
|
||||||
menu_open.addAction(menu_openproject)
|
self.menu_open.addAction(menu_openproject)
|
||||||
menu_open.addSeparator()
|
self.menu_open.addSeparator()
|
||||||
|
|
||||||
# Open Gerber ...
|
# Open Gerber ...
|
||||||
menu_opengerber = QtWidgets.QAction(QtGui.QIcon('share/flatcam_icon24.png'),
|
menu_opengerber = QtWidgets.QAction(QtGui.QIcon('share/flatcam_icon24.png'),
|
||||||
_('Open &Gerber ...\tCTRL+G'), self)
|
_('Open &Gerber ...\tCTRL+G'), self)
|
||||||
menu_open.addAction(menu_opengerber)
|
self.menu_open.addAction(menu_opengerber)
|
||||||
|
|
||||||
# Open Excellon ...
|
# Open Excellon ...
|
||||||
menu_openexcellon = QtWidgets.QAction(QtGui.QIcon('share/open_excellon32.png'),
|
menu_openexcellon = QtWidgets.QAction(QtGui.QIcon('share/open_excellon32.png'),
|
||||||
_('Open &Excellon ...\tCTRL+E'), self)
|
_('Open &Excellon ...\tCTRL+E'), self)
|
||||||
menu_open.addAction(menu_openexcellon)
|
self.menu_open.addAction(menu_openexcellon)
|
||||||
|
|
||||||
# Open G-Code ...
|
# Open G-Code ...
|
||||||
menu_opengcode = QtWidgets.QAction(QtGui.QIcon('share/code.png'), _('Open G-&Code ...'), self)
|
menu_opengcode = QtWidgets.QAction(QtGui.QIcon('share/code.png'), _('Open G-&Code ...'), self)
|
||||||
menu_open.addAction(menu_opengcode)
|
self.menu_open.addAction(menu_opengcode)
|
||||||
|
|
||||||
menu_open.addSeparator()
|
self.menu_open.addSeparator()
|
||||||
|
|
||||||
exitAction = menu.addAction(_("Exit"))
|
|
||||||
exitAction.setIcon(QtGui.QIcon('share/power16.png'))
|
|
||||||
self.setContextMenu(menu)
|
|
||||||
|
|
||||||
menu_runscript.triggered.connect(self.app.on_filerunscript)
|
|
||||||
menu_openproject.triggered.connect(self.app.on_file_openproject)
|
menu_openproject.triggered.connect(self.app.on_file_openproject)
|
||||||
menu_opengerber.triggered.connect(self.app.on_fileopengerber)
|
menu_opengerber.triggered.connect(self.app.on_fileopengerber)
|
||||||
menu_openexcellon.triggered.connect(self.app.on_fileopenexcellon)
|
menu_openexcellon.triggered.connect(self.app.on_fileopenexcellon)
|
||||||
menu_opengcode.triggered.connect(self.app.on_fileopengcode)
|
menu_opengcode.triggered.connect(self.app.on_fileopengcode)
|
||||||
|
|
||||||
|
exitAction = menu.addAction(_("Exit"))
|
||||||
|
exitAction.setIcon(QtGui.QIcon('share/power16.png'))
|
||||||
|
self.setContextMenu(menu)
|
||||||
|
|
||||||
|
menu_runscript.triggered.connect(lambda: self.app.on_filerunscript(
|
||||||
|
silent=True if self.app.cmd_line_headless == 1 else False))
|
||||||
|
|
||||||
exitAction.triggered.connect(self.app.final_save)
|
exitAction.triggered.connect(self.app.final_save)
|
||||||
|
|
||||||
# end of file
|
# end of file
|
||||||
|
|||||||
@@ -42,5 +42,5 @@ class TclCommandPlotAll(TclCommand):
|
|||||||
:param unnamed_args:
|
:param unnamed_args:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
if self.app.cmd_line_headless != 1:
|
||||||
self.app.plot_all()
|
self.app.plot_all()
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ class TclCommandPlotObjects(TclCommand):
|
|||||||
:param unnamed_args:
|
:param unnamed_args:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
if self.app.cmd_line_headless != 1:
|
||||||
names = [x.strip() for x in args['names'].split(",")]
|
names = [x.strip() for x in args['names'].split(",")]
|
||||||
objs = []
|
objs = []
|
||||||
for name in names:
|
for name in names:
|
||||||
|
|||||||
Reference in New Issue
Block a user