Как правильно уничтожить объект QMovie и QLabel при переходи из заставки в основную программу
Решил добавить красивую заставку при загрузки программы. Сделал гифку. Добавил ее в main. Но при старте программы гифка не уничтожается и продолжает грузить процессор.
Как нужно правильно, переходить из заставки в основную программу?
MainWindow w;
SoftKeyBoardContext * ic = new SoftKeyBoardContext();
a.setInputContext(ic);
w.setWindowFlags(Qt::FramelessWindowHint);
QMovie *movie = new QMovie("./image/Titul.gif");
QLabel *processLabel = new QLabel();
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, processLabel, SLOT(close()));
QTimer::singleShot(4500, &w, SLOT(show()));
Сделал по новому:
#include "mainwindow.h"
#include <QApplication>
#include <QTextCodec>
#include "SoftKeyBoardContext.h"
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/ioctl.h>
#include <linux/serial.h>
#include <asm-generic/ioctls.h>
#include <gpio.h>
#include <QPixmap>
#include <QMovie>
// Класс заставки
class Splash : public QObject {
Q_OBJECT
public:
Splash() {
this->processLabel = new QLabel();
connect(&_timer, SIGNAL(timeout()), this, SLOT(emitFinished()));
}
// Показываем заставку и стартуем таймер
void start() {
movie = new QMovie("./image/Titul.gif");
processLabel->setText("Splash Screen");
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();
_timer.start(5000);
}
signals:
// Сигнал завершения работы заставки
void finished();
private slots:
void emitFinished() {
processLabel->deleteLater();
movie->deleteLater();
emit finished();
}
private:
QLabel *processLabel;
QMovie *movie;
QTimer _timer;
};
#include "main.moc"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForTr( QTextCodec::codecForName("UTF-8"));
// настройка ножек для RS232 порта 1
Gpio gpio;
gpio.open(76);
gpio.set_direction(76,1);
gpio.set_value(76,0);
gpio.open(77);
gpio.set_direction(77,1);
gpio.set_value(77,1);
gpio.open(78);
gpio.set_direction(78,1);
gpio.set_value(78,1);
gpio.open(79);
gpio.set_direction(79,1);
gpio.set_value(79,1);
// порт 2
gpio.open(68);
gpio.set_direction(68,1);
gpio.set_value(68,0);
gpio.open(69);
gpio.set_direction(69,1);
gpio.set_value(69,1);
gpio.open(70);
gpio.set_direction(70,1);
gpio.set_value(70,1);
gpio.open(71);
gpio.set_direction(71,1);
gpio.set_value(71,1);
struct serial_rs485 rs485conf;
int fd = open ("/dev/ttyAPP1", O_RDWR);
if (fd < 0) {
qDebug()<<"rror: Can't open: /dev/ttySP0";
}
if (ioctl (fd, TIOCGRS485, &rs485conf) < 0) {
qDebug()<<"Error: TIOCGRS485 ioctl not supported";
}
rs485conf.flags |= SER_RS485_ENABLED;
rs485conf.delay_rts_before_send = 100;
rs485conf.delay_rts_after_send = 100;
if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
qDebug()<<"Error: TIOCSRS485 ioctl not supported.";
}
MainWindow w;
SoftKeyBoardContext * ic = new SoftKeyBoardContext();
a.setInputContext(ic);
w.setWindowFlags(Qt::FramelessWindowHint);
Splash splash;
splash.start();
QObject::connect(&splash, SIGNAL(finished()), &w, SLOT(show()));
return a.exec();
}
Собрал без ошибок. Программа падает при переходи на 'processLabel->deleteLater();'.
Ответы (1 шт):
Автор решения: Alexander Chernin
→ Ссылка
Попробуйте так (Qt 5.4+):
MainWindow w;
...
QTimer::singleShot(5000, [processLabel, movie, &w]() {
processLabel->deleteLater();
movie->deleteLater();
w.show()
});
Или:
QTimer::singleShot(5000, [processLabel, &w]() {
// Если вы точно знаете, что метка содержит муви
processLable->movie()->deleteLater();
processLabel->deleteLater();
w.show()
});
Тогда второй singleShot не нужен.
Дополнение для "древних" версий Qt. Файл main.cpp
// Класс заставки
class Splash : public QObject {
Q_OBJECT
public:
Splash() {
this->processLabel = new QLabel();
connect(&_timer, SIGNAL(timeout()), this, SLOT(emitFinished()));
}
// Показываем заставку и стартуем таймер
void start() {
processLabel->setText("Splash Screen");
processLabel->resize(640,480);
processLabel->setWindowFlags(Qt::FramelessWindowHint);
processLabel->setAlignment(Qt::AlignCenter);
processLabel->setMovie(...)
processLabel->show();
_timer.start(5000);
}
signals:
// Сигнал завершения работы заставки
void finished();
private slots:
void emitFinished() {
processLabel->deleteLater();
movie->deleteLater();
emit finished();
}
private:
QLabel *processLabel;
QMovie *movie;
QTimer _timer;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
Splash splash;
splash.start();
QObject::connect(&splash, SIGNAL(finished()), &w, SLOT(show()));
return a.exec();
}
// Если класс Splash объявлен в main.cpp, то надо подключить `moc`-файл
// Не забудьте после этого выполнить команду `qmake`
#include "main.moc"