Trouble displaying sequence of images with setPixmap in Qlabel

牧云@^-^@ 提交于 2019-12-04 18:31:18

The reentrant wait-via-eventloop hack is a great source of hard-to-diagnose bugs. Don't use it. It's very, very rare that you'll need to instantiate your own event loop. Even rather complex projects can entirely avoid it.

You should simply run a timer and react to timer ticks. Here's one example:

#include <QApplication>
#include <QImage>
#include <QGridLayout>
#include <QLabel>
#include <QBasicTimer>

class Widget : public QWidget {
    QGridLayout m_layout;
    QLabel m_name, m_image;
    QStringList m_images;
    QStringList::const_iterator m_imageIt;
    QBasicTimer m_timer;
    void timerEvent(QTimerEvent * ev) {
        if (ev->timerId() == m_timer.timerId()) tick();
    }
    void tick() {
        display(*m_imageIt);
        m_imageIt ++;
        const bool loop = false;
        if (m_imageIt == m_images.end()) {
            if (loop)
                m_imageIt = m_images.begin();
            else
                m_timer.stop();
        }
    }
    void display(const QString & imageName) {
        QImage img(":/images/" + imageName);
        m_name.setText(imageName);
        m_image.setPixmap(QPixmap::fromImage(img));
    }
public:
    Widget(QWidget * parent = 0) : QWidget(parent), m_layout(this) {
        m_images << "redScreen.png" << "blueScreen.png" << "greenScreen.png";
        m_imageIt = m_images.begin();
        m_layout.addWidget(&m_name, 0, 0);
        m_layout.addWidget(&m_image, 1, 0);
        tick();
        m_timer.start(5000, Qt::CoarseTimer, this);
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

A code similar to the below must work for the task you mentioned. ( needs cleaning/class organization though )

  QTimer timer;
  int x=0;
  QStringList images;
  QString imageName;


  MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),ui(new Ui::MainWindow){
   ui->setupUi(this);

   images << "redScreen.png" << "blueScreen.png" << "greenScreen.png";

   connect( &timer, SIGNAL(timeout()), this, SLOT(ChangeImageSlot()) );
   timer.start(5000);

}

void ChangeImageSlot()
{
   imageName = images.at(x++);
   this->displayScreen(imageName, 5);

   if( x < images.size() )
      timer.start(5000);
}

Best solution is DeepBlack with a couple of QTimer, but if you want at you risk you can try insert an processEvent() function inside the for loop of display image.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!