Langleson
Langleson

Reputation: 103

Qt - What is the correct way to pause execution of a program to wait for user input?

I have a program that runs through a series of steps where the user selects points on a displayed picture. I am unsure of the proper way to pause execution while the user selects these points. Currently I am using something like this:

while(m_MouseCount < 2)
{
    qApp->processEvents(QEventLoop::WaitForMoreEvents);
    if(m_cancelFlag){
        // disconnect mousePressSignal
        return;
    }
}

The problem that I am running into is that when the window is closed during this loop, the program continues to run in the background.

It was brought to my attention that a Finite State Machine would be more appropriate to use in this case, and what I have done here is "horrible pseudo-synchronous" programming. But if I did use a FSM, I would still have the problem of waiting for the FSM to run its course before moving on to the next user selected measurement.

Is there a better way to wait for user input?

Edit

I understand that the Qt's UI is event driven and doesn't generally pause. My program works as follows:

  1. The user is shown a picture and presented with a few options via pushbuttons (Crop, Start Analysis, Cancel)
  2. User Selects Crop
  3. User is prompted to select a rectangle to crop picture (until rectangle is selected program is "paused" - cancel option still exists)
  4. User selects Full Analysis
  5. User is prompted to select measurement 1.
  6. Program "pauses" until two points are selected.
  7. User is prompted to select measurement 2.
  8. Program "pauses" until two points are selected.
  9. This repeats until all measurements have been selected.
  10. Calculations are done based on measurements.

I don't see anyway around some sort of pausing or waiting.

Upvotes: 0

Views: 1156

Answers (1)

Fire Lancer
Fire Lancer

Reputation: 30115

I am not entirely sure on what your end result is meant to be, but when working with UI's, you would normally never try to wait for anything in your own code block / loop. Let QT / the other framework handle how these loops need to work, which may or may not include blocking "modal" dialogues.

Instead you just wait for things (events) to happen. In this case you likely want to wait for QT to tell you that the user clicked on some coordinate in the image, then do whatever you want to do in response.

If you care about the user trying to close the window before completing the task, there will be an event for that as well.

Not real code.

//measurements may want to be a UI thing, such as a table or whatever
//is suitable for your use . You would then also have the ability to go
//back and make corrections, etc.
measurements.push_back(Measurement("Measurement Foo"));
measurements.push_back(Measurement("Measurement Bar"));
currentMeasurement = 0;
myImage->addMouseDownHandler(std::bind(&MyApp::onImageClickedOn, this));
...

void MyApp::startMeasurement()
{
    auto &measurement = measurements[currentMeasurement];
    delete fromMarker; fromMarker = nullptr;
    instructionCtrl->setText(
        "Please select two points to define " +
        measurement.getName());
}
void MyApp::onImageClickedOn(MouseEvent event)
{
    if (!fromMarker)
    {   //Create a marker where the from/start point is
        //Likely wants to be visual/ui object to aid user
        fromMarker = new FromSelectMarker(myImage, event.mousePos);
    }
    else
    {
        //Second point
        auto from = fromMarker.getPos();
        auto to = event.mousePos;
        auto &measurement = measurements[currentMeasurement];
        measurement.setPositions(from, to);

        ++currentMeasurement;
        if (currentMeasurement < measurements.size()
        {
            startMeasurement();
        }
        else
        {
            //finished, do next thing
        }
    }

}

If you really have a complex sequence of users going through a number of different finite "states" with some form of navigation, then maybe a FSM framework is what you want. Or if you don't have a simple one available, you can just tidy up the code to get something similar.

Upvotes: 2

Related Questions