0

I'm trying to change the image on QLabel in Qt.

At first, I did the basic set image as follows:

void MainWindow::setMainDisplayNew(QString imageName){
     QPixmap pix7 = imageName;
     QPixmap pix8 = pix7.scaled(QSize(720,480), Qt::KeepAspectRatio);
     ui->mainDisplay->setStyleSheet(imageName);
     ui->mainDisplay->setPixmap(pix8);
}

Now I want to change this so I can pass 2 arrays. List of images and duration they should appear for and I want the display to show them for the indicated duration.

        void MainWindow::setMainDisplay(QString imageName[], int size)
{
    for(unsigned int i=0; i<size; i++)
    {
        QTimer * timer = new QTimer(this);
        timer->setSingleShot(true);
        connect(timer, &QTimer::timeout, [=](){
            setMainDisplayNew(imageName[i]);
            timer->deleteLater(); // ensure we cleanup the timer
        });
        timer->start(3000);
    }
}

EDIT

With the help of the responses, I reached the above code. I am sending the 3 images. It is display the final image after 3 seconds and stays as is... Any help?

Syntax_Error
  • 5,964
  • 15
  • 53
  • 73
  • ``while(true)`` makes your application never get to process the timeout-event. – Sebastian Lange Oct 28 '15 at 13:15
  • I'm not sure why this has been down-voted; it's a reasonable question and a simple mistake to make for those who have had little experience with event-driven programming. – TheDarkKnight Oct 28 '15 at 13:28
  • the timer->start(3000) line is wrong. That will make all the timers fire at the same time. You want them to be staggered, so you need to use a different variable for each timer start time (i.e. first one at 0 ms, second one at 3000ms, third one at 6000ms, and so on). – ScottG Oct 28 '15 at 20:41
  • @ScottG thanks that seems to cover it up! One final question, how can I make it run continuously? – Syntax_Error Oct 29 '15 at 07:15

1 Answers1

4
while(true){

This is your problem. Qt is an event-driven framework. The while(true) prevents events from being processed. Such events include the timeout from the QTimer and updating of the GUI. You need to allow the function to exit.

In addition, you're not cleaning up your timers, so you're leaking memory every time you enter the function (although that's currently only once!). You can clean up with a call to deleteLater.

Using C++ 11, it would be something like this: -

for(int i=0; i<mySize; i++)
{
    QTimer * timer = new QTimer(this);
    timer->setSingleShot(true);

    connect(timer, &QTimer::timeout, [=](){
        setMainDisplayNew(imageName[i]);
        timer->deleteLater(); // ensure we cleanup the timer
    });

    timer->start(duration[i]);
}
Community
  • 1
  • 1
TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85
  • You're right, and although you could get it to work by adding a 'QApplication::processEvents();' inside the while loop, it would not change the fact that this is bad design in the first place. – zeFrenchy Oct 28 '15 at 13:20
  • Indeed, processEvents should not be called here. – TheDarkKnight Oct 28 '15 at 13:21
  • @TheDarkKnight thanks for the quick response! I implemented it, it is giving me timeout() was not declared in this scope. Any advice? – Syntax_Error Oct 28 '15 at 15:35
  • Sorry, I missed the scope in the connect call. It should be *&QTimer::timeout*. I've updated the answer to reflect this. – TheDarkKnight Oct 28 '15 at 15:48
  • @TheDarkKnight I think it should be &QTimer::timeout ?? it was giving no matching function with timeout(). it is still not working properly, I updated question – Syntax_Error Oct 28 '15 at 17:03
  • Correct, it's &QTimer::timeout, as it takes a reference to a function. This also means that using this connection syntax allows the connection to any class function, not just those defined as a slot. – TheDarkKnight Oct 28 '15 at 22:44