1

I have to create a cookie factory simulation program for an assignment. The program's GUI uses normal Qt widgets (such as: labels, buttons, and line edits) to control the simulation variables and objects. I already created the GUI, but I don't know how to do the simulation.

Our teacher suggested using threads (one per machine). I read on QThreads, but got the impression (from this link) that they are not really ideal for accessing objects from other threads, and I don't really know how to create or handle them.

However, the simulation is simple enough that (I believe) it could be done with only one loop (one thread), but I don't know how to create this loop in the QMainWindow class.

So, my main question is: How can I run a loop that can access the GUI, can be accessed by the GUI (so that it can change machines' values), and can access the machines? I just don't really know how to connect the GUI and the simulation.

Thanks, sorry for the long post.

Edit #1: Pseudo-code of what I am trying to do:

// Machines' initialization:
rawMaterialsTransport = new RawTransport();
doughMachine->conveyour = doughConveyour;

// Simulation loop:
lastTime = 0
while(running) {
    // Handle pauses.
    while(simulationPaused) {
        sleep(100);
    }

    // Update machines/do the simulation
    timePassed = now() - lastTime
    lastTime = now()

    rawMaterialsTransport->update(timePassed);
    doughMachine->update(timePassed);
    chocolateMachine->update(timePassed);
    doughConveyour->update(timePassed);

    // Update the GUI
    chocolateGramsProcessedLabel->setText(to_string(chocolateMachine->gramsProcessed()));

    // Sleep so as to not waste 
    sleep(100);
}


// On the GUI side:
onLineEditEnter() {
    doughMachine->gramsPerSecond = double(lineEdit->text);
}

onPauseButtonPress() {
    simulationPaused = !simulationPaused;
}
sempiedram
  • 137
  • 12
  • I am not sure if I understand what you are trying to do exactly. Maybe show some code. Depending on that I see different solutions. Probably: Don't use a loop but signals and slots. Possibly: QCoreApplication::processEvents() (don't), QEventLoop, QThread::exec(), QObject::moveToThread(), or QTimer::singleShot(). It's also fine to send signals across threads. – SteakOverflow Oct 05 '17 at 06:32
  • I will try to add some pseudo-code. – sempiedram Oct 05 '17 at 06:41
  • 3
    If you decide not to use Threads, I agreed with you that they do not seem necessary here, I suggest that you user a set of QTimer connected with Slots rather than sleep() ... by the way sleep in the main thread is almost never a good idea. – Marco Oct 05 '17 at 06:57
  • Yes, I tried a sleep in the main thread, it made the GUI unusable. – sempiedram Oct 05 '17 at 07:01
  • 1) You may use `QEventLoop` + `QTimer` (or other signal provider) for sleep simulation. 2) You may call `QApplication::processEvents` inside your loop to force GUI to be responsive. But it is a bad practice. – Dmitry Sazonov Oct 05 '17 at 08:25
  • I call this "non-blocking worker", there is an example for an interruptible, progress tracking file copy here: https://stackoverflow.com/questions/32952474/non-blocking-worker-interrupt-file-copy/32952945#32952945 – dtech Oct 05 '17 at 10:37

1 Answers1

2

You could use signals and slots.

In the GUI, you connect the signals emitted by your GUI items (the buttons, line edits, etc.) to a custom slot which does the business logic. For example buttons emit the clicked signal when pressed.

If the processing of the business logic in the slot has terminated, you emit another signal that is connected to a slot in your widget which updates the GUI.

If the GUI hangs, i.e. the processing of the business logic takes too much time, you have to start another thread for doing the business logic. Signals and slots also work across threads.

References

Christophe Weis
  • 2,518
  • 4
  • 28
  • 32
  • Wouldn't there be problems with using slots, because the simulation is continuously running (as long as the pause button is not pressed)? Anyway, thank you very much. I kinda' feel dumb. I will read your links. – sempiedram Oct 05 '17 at 06:37
  • @sempiedram That depends on your needs. To give you an idea, I edited the post and added an example where a thread starts a loop. – Christophe Weis Oct 05 '17 at 06:53