无法在Qlabel中使用setPixmap显示图像序列

时间:2014-07-14 20:22:30

标签: qt qpixmap qlabel

我正在尝试使用setPixmap通过Qlabel显示一系列图像。我有一个包含图像文件名的QStringList和一个for循环,它在每个图像后等待5秒钟后迭代图像。但是,只显示最后一个图像文件。目前,在第一次迭代的等待期间屏幕保持空白,直到最后显示最后一个图像。我已经读过,使用for循环不会工作,我应该使用信号和插槽。我对这个概念不熟悉,我真的很感激一个例子,指出我正确的方向。

这是我目前的代码:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),ui(new Ui::MainWindow){
   ui->setupUi(this);
   QStringList images;
   QString imageName;
   images << "redScreen.png" << "blueScreen.png" << "greenScreen.png";

   for(int x=0; x < images.size(); x++){
      imageName = images.at(x);
      this->displayScreen(imageName, 5);
   } 
}

void MainWindow::displayScreen(QString imageName, int wait){
   QTimer t;
   QEventLoop loop;
   QPixmap myImage;

   myImage.load(":/images/" + imageName);
   ui->imageLabel->setPixmap(myImage);
   ui->imageLabel->repaint();

   // 5 second wait between next iteration
   t.start(wait*1000);
   connect(&t, SIGNAL(timeout()), &loop, SLOT(quit()));
   loop.exec();
}

3 个答案:

答案 0 :(得分:1)

可重入的wait-via-eventloop hack是难以诊断的错误的重要来源。不要使用它。您需要实例化自己的事件循环非常非常罕见。即使是相当复杂的项目也可以完全避免它。

你应该只是运行一个计时器并对计时器滴答做出反应。这是一个例子:

#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();
}

答案 1 :(得分:0)

类似于以下的代码必须适用于您提到的任务。 (虽然需要清洁/班级组织)

  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);
}

答案 2 :(得分:0)

最好的解决方案是使用几个QTimer的DeepBlack,但是如果你想冒风险,你可以尝试在显示图像的for循环中插入processEvent()函数。