[SOLVED] MS Excel and QThread
Here I am again with a new problem on acessing MS Excel with QT, this time involving threads.
I have the folowing code that perform some Excel actions (I've "posted":http://developer.qt.nokia.com/forums/viewthread/13656/ this code regarding another problem before):
QAxObject* excel = new QAxObject( "Excel.Application", 0 );
QAxObject* workbooks = excel->querySubObject( "Workbooks" );
QAxObject* workbook = workbooks->querySubObject( "Open(const QString&)", "C:\Users\LocalDev\teste.xls" );
QAxObject* sheets = workbook->querySubObject( "Worksheets" );
sheets->dynamicCall("Add()"); QAxObject* sheet = sheets->querySubObject( "Item( int )", 1 ); sheet->setProperty("Name","Nova Planilha"); QAxObject * range = sheet->querySubObject("Cells( int, int)",1,1); range->setProperty("Value", QVariant(1234)); QAxObject * shapes = sheet->querySubObject("Shapes"); shapes->dynamicCall("AddPicture( QString&, bool, bool, double, double, double, double","C:\\Users\\LocalDev\\Pictures\\cvrd1.png",true,true,100,100,70,70); excel->setProperty("DisplayAlerts", false); excel->dynamicCall("Save()"); //workbook->dynamicCall("Close()"); //excel->dynamicCall("Quit()"); workbook->dynamicCall("Close (Boolean)", true); excel->dynamicCall("Quit (void)"); delete shapes; delete range; delete sheet; delete sheets; delete workbook; delete workbooks; delete excel;
As my specifc code may take a long time to finalize I decided to run it in a separate thread. For this task, I subclassed a QThread class and put this code inside the method "run()" of my new inherited class.
When executing the code, if I call the "run()" method of my class directly (this way not executing as a thread) then the code works fine, but if I call the method "start()" (to execute as a thread) then it breaks at line 4 (while trying to open the file) with a popup message reporting an "Exception Triggered". The popup message says:
"The inferior stopped because it triggered an exception.
Stopped in thread 9 by: Exception at 0x45728a, code: 0x0000005, read access violation at:0x0, flags=0x0"
Well, I can't understand why this code does not execute correctly as a separate thread. I may be doing something silly and as I'm not that experienced with QT I'm asking if someone could help me, please.
Thanks for the attention.
Are you developing in VS? If yes, Run as debug profile and take a look at Local variables.
Isn't QAxObject * range are QAxObject shape child? Maybe it got deleted early in delete shapes. Check the delete instructions....
I'm developing with Qt Creator and already executing it in debug mode.
I don't know if I got your point correctly, but this code executes fine if it is in the main program thread and it breaks in the 4th line if exactly the same code is executed in a separete thread. Maybe it is not well written, but it works. I've also checked the variables in debugger but couldn't notice any problem in them.. Furthermore, all the variables this code needs are declared there so it does't depend on any other variable delcared outside the method body.
Anyway, thanks for your answer.
I found the solution. We must call "CoInitialize()" when working with ActiveQt in threads. I just called it before running my code and it works well.
do you use MSVC compiler? i cannot find this CoInitialize() function... Could you share more details of your solution, since this is a rare topic...
yes, I use MSVC compiler.
CoInitialize() is a function from Windows API to initialize the COM Library, it is not from QT framework.
Sice the time of my last post in this thread I don't deal with this project anymore, so I may not remember all the details. But my class definition header has the following include files:
In the run() method of my QThread inherited class I call the CoInitialize() before using other funcitons:
And this should be enough.
Hope it helps.
Unfortunately CoInitialize only works in MSVC, but i need to use mingw, so i could not init my QAxObject in a different thread then the main thread. I've solved it with a workaround, but your comment will be useful in the future when i need this again, and i'll use MSVC.