[Résolu][Python] Impress :Passer à la diapositive suivante

Discussions et questions sur tout ce qui concerne la programmation tous langages et tous modules confondus.

Modérateur: Vilains modOOs

Règles du forum
:alerte: Balisage obligatoire dans cette section !
Aidez-nous à vous aider au mieux en balisant correctement votre question : reportez-vous sur les règles de cette section avant de poster !

[Résolu][Python] Impress :Passer à la diapositive suivante

Messagepar khoeds » 03 Août 2018 10:19

Bonjour,

J'ai le code macro python qui fonctionne :
Code : Tout sélectionner   AgrandirRéduire
def test():
   monDocument = XSCRIPTCONTEXT.getDocument()
   Pres =monDocument.Presentation
   Pres.start()
   Pres.Controller.gotoSlideIndex(1)


Je cherche à transposer ce code pour qu'il fonctionne LibreOffice à partir d'IDLE. J'utilise python 3.7. J'ai cru comprendre que pyuno ne fonctionne pas avec cette version. Je crois qu'il est possible de le faire via piwin32 et COM, mais je n'arrive pas à le retrouver. Je suis preneur de toutes les pistes. Merci d'avance.

Cordialement
Dernière édition par khoeds le 10 Août 2018 14:26, édité 3 fois.
LibreOffice 6 32 bit sous Windows 10 64 bit
khoeds
Fraîchement OOthentifié
 
Message(s) : 7
Inscrit le : 03 Août 2018 07:56

Re: [Python] Impress :Passer à la diapositive suivante

Messagepar khoeds » 08 Août 2018 15:57

Je continue de chercher et j'avance un peu. J'ai réussi à importer uno :bravo: . Je débute et voici ce sur quoi j'ai bloqué. Le "Hello Word" que j'ai trouvé ne fonctionne que pour windows 32 bit. J'ai donc installé LibreOffice 6 version 32 bit sur mon windows10 64 bit. Ensuite javais la version 3.7 de python or LibreOffice 6 fonctionne avec python 3.5. Donc j'ai installer python 3.5, en version 32 bit bien sûr.
Voici le code qui me permet de ne pas avoir d'erreur lors de l'import de uno
Code : Tout sélectionner   AgrandirRéduire
import os, sys, time
import subprocess

#On lance writer en mode serveur
args='"C:\Program Files (x86)\LibreOffice\program\swriter" "-accept=socket,host=localhost,port=2002;urp;"'
myPopen = subprocess.Popen(args, shell=False)
while myPopen.poll()!=0:
    time.sleep(1)

if sys.platform == 'win32':
    #Adresse d'installation de LibreOffice 6 32 bit
    value = "C:\Program Files (x86)\LibreOffice\program"
    install_folder = '\\'.join(value.split('\\')[:-1])
   
    os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:{0}\\program\\fundamental.ini'.format(install_folder)
    os.environ['UNO_PATH'] = install_folder+'\\program\\'

    sys.path.append(install_folder+'\\program')

    paths = ''
    for path in ("\\URE\\bin;", "\\program;"):
        paths += install_folder + path
    os.environ['PATH'] =  paths+ os.environ['PATH']

import uno


Donc jusque là tout fonctionne. Je teste en ajoutant un "Hello Word" avec le code suivant :
Code : Tout sélectionner   AgrandirRéduire

""" Here is the sequence of things the lines do:
1.  Get the uno component context from the PyUNO runtime(
2.  Create the UnoUrlResolver
3.  Get the central desktop object
4.  Declare the ServiceManager
5.  Get the central desktop object
6.  Access the current writer document
7.  Access the document's text property
8.  Create a cursor
9.  Insert the text into the document """

localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
            "com.sun.star.bridge.UnoUrlResolver", localContext )
ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager
#desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)
model = smgr.createInstanceWithContext( "com.sun.star.script.provider.XScriptContext",ctx)
#model = desktop.getCurrentComponent()
#monDocument = document.getDocument()
monDocument = model.getDocument()
Pres =monDocument.Presentation
Pres.start()
Pres.Controller.gotoSlideIndex(1)
   

""" Do a nasty thing before exiting the python process. In case the
last call is a one-way call (e.g. see idl-spec of insertString),
it must be forced out of the remote-bridge caches before python
exits the process. Otherwise, the one-way call may or may not reach
the target object.
I do this here by calling a cheap synchronous call (getPropertyValue)."""
ctx.ServiceManager


Et là miracle, mais pas tant que ça, j'ai bien Hello Word qui s'affiche dans Writer :bravo:

Maintenant partant de là je voudrais transposer le code suivant, mais je n'y arrive pas :
Code : Tout sélectionner   AgrandirRéduire
   monDocument = XSCRIPTCONTEXT.getDocument()
   Pres =monDocument.Presentation
   Pres.start()
   Pres.Controller.gotoSlideIndex(1)

Je pense ne pas être loin mais je suis preneur de n'importe quelle piste.

Merci d'avance
LibreOffice 6 32 bit sous Windows 10 64 bit
khoeds
Fraîchement OOthentifié
 
