[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 !
khoeds
Fraîchement OOthentifié
Messages : 9
Inscription : 03 août 2018 06:56

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

Message par khoeds »

Bonjour,

J'ai le code macro python qui fonctionne :

Code : Tout sélectionner

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 modification par khoeds le 10 août 2018 13:26, modifié 3 fois.
LibreOffice 6 32 bit sous Windows 10 64 bit
khoeds
Fraîchement OOthentifié
Messages : 9
Inscription : 03 août 2018 06:56

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

Message par khoeds »

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

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

 
""" 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

   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é
Messages : 9
Inscription : 03 août 2018 06:56

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

Message par khoeds »

Bonjour à tous,

Je touche enfin au but, j'ai enfin pu transposer ma macro. Voici le code final :

Code : Tout sélectionner

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
Avatar de l’utilisateur
Hubert Lambert
SuppOOrter
SuppOOrter
Messages : 1214
Inscription : 06 avr. 2016 07:26

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

Message par Hubert Lambert »

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.7 sur Win10
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
Jurassic Pork
PassiOOnné
PassiOOnné
Messages : 626
Inscription : 09 août 2017 22:15

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

Message par Jurassic Pork »

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

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

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
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 7.6.2.1 et OpenOffice 4.1.15 sous windows 11
LibreOffice 24.2.0 et OpenOffice 4.1.15 sous Ubuntu 20.04
khoeds
Fraîchement OOthentifié
Messages : 9
Inscription : 03 août 2018 06:56

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

Message par khoeds »

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é
Messages : 9
Inscription : 03 août 2018 06:56

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

Message par khoeds »


La modération vous 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

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

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