How to call plain function from exec()?

772 views Asked by At

I have 2 classes: one maintains some loop (at leas for 2-3 minutes; and is inherited from QObject) and another shows up a progress dialog (inherited from QDialog). I want to start the loop as soon as the dialog is shown. My first solution was:

 int DialogClass::exec()
 {
     QTimer::singleShot(0, LoopClassPointer, SLOT(start()));
     return __super::exec();
 }

There is a problem with throwing exceptions from slots. so I considered a possibility to make public slot start() just a public function. But now I don't know how to make it works well. Things like this:

int DialogClass::exec()
{
     LoopClassPointer->start();
     QApplication::processEvents();
     return __super::exec();
}

don't help. The dialog doesn't appears. Is there a common approach to this kind of situations?

some details, according to questions:

  1. I have to work with system with its own styles, so we have a common approach in creating any dialogs: to inherit them from stytle class, which is inherited from QDialog.

  2. my 'LoopClassPointer' is an exported class from separate dll (there is no UI support in it).

  3. I have a 'start' button in main app, which connected with a slot, which creates progress dialog and 'LoopClassPointer'. at the moment I send 'LoopClassPointer' instance in the dialog and don't whant to make significant changes in the architecture.

2

There are 2 answers

0
Valentin H On

Take a look at QtDemo->Concurrent Programming->Run function

e.g. in Qt 4.8: http://qt-project.org/doc/qt-4.8/qtconcurrent-runfunction.html

0
TheDarkKnight On

In this situation, I recommend you separate the logic of the loop from the dialog. Gui elements should always be kept separate.

It's great that your worker class is derived from QObject because that means you can start it running on a separate thread: -

QThread* m_pWorkerThread = new QThread;
Worker* m_pWorkerObject  = new Worker; // assuming this object runs the loop mentioned

// Qt 5 connect syntax
connect(m_pWorkerThread, &QThread::started, m_pWorkerObject, &WorkerObject::start);
connect(m_pWorkerThread, &QThread::finished, m_pWorkerThread, &QThread::deleteThis);

m_pWorkerObject->moveToThread(m_pWorkerThread);
m_pWorkerThread->start();

If you're not familiar with using QThread, then start by reading this.

The only other thing you require is to periodically send signals from your worker object with progress of its work and connect that to a slot in the dialog, which updates its display of the progress.