Запуск основной программы после закрытия заставки
Использую достаточно медленный ARM контроллер. Поднял на нем линукс.
Перед запуском основной программы появляется заставка на 5 секунд. После происходит загрузка. Понятно что гиф анимация требует достаточно ресурсов ЦПУ, которых и так нет.
Проблема заключается в одновременном запуски конструктора и окна "mainwindow" и гиф анимации. Охота разделить их во времени, чтобы сначала была гиф анимация после запуск конструктора окна "mainwindow" и переход на основную программу.
Вот код, что сделал:
// Класс заставки
class Splash : public QObject {
Q_OBJECT
public:
Splash() {
processLabel = new QLabel();
connect(&_timer, SIGNAL(timeout()), this, SLOT(emitFinished()));
connect(&_temerMainWindow, SIGNAL(timeout()), this, SLOT(emitShowMainWindow()));
}
// Показываем заставку и стартуем таймер
void start() {
movie = new QMovie("./image/Titul.gif");
processLabel->resize(640,480);
processLabel->setMovie(movie);
processLabel->setWindowFlags(Qt::FramelessWindowHint);
processLabel->setAlignment(Qt::AlignCenter);
processLabel->setGeometry(QStyle::alignedRect(Qt::LeftToRight,Qt::AlignCenter,processLabel->size(),qApp->desktop()->availableGeometry()));
movie->start();
processLabel->show();
_temerMainWindow.start(4500);
_timer.start(5000);
}
signals:
// Сигнал завершения работы заставки
void finished();
private slots:
void emitFinished()
{
movie->stop();
movie->deleteLater();
processLabel->deleteLater();
_timer.stop();
}
void emitShowMainWindow()
{
_temerMainWindow.stop();
MainWindow w; // Не хочет запускать окно MainWindow программа падает. В чем дело?
w.setWindowFlags(Qt::FramelessWindowHint);
w.show();
emit finished();
}
private:
QLabel *processLabel;
QMovie *movie;
QTimer _timer;
QTimer _temerMainWindow;
};
#include "main.moc"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Splash splash;
splash.start();
return a.exec();
}
Программа падает при вызове окна 'MainWindow'.
Ответы (1 шт):
Ваш объект окна создается в локальной (стековой) памяти метода, поэтому когда метод завершает свою работу, то вся локальная память очищается, следовательно удаляется объект окна. Я предлагаю сделать немного по-другому.
Минимальный рабочий вариант с применением QEvenLoop:
#include "mainwindow.h"
#include <QApplication>
#include <QLabel>
#include <QMovie>
#include <QStyle>
#include <QTimer>
#include <QDesktopWidget>
#include <QEventLoop>
// Класс заставки
class Splash : public QObject {
Q_OBJECT
public:
Splash() :QObject() {
}
// Показываем заставку и стартуем таймер
int exec() {
// Класс QEventLoop нам нужен для создания локального бесконечного цикла сообщений, запускаемого методом QEventLoop::exec(), в самом конце метода
QEventLoop _loop;
// Объекты movie и processLabel удалятся автоматически при завершении работы метода
QMovie movie("./image/Titul.gif");
QLabel processLabel;
processLabel.resize(640,480);
processLabel.setMovie(&movie);
processLabel.setWindowFlags(Qt::FramelessWindowHint);
processLabel.setAlignment(Qt::AlignCenter);
processLabel.setGeometry(
QStyle::alignedRect(
Qt::LeftToRight,
Qt::AlignCenter,
processLabel.size(),
qApp->desktop()->availableGeometry())
);
movie.start();
processLabel.show();
// Одноразовый сигнал завершения показа заставки
QTimer::singleShot(5000, &_loop, SLOT(quit()));
// Метод _loop.exec() не завершит свою работу до тех пор, пока
// _loop не получит сигнал quit() (от таймера)
return _loop.exec();
}
};
#include "main.moc"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Заставку создаем через указатель, чтобы после удалить его за ненадобностью и освободить память
Splash* splash = new Splash();
// Создаем и показываем заставку. Метод exec будет работать пока не получит сигнал
// от внутреннего таймера о завершении цикла и выходе из него
splash->exec();
// Удаляем объект заставки - очищаем память
splash->deleteLater();
// Показываем главное окно приложения
MainWindow window;
window.show();
return a.exec();
}
Дополнение 1. Попытка избавления от "зеленого":
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow window;
Splash* splash = new Splash();
splash->exec();
window.show();
splash->deleteLater();
return a.exec();
}
Дополнение 2. Чуть более сложный вариант избавления от зеленого экрана
// Класс заставки
class Splash : public QObject {
Q_OBJECT
public:
Splash():
movie("./image/Titul.gif")
{
}
// Показываем заставку и стартуем таймер
int exec() {
// из метки и муви делаем поля класса
// остальное оставляем как было
// ...
}
private:
QMovie movie;
QLabel processLabel;
};
#include "main.moc"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Splash* splash = new Splash();
splash->exec();
MainWindow window;
window.show();
// Теперь у вас на экране должны быть и заставка, и окно
// Следующая строка должна заставку скрыть и удалить
splash->deleteLater();
return a.exec();
}