Reputation: 720
I am trying to make it where my GUI does not freeze when I run a function, so I put it into a thread, however when I use it as a thread, I get the following error;
Error:
I am currently using xlwings to do something with an excel sheet in the SaveRunThread function
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')
I'd like for it to run the code when called without freezing the GUI. I don't have a MCVE right now, so I just posted partial code.
Upvotes: 3
Views: 1672
Reputation: 1559
I was able to fix in my circumstance by simply using 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
Upvotes: 2
Reputation: 720
I created a workaround for this error. I created my own thread class, and put the code where I did something with xlwings in the run function and use signals to communicate with main thread.
The error occurred when I used app.kill() in the thread.
In my GUI/ui, I created an empty list before thread started, appended the app method, then accessed item in list to kill the excel when thread was finished. This worked for me.
######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()
Upvotes: 0