With an understanding that "show a random image numbered 1-28 in a random time ranging 1.5-3secs then show it for 250milisecs" means "show a random image numbered 1-28 in a random time between 1.75s and 3.25s", the below does it.
The code requires Qt 5.x and a C++11 compiler. I tried to highlight proper use of C++11 pseudorandom number facilities. I don't know the end-use of your code, but if you substituted std::mt19937_64
for random_engine
, it'd be good enough for running psychological research as far as randomness goes.
The images shown are randomly drawn from a set of 28 images. Each of the source images are also randomly generated.
Notice the conspicuous absence of any form of sleep or busy-looping, and zealous use of lambdas. This code wouldn't be any shorter were it written in Python. That's what C++11 buys you: conciseness, among other things :)
#include <QApplication>
#include <QStateMachine>
#include <QTimer>
#include <QStackedWidget>
#include <QPainter>
#include <QLabel>
#include <QPushButton>
#include <random>
typedef std::default_random_engine random_engine;
QImage randomImage(int size, random_engine & rng) {
QImage img(size, size, QImage::Format_ARGB32_Premultiplied);
img.fill(Qt::white);
QPainter p(&img);
p.setRenderHint(QPainter::Antialiasing);
int N = std::uniform_int_distribution<>(25, 200)(rng);
std::uniform_real_distribution<> dP(0, size);
std::uniform_int_distribution<> dC(0, 255);
QPointF pt1(dP(rng), dP(rng));
for (int i = 0; i < N; ++i) {
QColor c(dC(rng), dC(rng), dC(rng));
p.setPen(QPen(c, 3));
QPointF pt2(dP(rng), dP(rng));
p.drawLine(pt1, pt2);
pt1 = pt2;
}
return img;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
std::random_device rd;
random_engine gen(rd());
int imageSize = 300;
QList<QImage> images;
for (int n = 0; n < 28; ++n) images << randomImage(imageSize, gen);
std::uniform_int_distribution<> dImage(0, images.size()-1);
QStackedWidget display;
QPushButton ready("I'm Ready!");
QLabel label, labelHidden;
display.addWidget(&ready);
display.addWidget(&label);
display.addWidget(&labelHidden);
QTimer splashTimer;
QStateMachine machine;
QState s1(&machine), s2(&machine), s3(&machine), s4(&machine);
splashTimer.setSingleShot(true);
QObject::connect(&s1, &QState::entered, [&]{
display.setCurrentWidget(&ready);
ready.setDefault(true);
ready.setFocus();
});
s1.addTransition(&ready, "clicked()", &s2);
QObject::connect(&s2, &QState::entered, [&]{
label.setPixmap(QPixmap::fromImage(images.at(dImage(gen))));
display.setCurrentWidget(&label);
splashTimer.start(250 + std::uniform_int_distribution<>(1500, 3000)(gen));
});
s2.addTransition(&splashTimer, "timeout()", &s3);
QObject::connect(&s3, &QState::entered, [&]{
display.setCurrentWidget(&labelHidden);
splashTimer.start(2000);
});
s3.addTransition(&splashTimer, "timeout()", &s4);
QObject::connect(&s4, &QState::entered, [&]{
display.setCurrentWidget(&label);
splashTimer.start(3000);
});
s4.addTransition(&splashTimer, "timeout()", &s1);
machine.setInitialState(&s1);
machine.start();
display.show();
return a.exec();
}