Threading und COM-Schnittstelle

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
patmaster
User
Beiträge: 106
Registriert: Donnerstag 3. Februar 2011, 17:21

Hi,

Ich baue gerade eine GUI in wx.Python, mein Problem liegt jedoch woanders deswegen habe ich nicht uns GUI-Forum gepostet.
Jedenfalls wollte ich threading einbauen, damit die GUI weiter reagiert wenn gerade eine Operation läuft.
Jetzt bekomme ich folgenden Fehler:

Code: Alles auswählen

Exception in thread Thread-4:
Traceback (most recent call last):
  File "C:\Python27\lib\threading.py", line 530, in __bootstrap_inner
    self.run()
  File "C:\work\workspace\ChecktO_ol\src\ChecktO_ol.py", line 117, in run
    for error in self.checkson.main(file):
  File "C:\work\workspace\ChecktO_ol\src\word_test.py", line 31, in main
    word = win32.gencache.EnsureDispatch('Word.Application')
  File "C:\Python27\lib\site-packages\win32com\client\gencache.py", line 529, in EnsureDispatch
    disp = win32com.client.Dispatch(prog_id)
  File "C:\Python27\lib\site-packages\win32com\client\__init__.py", line 95, in Dispatch
    dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
  File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 108, in _GetGoodDispatchAndUserName
    return (_GetGoodDispatch(IDispatch, clsctx), userName)
  File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 85, in _GetGoodDispatch
    IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)
com_error: (-2147221008, 'CoInitialize wurde nicht aufgerufen.', None, None)
Hier der Code meines Threads:

Code: Alles auswählen

class CheckThread(Thread):
    """Test Worker Thread Class."""
 
    def __init__(self, files):
        """Init Worker Thread Class."""
        Thread.__init__(self)        
        self.checkson = word_test.CheckOr()
        self.files = files
        self.start()    # start the thread
    
    def run(self):
        """Run Worker Thread."""
        # This is the code executing in the new thread.
        for file in self.files:
            self.postTime("Working on %s...\n" % file)          
            for error in self.checkson.main(file):
                self.postTime("  Unknown: '%s' at '%s'(%i)\n" % (error[2],error[1],error[0]))       
 
    def postTime(self, amt):
        Publisher().sendMessage("update", amt)
In checkson.main wirdfolgende Methode aufgerufen:

Code: Alles auswählen

def main(self, file):        
            word = win32.gencache.EnsureDispatch('Word.Application')
            doc = word.Documents.Open(file)
            errors = []
            p = 0
            for par in doc.Paragraphs:
                if not(self.zeichen(str(par.Format.Style)).lower().strip() in self.final_formats):
                    #print "WRONG: %s" % self.zeichen(str(par.Format.Style)).lower()
                    #print "P%i: %s" % (p+1,par)
                    errors.append([p+1,str(par).strip(),self.zeichen(str(par.Format.Style)).lower()])                    
                p+=1 
            doc.Close()
            word.Application.Quit(-1)
            return errors
In diesem thread von 2005 http://www.python-forum.de/viewtopic.php?f=1&t=4354 führte man das Problem auf den Zugriff auf eine COM-Schnittstelle zurück.

Weis einer wie ich das nun machen soll ?

Vielen Dank im Vorraus !
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich kenne mich mit wx nicht aus, weiß aber, dass eigentliche so ziemlich alle GUI-Toolkits mit den normalen Python-Threading-Methoden nicht zurecht kommen. Du müsstest da wohl mal in die Howtos und Dokus zu wx gucken. Dort sollte eine Möglichkeit beschrieben sein, wie man so etwas umsetzt.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
patmaster
User
Beiträge: 106
Registriert: Donnerstag 3. Februar 2011, 17:21

Hyperion hat geschrieben:Ich kenne mich mit wx nicht aus, weiß aber, dass eigentliche so ziemlich alle GUI-Toolkits mit den normalen Python-Threading-Methoden nicht zurecht kommen. Du müsstest da wohl mal in die Howtos und Dokus zu wx gucken. Dort sollte eine Möglichkeit beschrieben sein, wie man so etwas umsetzt.
Danke für deine schnelle Antwort, aber das is aus der wx Doku ^^. Ich hab lediglich meinen Code eingefügt, was auch hinhaut so lange ich nicht auf eine COM-Schnittstelle zugreife.
Wie gesagt glaube ich nicht das es an wx liegt, sondern eher am threading in verbindung mit einer COM-Schnittstelle.
patmaster
User
Beiträge: 106
Registriert: Donnerstag 3. Februar 2011, 17:21

Okay ich habe weiter gegoogelt und folgender Code haut hin:

Code: Alles auswählen

def run(self):
        pythoncom.CoInitializeEx(pythoncom.COINIT_APARTMENTTHREADED)
        """Run Worker Thread."""
        # This is the code executing in the new thread.
        for file in self.files:
            self.postTime("Working on %s...\n" % file)
            for error in self.checkson.main(file):
                self.postTime("  Unknown: '%s' at '%s'(%i)\n" % (error[2],error[1],error[0]))            
        pythoncom.CoUninitialize(pythoncom.COINIT_APARTMENTTHREADED)
Antworten