Message(s) : 7
Inscrit le : 03 Août 2018 07:56

Re: [Python] Impress :Passer à la diapositive suivante

Messagepar khoeds » 10 Août 2018 14:24

Bonjour à tous,

Je touche enfin au but, j'ai enfin pu transposer ma macro. Voici le code final :
Code : Tout sélectionner   AgrandirRéduire
import os, sys, time
import subprocess

args='"C:\Program Files (x86)\LibreOffice\program\simpress" "-accept=socket,host=localhost,port=2002;urp;" "D:\MaPrésentation.odp"'
myPopen = subprocess.Popen(args, shell=False)
while myPopen.poll()!=0:
    time.sleep(1)
time.sleep(1)

if sys.platform == 'win32':
    #This is required in order to make pyuno usable with the default python interpreter under windows
    #Some environment varaible must be modified
   
    value = "C:\Program Files (x86)\LibreOffice\program"
    install_folder = '\\'.join(value.split('\\')[:-1])
   
    #modify the environment variables
    os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:{0}\\program\\fundamental.ini'.format(install_folder)
    os.environ['UNO_PATH'] = install_folder+'\\program\\'

    sys.path.append(install_folder+'\\program')

    paths = ''
    for path in ("\\URE\\bin;", "\\program;"):
        paths += install_folder + path
    os.environ['PATH'] =  paths+ os.environ['PATH']

import uno

""" Here is the sequence of things the lines do:
1.  Get the uno component context from the PyUNO runtime(
2.  Create the UnoUrlResolver
3.  Get the central desktop object
4.  Declare the ServiceManager
5.  Get the central desktop object
6.  Access the current impress document"""

localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
            "com.sun.star.bridge.UnoUrlResolver", localContext )
ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)
model = desktop.getCurrentComponent()
Pres = model.Presentation
time.sleep(5)
Pres.start()
time.sleep(1)
Pres.Controller.gotoSlideIndex(1)
   

""" Do a nasty thing before exiting the python process. In case the
last call is a one-way call (e.g. see idl-spec of insertString),
it must be forced out of the remote-bridge caches before python
exits the process. Otherwise, the one-way call may or may not reach
the target object.
I do this here by calling a cheap synchronous call (getPropertyValue)."""
ctx.ServiceManager



Je l'avoue ce n'est pas transcendant, mais maintenant je peux contrôler ma présentation et mes diapositives :D
LibreOffice 6 32 bit sous Windows 10 64 bit
khoeds
Fraîchement OOthentifié
 
Message(s) : 7
Inscrit le : 03 Août 2018 07:56

Re: [Résolu][Python] Impress :Passer à la diapositive suivan

Messagepar Hubert Lambert » 10 Août 2018 19:02

Bonjour,

J'arrive un peu comme les cavaliers d'Offenbach sur ton fil.
Donc :
- bravo d'abord pour avoir persévéré malgré l'absence de réponse;
- merci ensuite pour avoir partagé ta solution.
:)
AOOo 4.1.2 sur Win7
AOOo 4.1.x sur Linux Mint
LibreOffice 5.x/6.x sur Linux Mint
--
| « Nos défauts devraient nous donner une qualité : l'indulgence pour les défauts des autres » (Rivarol)
Avatar de l’utilisateur
Hubert Lambert
InconditiOOnnel
InconditiOOnnel
 
Message(s) : 972
Inscrit le : 06 Avr 2016 08:26

Re: [Résolu][Python] Impress :Passer à la diapositive suivan

Messagepar Jurassic Pork » 11 Août 2018 06:58

hello,
Arf ! :aie: moi aussi j'arrive après la bataille.
khoeds a écrit:Je crois qu'il est possible de le faire via piwin32 et COM, mais je n'arrive pas à le retrouver. Je suis preneur de toutes les pistes. Merci d'avance.

pywin32 est disponible ici :
il faut installer la version qui correspond à la version de python que l'on utilise :
Par exemple moi qui utilise du python 3.6 en version 64 bits, j'ai téléchargé pywin32-223.win-amd64-py3.6.exe
Et voici un exemple d'utilisation pour se connecter à un document impress déjà ouvert, lancer le diaporama et aller à la 3ème Diapo.
Code : Tout sélectionner   AgrandirRéduire
import time
from win32com.client.dynamic import Dispatch
print('connexion au document impress')
objServiceManager = Dispatch('com.sun.star.ServiceManager')
Stardesktop = objServiceManager.CreateInstance('com.sun.star.frame.Desktop')
diaporama = Stardesktop.getCurrentComponent()
Pres = diaporama.Presentation
time.sleep(5)
print('démarrage du diaporama')
Pres.start()
time.sleep(2)
print('passage à la 3ème diapo')
Pres.Controller.gotoSlideIndex(2)


Voici le script l'intérieur de mon IDE python préféré (Eric6) sous Windows 10 qui fonctionne en connexion avec LibreOffice 5.4.4.2 :
LibreOfficePywin32.png


