我正在尝试使用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();
}
答案 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()函数。