【问题标题】:Thread that calls a xlwings function returns pywintype error调用 xlwings 函数的线程返回 pywintype 错误
【发布时间】:2021-07-16 08:17:00
【问题描述】:

我试图让它在我运行一个函数时我的 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,所以我只发布了部分代码。

【问题讨论】:

  • 您使用的是什么版本的 xlwings?
  • @FelixZumstein 我正在使用当前版本:0.15.8

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


【解决方案1】:

我可以通过简单地使用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

【讨论】:

  • 我遇到了类似的问题,您的解决方案似乎有效。你能解释一下这是如何工作的吗?特别是pythoncom.CoInitialize()
  • 其实没有。在这一点上,我只是认为pythoncom.CoInitialize() 是允许使用 xlwings 进行多处理的魔术代码。我什至用它来解决单个 xlwings 线程的问题。
【解决方案2】:

我为这个错误创建了一个解决方法。我创建了自己的线程类,并将我用 xlwings 做某事的代码放在 run 函数中,并使用信号与主线程通信。

当我在线程中使用 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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多