调用xlwings函数的线程返回pywintype错误

时间:2019-05-10 15:40:59

标签: python-3.x python-multithreading xlwings

运行函数时,我试图使其GUI不冻结,因此我将其放入线程,但是当将其用作线程时,出现以下错误;

错误:

  • pywintypes.com_error:(-2147417842,“应用程序调用了已编组用于不同线程的接口。”,无,无)

我目前正在使用xlwings在SaveRunThread函数中对Excel工作表进行某些操作

import xlwings as xw

 def SaveRun(self):
        try:
            saverun = threading.Thread(target=self.SaveRunThread)
            saverun.start()
        except:
            print('Not Run')

 def SaveRunThread(self):
        'Save Run File to directory'
        try:
            app = xw.App(visible=False)

            book = xw.Book(r'{0}\Template_VS.xlsx'.format(TemplateDirectory[-1]))
              ### Do something

            book.save(r'{0}\{1}.xlsx'.format(newDirectory[-1], nameList[-1]))
            app.kill() #####Error occurs here
       except:
           print('Not Run')

我希望它在调用时运行代码而不会冻结GUI。我现在没有MCVE,所以我只发布了部分代码。

2 个答案:

答案 0 :(得分:0)

我为此错误创建了一种解决方法。我创建了自己的线程类,并将代码在运行函数中用xlwings进行了处理,并使用信号与主线程进行通信。

在线程中使用app.kill()时发生错误。

在我的GUI / ui中,我在线程启动之前创建了一个空列表,追加了app方法,然后在线程完成后访问列表中的项目以杀死excel。这对我有用。

######This is the code in my ui init method######
    self.saveThread = SaveThread()
    self.saveThread.finished.connect(self.on_finished)


    def SaveRun(self):
        'Save Run File to directory'
        try:
            directory = str(QFileDialog.getExistingDirectory(self, "Select Directory"))
            saveDirectory.append(directory)
            app = xw.App(visible=False)
            appList.append(app)
            self.saveThread.start()

    def on_finished(self):
            appList[-1].kill()

class SaveThread(QtCore.QThread):
    saveSignal = pyqtSignal()
    def __init__(self, parent = None):
        super().__init__(parent)

    def run(self):
        book = xw.Book(r'{0}\Template_VS.xlsx'.format(TemplateDirectory[-1]))
           ### Do something with excel
        book.save(r'{0}\{1}.xlsx'.format(newDirectory[-1], nameList[-1]))
        self.saveSignal.emit()

答案 1 :(得分:0)

我可以通过简单地使用 pythoncom 来解决我的情况:

import xlwings as xw
import pythoncom

pythoncom.CoInitialize()
app = xw.apps.add()
app.display_alerts = False
app.screen_updating = False
wb = xw.Book() #Automatically added to app
ws = wb.sheets.add(name='TestSheet')
wb.save()
app.quit() #Automatically closes workbook