Есть сцена, есть вью. На вью один итем - анимированная картинка. В методе advance, устанавливается следующий кадр. Проделываю следующие шаги:
1. Запускаю таймер в главном гуи потоке, по таймауту которого вызывается advance сцены - все ок, анимацию видно.
2. Останавливаю таймер - анимация прекращается, логично.
3. Запускаю поток, в run() которого вызывается advance этой же сцены - анимации не видно, оно и верно потому как потоки разные, ну да и хрен. Теперь самое важное:
4. Останавливаю поток.
5. Опять запускаю шаг 1, и... НЕ АПДЕЙТИТСЯ, НЕТ АНИМАЦИИ!
Куда все подевалось?
Вобщем вот код, помогите, чем сможете:
#ifndef DIALOG_H
#define DIALOG_H
#include <QtGui/QDialog>
#include <QGraphicsPixmapItem>
#include <qmovie.h>
#include <qthread.h>
#include <qmutex.h>
class QTimer;
class QGraphicsScene;
class Item : public QGraphicsPixmapItem {
public:
Item() {
movie.setFileName("pp.mng");
movie.jumpToNextFrame();
setPixmap(movie.currentPixmap());
}
void advance(int phase) {
if (!phase)
movie.jumpToNextFrame();
else setPixmap(movie.currentPixmap());
}
private:
QMovie movie;
};
class Thread : public QThread {
Q_OBJECT
public:
Thread(QObject *parent = 0);
~Thread(){}
QGraphicsScene* graphicsScene() { return scene; }
public slots:
void stop();
protected:
void run();
private:
QGraphicsScene *scene;
bool stopped;
QMutex mutex;
};
class Dialog : public QDialog {
Q_OBJECT
public:
Dialog(QWidget *parent = 0, Qt::WFlags flags = 0);
~Dialog();
private:
Thread *thread;
QTimer *timer;
};
#endif // DIALOG_H
#include "dialog.h"
#include <qtimer.h>
#include <qlayout.h>
#include <qpushbutton.h>
#include <qgraphicsview.h>
#include <qgraphicsscene.h>
Thread::Thread(QObject *parent):QThread(parent) {
scene = new QGraphicsScene(this);
scene->setSceneRect(0,0,320,240);
scene->addItem(new Item());
}
void Thread::run() {
mutex.lock();
stopped = false;
while(!stopped) {
mutex.unlock();
scene->advance();
mutex.lock();
}
mutex.unlock();
}
void Thread::stop() {
QMutexLocker ml(&mutex);
stopped = true;
}
Dialog::Dialog(QWidget *parent, Qt::WFlags flags)
: QDialog(parent, flags)
{
thread = new Thread(this);
QPushButton *startGUI = new QPushButton("Start in GUI", this);
QPushButton *stopGUI = new QPushButton("Stop", this);
QPushButton *startThread = new QPushButton("Start in thread", this);
QPushButton *stopThread = new QPushButton("Stop", this);
QGraphicsView *view = new QGraphicsView(thread->graphicsScene(), this);
timer = new QTimer(this);
timer->setInterval(40);
QHBoxLayout *topLt = new QHBoxLayout;
topLt->addWidget(startGUI);
topLt->addWidget(stopGUI);
topLt->addStretch();
topLt->addWidget(startThread);
topLt->addWidget(stopThread);
QVBoxLayout *lt = new QVBoxLayout(this);
lt->addLayout(topLt);
lt->addWidget(view);
connect(startGUI, SIGNAL(clicked()), timer, SLOT(start()));
connect(stopGUI, SIGNAL(clicked()), timer, SLOT(stop()));
connect(startThread, SIGNAL(clicked()), thread, SLOT(start()));
connect(stopThread, SIGNAL(clicked()), thread, SLOT(stop()));
connect(timer, SIGNAL(timeout()), thread->graphicsScene(), SLOT(advance()));
}
Dialog::~Dialog()
{
}
Кому не охота копировать и вставлять -
http://www.creobyte.com/viewscene.zip архив с vs2003 проектом и исходниками.