voici un autre exemple pour ouvrir un nouveau document writer et écrire "hello World" dedans :
Code : Tout sélectionner   AgrandirRéduire
from win32com.client.dynamic import Dispatch
print('ouverture nouveau document writer')
objServiceManager = Dispatch('com.sun.star.ServiceManager')
Stardesktop = objServiceManager.CreateInstance('com.sun.star.frame.Desktop')
doc = Stardesktop.loadComponentfromURL('private:factory/swriter', '_blank', 0, [])
text = doc.getText()
print('écriture de hello World')
text.setString("Hello World")


Je ne sais pas si l'on peut tout faire en procédant de la sorte mais en tout cas cela semble assez simple à utiliser.

Ami calmant, J.P
LibreOffice 6.1.x sous windows 10 et LibreOffice 6.0.x sous linux - OpenOffice 4.1.5 sous windows 10
Avatar de l’utilisateur
Jurassic Pork
Membre hOOnoraire
Membre hOOnoraire
 
Message(s) : 192
Inscrit le : 09 Août 2017 23:15

Re: [Résolu][Python] Impress :Passer à la diapositive suivan

Messagepar khoeds » 13 Août 2018 16:02

Merci beaucoup pour ta proposition, elle présente beaucoup d'avantage par rapport à celle que j'ai mise en place :
- Elle est plus courte et plus simple
- Je peux utiliser la version de Python que je veux avec la version de Libre Office que je veux, je l'ai testé avec Python 3.7 32bit et LO 6 64bit
- Je peux lancer la présentation que je veux (C'est plus simple pour moi)
Et le dernier et le plus important :
- Il n'y a pas de maintenance du code, lorsque je vais changer ma version de Libre Office je n'aurais (à priori) pas besoin de modifier le code notamment le chemin d'accès

Donc il doit bien y avoir des inconvénients, mais pour mon utilisation toute simple c'est parfait. Encore un grand merci
LibreOffice 6 32 bit sous Windows 10 64 bit
khoeds
Fraîchement OOthentifié
 
Message(s) : 7
Inscrit le : 03 Août 2018 07:56

Re: [Résolu][Python] Impress :Passer à la diapositive suivan

Messagepar khoeds » 20 Août 2018 11:17


La modération a écrit:Question initiale résolue donc pour tout autre problème : ouvrir un nouveau fil avec un titre explicite.

Bonjour,

Me revoilà toujours sur le même projet. Le projet plus global est celui-ci. J'ai un double écran, un où j'aurais ma présentation impress et un autre où j'aurais un logiciel quelconque. La fenêtre active ne sera pas ma présentation mais mon logiciel sur mon autre écran. Mon objectif serait de changer de diapo avec la barre d'espace et éventuellement d'autres contraintes même si la focalisation n'est pas sur ma présentation. Afin de récupérer les événements clavier j'utilise pyhook avec ce code qui fonctionne très bien :
Code : Tout sélectionner   AgrandirRéduire
import pyHook, pythoncom
txt="La barre d'espace est appuyée!!!"

def OnKeyboardEvent(event):
    if event.KeyID==32:
        print(txt)
    return event.KeyID

hooks_manager = pyHook.HookManager()
hooks_manager.KeyDown = OnKeyboardEvent
hooks_manager.HookKeyboard()
pythoncom.PumpMessages()


J'ai essayé d'y insérer le code vu précédemment de cette manière :
Code : Tout sélectionner   AgrandirRéduire
import time
from win32com.client.dynamic import Dispatch
print('connexion au document impress')
objServiceManager = Dispatch('com.sun.star.ServiceManager')
Stardesktop = objServiceManager.CreateInstance('com.sun.star.frame.Desktop')
diaporama = Stardesktop.getCurrentComponent()
Pres = diaporama.Presentation
time.sleep(5)
print('démarrage du diaporama')
Pres.start()
time.sleep(2)

import pyHook, pythoncom
SlideNo=0
txt="La barre d'espace est appuyée!!!"
def OnKeyboardEvent(event):
    global SlideNo
    global Pres
    if event.KeyID==32:
        print(txt)
        SlideNo = SlideNo + 1
        Pres.Controller.gotoSlideIndex(SlideNo)
    return True
hooks_manager = pyHook.HookManager()
hooks_manager.KeyDown = OnKeyboardEvent
hooks_manager.HookKeyboard()
pythoncom.PumpMessages()


Cependant, la fonction "OnKeyboardEvent" ne semble pas reconnaître "Pres" malgré la déclaration en "global". Je suis débutant en python, il doit donc y avoir quelque chose que je n'ai pas compris.
J'ai hésité à poster ce message car ce n'ai pas un problème LO mais plutôt python pur. Me dire si je dois le supprimer ou créer un nouveau sujet.

Encore merci d'avance à ceux qui me permettront d'avancer.
LibreOffice 6 32 bit sous Windows 10 64 bit
khoeds
Fraîchement OOthentifié
 
Message(s) : 7
Inscrit le : 03 Août 2018 07:56


Retour vers Macros et API

Qui est en ligne ?

Utilisateur(s) parcourant ce forum : Aucun utilisateur inscrit et 6 invité(s)