-1

I have 3 python modules,

main.py

client.py

interface.py

interface.py is a Qt UI modules so it doesn't have anything related to this question.

main.py imports the interface.py and client.py class and execute the main functions of the program.

client.py is the core module where all the core functions are located.

one of the function in client.py (format_excel function) is to call the win32com.client to execute excel operations, which it will modify the output of the excel from the inputs given.

the issue here is when I start a thread in main.py to run the function in client.py (format_excel function) and it gave me and error like this.

The application called an interface that was marshalled for a different thread.

my code as below (simplified)

client.py

class Formatter:
    def __init__(self):
        self._excel = win32.dynamic.Dispatch('Excel.Application')

    def format_excel(self, info_list):
        pythoncom.CoInitialize()
        self._excel.Workbooks.Add()
        # other codes

main.py

self._data contain some info grabbed from GUI so I did not added into the snippet

class Main:
    def __init__(self):
        self._format = Formatter()
        self._data = []

    def start(self):
        t = threading.Thread(target=self._format.format_excel, args=[self._data])
        t.start()
        # other codes

need some help here.

ReverseEngineer
  • 529
  • 1
  • 5
  • 18
  • 2
    Possible duplicate of [Using win32com with multithreading](https://stackoverflow.com/questions/26764978/using-win32com-with-multithreading) – Maurice Meyer Aug 03 '18 at 10:24

1 Answers1

0

Using win32com with multithreading

excel = win32.dynamic.Dispatch('Excel.Application')
excel_id = pythoncom.CoMarshalInterThreadInterfaceInStream(pythoncom.IID_IDispatch, excel)

def format_excel(self, info_list, excel_id):
    pythoncom.CoInitialize()
    excel = win32com.client.Dispatch(pythoncom.CoGetInterfaceAndReleaseStream(excel_id, pythoncom.IID_IDispatch)

    excel.Workbooks.Add()

You just need to make an id and then create a new comobject from that id.