Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QProgressBar and ActiveX

QProgressBar and ActiveX

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 269 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    neo_qt
    wrote on last edited by
    #1

    With Qt Creator, I have inserted a progress bar using the QProgressBar object. I would like the progress bar displaying the busy mode while doing some operations in Excel ( called via ActiveX)

    If I am not wrong QAxObject will start another thread so the GUI should not hang out during the ActiveX call/operations. Could you tell me what I did wrong ?

    Here is my code

    // progressBar busy mode 
    ui->progressBar->setMinimum(0);
    ui->progressBar->setMaximum(0);
    ui->progressBar->show();
    
    // Kick Excel using ActiveX
    CoInitialize(0);
    QAxObject excel( "Excel.Application", 0 );
    
    //Some Excel operations... during few seconds
    
    // Quit Excel
    excel.dynamicCall("Quit()");
    
    // Revert to normal mode
    ui->progressBar->setMaximum(100);
    
    1 Reply Last reply
    0
    • hskoglundH Offline
      hskoglundH Offline
      hskoglund
      wrote on last edited by hskoglund
      #2

      Hi, while QAxObject can do many fancy things, starting another thread outside of the GUI is not of them :-(

      But if you add some QThread/worker code and move the QAxObject stuff in there, it will work nicely with the GUI.
      Here's an example that updates a progress bar: create an empty vanilla Widget app, add axcontainer to the QT line in the .pro file, then change mainwindow.h to this:

      #include <QMainWindow>
      #include "windows.h"    // for the CoInitialize() call
      #include "QAxObject"
      #include <QThread>
      
      namespace Ui { class MainWindow; }
      
      class ExcelWorker : public QObject
      {
          Q_OBJECT
      
      public slots:
          void doWork(int n)
          {
              CoInitialize(0);
              auto excel = new QAxObject("Excel.Application",0);
              if (nullptr == excel)
                  return;
      
              excel->setProperty("Visible",true);
              auto workbooks = excel->querySubObject("Workbooks");
              auto workbook  = workbooks->querySubObject("Add");
              auto sheets    = workbook->querySubObject("Worksheets");
              auto sheet     = sheets->querySubObject("Item(int)",1);
      
              for (int i = 0; (i < n); ++i)
              {
                  sheet->querySubObject("Cells(int,int)",i % 10 + 1,i / 10 + 1)->setProperty("Value",i);
                  QThread::msleep(100);  // simulate some heavy munging
      
                  emit oneReady(i);
              }
          }
      
      signals:
          void oneReady(int i);
      };
      
      class MainWindow : public QMainWindow
      {
          Q_OBJECT
          QThread excelThread;
      
      public:
          MainWindow(QWidget *parent = nullptr);
          ~MainWindow();
      
      private slots:
          void oneReadyFromExcel(int i);
          void on_pushButton_clicked();
      
      signals:
          void doExcelWork(int n);
      
      private:
          Ui::MainWindow *ui;
      };
      

      and change the mainwindow.cpp to this:

      #include "mainwindow.h"
      #include "ui_mainwindow.h"
      #include "qtimer.h"
      
      MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
      {
          ui->setupUi(this);
      
          auto ew = new ExcelWorker;
          ew->moveToThread(&excelThread);
          connect(this,&MainWindow::doExcelWork,ew,&ExcelWorker::doWork);
          connect(ew,&ExcelWorker::oneReady,this,&MainWindow::oneReadyFromExcel);
      
          excelThread.start();
      }
      
      MainWindow::~MainWindow()
      {
          delete ui;
      }
      
      void MainWindow::on_pushButton_clicked()
      {
          emit doExcelWork(100);
      }
      
      void MainWindow::oneReadyFromExcel(int i)
      {
          ui->progressBar->setValue(i);
      }
      

      Finally add one progress bar and a push button and connect the clicked() signal from the push button to starting Excel and you're good to go.

      Edit: I just tested it, it runs ok but crashes when exiting the app, the example is missing the cleanup of the worker thread and quitting Excel, but I think you'll get the idea anyhow..

      N 1 Reply Last reply
      1
      • hskoglundH hskoglund

        Hi, while QAxObject can do many fancy things, starting another thread outside of the GUI is not of them :-(

        But if you add some QThread/worker code and move the QAxObject stuff in there, it will work nicely with the GUI.
        Here's an example that updates a progress bar: create an empty vanilla Widget app, add axcontainer to the QT line in the .pro file, then change mainwindow.h to this:

        #include <QMainWindow>
        #include "windows.h"    // for the CoInitialize() call
        #include "QAxObject"
        #include <QThread>
        
        namespace Ui { class MainWindow; }
        
        class ExcelWorker : public QObject
        {
            Q_OBJECT
        
        public slots:
            void doWork(int n)
            {
                CoInitialize(0);
                auto excel = new QAxObject("Excel.Application",0);
                if (nullptr == excel)
                    return;
        
                excel->setProperty("Visible",true);
                auto workbooks = excel->querySubObject("Workbooks");
                auto workbook  = workbooks->querySubObject("Add");
                auto sheets    = workbook->querySubObject("Worksheets");
                auto sheet     = sheets->querySubObject("Item(int)",1);
        
                for (int i = 0; (i < n); ++i)
                {
                    sheet->querySubObject("Cells(int,int)",i % 10 + 1,i / 10 + 1)->setProperty("Value",i);
                    QThread::msleep(100);  // simulate some heavy munging
        
                    emit oneReady(i);
                }
            }
        
        signals:
            void oneReady(int i);
        };
        
        class MainWindow : public QMainWindow
        {
            Q_OBJECT
            QThread excelThread;
        
        public:
            MainWindow(QWidget *parent = nullptr);
            ~MainWindow();
        
        private slots:
            void oneReadyFromExcel(int i);
            void on_pushButton_clicked();
        
        signals:
            void doExcelWork(int n);
        
        private:
            Ui::MainWindow *ui;
        };
        

        and change the mainwindow.cpp to this:

        #include "mainwindow.h"
        #include "ui_mainwindow.h"
        #include "qtimer.h"
        
        MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
        {
            ui->setupUi(this);
        
            auto ew = new ExcelWorker;
            ew->moveToThread(&excelThread);
            connect(this,&MainWindow::doExcelWork,ew,&ExcelWorker::doWork);
            connect(ew,&ExcelWorker::oneReady,this,&MainWindow::oneReadyFromExcel);
        
            excelThread.start();
        }
        
        MainWindow::~MainWindow()
        {
            delete ui;
        }
        
        void MainWindow::on_pushButton_clicked()
        {
            emit doExcelWork(100);
        }
        
        void MainWindow::oneReadyFromExcel(int i)
        {
            ui->progressBar->setValue(i);
        }
        

        Finally add one progress bar and a push button and connect the clicked() signal from the push button to starting Excel and you're good to go.

        Edit: I just tested it, it runs ok but crashes when exiting the app, the example is missing the cleanup of the worker thread and quitting Excel, but I think you'll get the idea anyhow..

        N Offline
        N Offline
        neo_qt
        wrote on last edited by
        #3

        @hskoglund Thank you very much for the explanation and the code. I have not tested fully your code yet but now I understand why my code did not work as I expect.

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved