web-dev-qa-db-fra.com

Que pouvez-vous faire avec COM/ActiveX en Python?

J'ai lu qu'il était possible d'automatiser les rapports mensuels dans Crystal Reports avec COM/ActiveX. Je ne suis pas si avancé pour comprendre ce que c'est ou ce que vous pouvez même en faire.

Je travaille aussi beaucoup avec Excel et il semblerait que vous utilisiez également COM/ActiveX pour l’interfacer.

Quelqu'un peut-il expliquer comment cela fonctionne et peut-être donner un bref exemple?

30
mandroid

Vous devez d’abord installer le merveilleux module pywin32 .

Il fournit un support COM. Vous devez exécuter l'utilitaire makepy. Il est situé à C:\...\Python26\Lib\site-packages\win32com\client. Sur Vista, il doit être exécuté avec des droits d'administrateur.

Cet utilitaire affichera tous les objets COM disponibles. Vous pouvez trouver le vôtre et il va générer un wrapper Python pour cet objet.

Le wrapper est un module python généré dans le dossier C:\...\Python26\Lib\site-packages\win32com\gen_py. Le module contient l'interface des objets COM. Le nom du fichier est l'identifiant unique COM. Si vous avez plusieurs fichiers, il est parfois difficile de trouver le bon.

Après cela, il vous suffit d'appeler la bonne interface. C'est magique :)

Un petit exemple avec Excel

import win32com.client

xlApp = win32com.client.Dispatch("Excel.Application")
xlApp.Visible=1

workBook = xlApp.Workbooks.Open(r"C:\MyTest.xls")
print str(workBook.ActiveSheet.Cells(i,1))
workBook.ActiveSheet.Cells(1, 1).Value = "hello"                
workBook.Close(SaveChanges=0) 
xlApp.Quit()
37
luc

Vous pouvez essentiellement faire l'équivalent d'une liaison tardive. Ainsi, tout ce qui est exposé par IDispatch peut être consommé. 

Voici le code que j'ai écrit ce week-end pour extraire une image d'un périphérique twain via Windows Image Acquisition 2.0 et pour mettre les données dans quelque chose que je peux transférer dans une interface utilisateur basée sur gtk.

WIA_COM = "WIA.CommonDialog"
WIA_DEVICE_UNSPECIFIED = 0
WIA_INTENT_UNSPECIFIED = 0
WIA_BIAS_MIN_SIZE = 65536
WIA_IMG_FORMAT_PNG = "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}"

def acquire_image_wia():
    wia = win32com.client.Dispatch(WIA_COM)
    img = wia.ShowAcquireImage(WIA_DEVICE_UNSPECIFIED,
                           WIA_INTENT_UNSPECIFIED,
                           WIA_BIAS_MIN_SIZE,
                           WIA_IMG_FORMAT_PNG,
                           False,
                           True)
    fname = str(time.time())
    img.SaveFile(fname)
    buff = gtk.gdk.pixbuf_new_from_file(fname)
    os.remove(fname)

return buff

Ce n'est pas joli mais ça marche. Je dirais que cela équivaut à ce que vous auriez à écrire en VB.

3
Tom Willis

Voici une solution de travail qui crée un fichier et ajoute de la valeur à une cellule:

 import win32com.client
import xlsxwriter
import os
cwd = os.getcwd()
file_path = cwd + "\\test.xlsx"

#Create an Excel file
workbook = xlsxwriter.Workbook(file_path)
worksheet = workbook.add_worksheet()
workbook.close()

#Open an Excel application
xlApp = win32com.client.Dispatch("Excel.Application")
xlApp.Visible=1


workBook = xlApp.Workbooks.Open(file_path)
print str(workBook.ActiveSheet.Cells(1,1))
workBook.ActiveSheet.Cells(1, 1).Value = "hello55"                
workBook.Close(SaveChanges=1) 
xlApp.Quit()
1
Valentyn

Comment recevoir des événements ActiveX dans Python 3  

# coding=utf8

from PyQt5.QAxContainer import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QObject
import sys

TITLE = "CallX Python Example: accept any calls"
TrueConfCallX_Class = '{27EF4BA2-4500-4839-B88A-F2F4744FE56A}'

SERVER = '' # empty - connect to TrueConf Online cloud
USER = '<trueconf id>'
PASSWORD = '<password>'

class CallXWindow(QWidget):

    def __init__(self):
        QAxWidget.__init__(self)
        self.setWindowTitle(TITLE)
        self.move(400, 30)
# end of class CallXWindow(QWidget)


class ActiveXExtend(QObject):

    def __init__(self, view):
        super().__init__()
        self.view = view
        self.ocx = QAxWidget(TrueConfCallX_Class)

        self.ocx.move(0, 0)
        self.ocx.setFixedSize(640, 375)
        self.ocx.setParent(self.view)
        self.ocx.show()

        # receive some ActiveX events 
        self.ocx.OnXAfterStart.connect(self._OnXAfterStart)
        self.ocx.OnServerConnected[str].connect(self._OnServerConnected)
        self.ocx.OnLogin[str].connect(self._OnLogin)
        self.ocx.OnInviteReceived[str].connect(self._OnInviteReceived)
        self.ocx.OnXError[int, str].connect(self._OnXError)
        self.ocx.OnXLoginError[int].connect(self._OnXLoginError)

    # Events
    def _OnXAfterStart(self):
        print("**OnXAfterStart")
        # select devices
        self.ocx.XSetCameraByIndex(0)
        self.ocx.XSelectMicByIndex(0)
        self.ocx.XSelectSpeakerByIndex(0)
        # connect to server
        self.ocx.connectToServer(SERVER)

    def _OnServerConnected(self, eventDetails):
        print("**OnServerConnected")
        print(eventDetails)
        # login
        self.ocx.login(USER, PASSWORD)

    def _OnLogin(self, eventDetails):
        print("**OnLogin")

    def _OnInviteReceived(self, eventDetails):
        print("**OnInviteReceived")
        print(eventDetails)
        # accept any calls
        self.ocx.accept()

    def _OnXError(self, errorCode, errorMsg):
        print("**OnXError")
        print('{}. Code: {}'.format(errorMsg, errorCode))

    def _OnXLoginError(self, errorCode):
        print("**OnXLoginError")
        if errorCode == 8:
            print('Support for SDK Applications is not enabled on this server')
        else:
            print('Login error. Code: {}'.format(errorCode))
# end of class ActiveXExtend(QObject)


if __== '__main__':
    app = QApplication(sys.argv)
    MainWindow = CallXWindow()
    axwin = ActiveXExtend(MainWindow)
    MainWindow.show()
sys.exit(app.exec_())
0
Andrey Zobov