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
Qt 6.11 is out! See what's new in the release blog

QProgressBar and ActiveX

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 849 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