Qt: QAxObject



  • Hallo,

    ich bräuchte mal eure Hilfe. Ich arbeite gerade an einem Qt Widget Projekt mit grafischer Oberfläche und allem drum und dran. Ich habe eine Klasse Excel geschrieben, mit der man wie der Name schon sagt, in ein Excel File schreiben kann.
    Folgendes Problem:
    Ich erstelle mir in einem separanten Thread einen Pointer vom Typ Excel. Wenn ich das mache, dann erhalte ich die Fehlermeldung

    CoCreateInstance failure (CoInitialize wurde nicht aufgerufen.)
    QAxBase::setControl: requested control Excel.Application could not be instantiated
    QAxBase::dynamicCallHelper: Object is not initialized, or initialization failed.

    Wenn ich mir im selben Projekt von main() aus einen Pointer vom Typ Excel erzeuge funktioniert dies aber problemlos. Hat jemand eine Idee woran das liegen könnte?

    Excel.h:

    #ifndef EXCEL_H
    #define EXCEL_H
    
    #include <QtGui>
    #include <QAxObject>
    //#include <QAxWidget>
    #include <QDebug>
    //#include <QList>
    #include <QString>
    
    class Excel
    {
    public:
        explicit Excel();
        void AddHeader();
        void Write(const QString& cell, const QString& value);
        void Autosize();
        void SetFontBold(const QString& startCell, const QString& endCell, bool bold);
        void SetCellColor(const QString& startCell, const QString& endCell, int color);
        void SetFontSize(const QString& startCell, const QString& endCell, int size);
        ~Excel();
    private:
        QAxObject *p_Excel;
        QAxObject *p_Workbooks;
        QAxObject *p_Workbook;
        QAxObject *p_Sheets;
        QAxObject *p_Sheet;
    };
    
    #endif // EXCEL_H
    

    Excel.cpp:

    #include "excel.h"
    
    Excel::Excel()
    {
        p_Excel = new QAxObject("Excel.Application",0);//,0);
        p_Excel->dynamicCall("SetVisible(bool)",true);
        p_Workbooks = p_Excel->querySubObject("WorkBooks");
        p_Workbook = p_Workbooks->querySubObject("Add()");
        p_Sheets = p_Workbook->querySubObject("Worksheets");
        p_Sheet = p_Sheets->querySubObject("Item(int)",1);
        p_Sheet->dynamicCall("SetName(const QString&)", QVariant("Umbrellas"));
        p_Sheet->dynamicCall("Close()");
    }
    
    void Excel::AddHeader()
    {
        SetFontBold("A1", "G1", true);
        SetCellColor("A1","G1",27);
        SetFontSize("A1", "G1", 16);
        Write("A1","Group");
        Write("B1","Ctrl_Group");
        Write("C1","Monitor");
        Write("D1","Device");
        Write("E1","Alias");
        Write("F1","Variable");
        Write("G1","Value");
    }
    
    void Excel::Write(const QString& cell, const QString& value)
    {
        QAxObject *p_Entry = p_Sheet->querySubObject("Range(const QVariant&)", QVariant(cell));
        p_Entry->dynamicCall("SetValue(const QVariant&)", QVariant(value));
        p_Entry->dynamicCall("Close()");
        Autosize();
    }
    
    void Excel::SetCellColor(const QString& startCell, const QString& endCell, int color)
    {
        QAxObject *p_Range = p_Sheet->querySubObject("Range(const QString&, const QString&)", QString(startCell), QString(endCell));
        p_Range->querySubObject("Interior")->setProperty("ColorIndex",color);
    }
    
    void Excel::SetFontSize(const QString& startCell, const QString& endCell, int size)
    {
        QAxObject *p_Range = p_Sheet->querySubObject("Range(const QString&, const QString&)", QString(startCell), QString(endCell));
        p_Range->querySubObject("Font")->setProperty("Size",size);
    }
    
    void Excel::SetFontBold(const QString& startCell, const QString& endCell, bool bold)
    {
        QAxObject *p_Range = p_Sheet->querySubObject("Range(const QString&, const QString&)", QString(startCell), QString(endCell));
        p_Range->querySubObject("Font")->setProperty("Bold",bold);
    }
    
    void Excel::Autosize()
    {
        QAxObject* p_Columns = p_Sheet->querySubObject("Columns(const QString&)", "a:z");
        p_Columns->dynamicCall("AutoFit()");
        p_Columns->dynamicCall("Close()");
    }
    
    Excel::~Excel()
    {
        delete p_Excel;
    }
    


  • HannesKannNIX schrieb:

    Hat jemand eine Idee woran das liegen könnte?

    Daran:

    HannesKannNIX schrieb:

    CoCreateInstance failure (CoInitialize wurde nicht aufgerufen.)

    Ich glaub, du wirst mit COM Apartment Marshalling noch sehr viel Spass haben 😉



  • Ich habe aber keinen Spaß daran 😞
    Ich weiß, dass es an dem Fehler liegt, aber wie behebe ich ihn???



  • Also ich bin nun ein bisschen weitergekommen. Mein Thread besitzt einen Run(). Innerhalb des run() ist es mir nicht möglich ein Objekt der Klasse Excel zu erzeugen und zwar aus dem Grund, dass innerhalb dieser Excel Klasse neue QAxObjects erzeugt werden.
    Inzwischen habe ich die Klasse Excel woanders erzeugt und mit movetothread() diesem Thread hinzugefügt. Mit Signals und Slots habe ich nun die Threadklasse und die Klasse Excel miteinander verbunden. Sobald in der Klasse Excel ein neues QAxObject erzeugt wird, hängt es sich wieder auf 😞
    Wie kann ich einem Thread eine Klasse übergeben, die dynamisch mehrere QAxObjects erzeugt???



  • Ich habe ActiveQt nie benutzt und weiß nicht, wie sie das handhaben. Aber normal musst du bei COM in jedem Thread CoInitialize aufrufen.



  • Die Lösung war wirklich die Initialisierung.
    Innerhalb run() muss man einfach CoInitialize(NULL;COINIT_MULTITHREADED) hinzufügen und alles läuft wunderbar.
    Vielen Dank euch allen.


Anmelden zum Antworten