Launch Python Console to Use From Macro

Can I run code in a python macro and print output to a console? I’ve tried the following code based on the links it contains.

This code does not print to the console:

# https://help.libreoffice.org/latest/bo/text/sbasic/python/python_shell.html#N0127
def interpreter_console():
    import uno, os, subprocess
    ctx = XSCRIPTCONTEXT.getComponentContext()
    smgr = ctx.getServiceManager()
    ps = smgr.createInstanceWithContext("com.sun.star.util.PathSettings", ctx)
    install_path = uno.fileUrlToSystemPath(ps.Module)
    pgm = install_path + os.sep + "python"  # Python shell/console path
    subprocess.Popen(pgm)  # Start Python interactive Shell
    print("Hi")

The testhelpers macro generates an error unless apso has been launched before running (which I’m trying to avoid). It prints to the console if it is open, otherwise it just opens the console without printing.

# https://gitlab.com/jmzambon/apso#helpers
def testhelpers():
    from apso_utils import console, msgbox
    ## simple console:
    # console()

    ## black&white console:
    # console(BACKGROUND=0x0, FOREGROUND=0xFFFFFF)

    ## pass parent window to get non-modal top console:
    # doc = XSCRIPTCONTEXT.getDocument()
    # console(parent=doc.CurrentController.ComponentWindow)

    ## load currents variables into console namespace:
    loc = locals()
    loc.update(globals())
    console(loc=loc)

    ## introspection tools and message box:
    doc = XSCRIPTCONTEXT.getDocument()
    print(doc.Title)
    msgbox(doc.Title)

def entryfunc(event=None):
    ctx = XSCRIPTCONTEXT.getComponentContext()
    ctx.ServiceManager.createInstance("apso.python.script.organizer.impl")
    # now we can import apso_utils library
    from apso_utils import mri
    mri(ctx)

entryfunc might be relevant.

https://wiki.documentfoundation.org/Macros/Python_Design_Guide#Output_to_Consoles

1 Like

Console on Windows is ugly. Maybe someone will offer a way of using apso without preloading it.
.
Test:

def p_hi():
    from scriptforge import CreateScriptService
    bas = CreateScriptService("Basic")
    print("hi")
    bas.MsgBox("Hello!")

Could you please post a screenshot showing how it’s ugly. Maybe you could set some advanced Windows console options to look/behave better.

It’s not the look, it’s the process. Instead of a scalc.exe taskbar icon it’s soffice.com instead (more in console mode for LibreOffice on Windows).

Lol. A hint: I had written that blog :wink:

Anyway, you may use the way described in the “Prior to this release” part of the article, to make the .exe also console (no need to run that against .bin anymore).

import sys
from subprocess import Popen, PIPE

def run_python_terminal():

    proc = Popen([sys.executable], stdin=PIPE)
    
    outs, errs = proc.communicate(timeout=10)
    print("hi")
    print("But WHY do you want to put the cart before the horse?")

But its a mess, run soffice from terminal, and any print(…) from python goes to the terminal.

1 Like

Running as:

def run_python_terminal():
    import sys
    from subprocess import Popen, PIPE
    from scriptforge import CreateScriptService
    bas = CreateScriptService("Basic")
    proc = Popen([sys.executable], stdin=PIPE)
    outs, errs = proc.communicate(timeout=10)
    print("hi")
    bas.MsgBox("Hello!")

Starting soffice.exe (with icon) then calc and getting:

Demo.py (<class 'OSError'>: [WinError 6] The handle is invalid
  File "C:\Program Files\LibreOffice\program\pythonscript.py", line 915, in invoke
    ret = self.func( *args )
  File "C:\Users\User\AppData\Roaming\LibreOffice\4\user\Scripts\python\Demo.py", line 72, in run_python_terminal
    proc = Popen([sys.executable], stdin=PIPE)

If I’m going to run soffice.com instead of scalc.exe from an icon I’ll find it with Everything and double click it given it is not in the path.