Qt: закрытие дочернего окна

Модератор: Модераторы разделов

Ответить
IMB
Сообщения: 2561
ОС: Debian

Qt: закрытие дочернего окна

Сообщение IMB »

Доброго дня!
Из приложения просматриваю RTSP-поток с использованием libvlc в дочернем окне, для обращения к libvlc использую http://qt-apps.org/content/show.php?content=133649.
Настроено удаление дочернего окна при закрытии его и при активации пункта меню центрального окна.
mainwindow.cpp

Код: Выделить всё

VLC *vlc;
void MainWindow::on_actionRtsp_triggered(bool checked)
{
    disable_video_stream(); //активация/деактивация дополнительных пунктов меню

    qDebug("run on_actionRtsp_triggered");

    if (checked) {
        vlc = new VLC();
        connect(vlc, SIGNAL(finished(int)), this, SLOT(close_vlc())); //обработка закрытия окна
        vlc->start(cur_stream, server_address, resolution);
    } else {
        qDebug("before delete vlc");
        delete vlc;
        qDebug("after delete vlc");
    }

    qDebug("end on_actionRtsp_triggered");
}

void MainWindow::close_vlc()
{
    ui->actionRtsp->setChecked(false);
    qDebug("after ui->actionRtsp->setChecked");
    on_actionRtsp_triggered(false);
    qDebug("after on_actionRtsp_triggered");
}

vlc.cpp

Код: Выделить всё

VLC::VLC(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::VLC)
{
    ui->setupUi(this);
    setAttribute(Qt::WA_QuitOnClose, false);
    QStringList vlc_args = QStringList() << "--ignore-config"
                                         << "--rtsp-caching=100"
                                         << "--no-osd";
    instance = new VlcInstance(vlc_args, this);
    player = new VlcMediaPlayer(ui->video->widgetId(), this);
}

VLC::~VLC()
{
    stop();
    delete player;
    qDebug("after player");
    delete instance;
    qDebug("after inst");
    delete ui;
    qDebug("after ui");
}
void VLC::start(stream_format_e stream, QString &server, QSize &res)
{
    QString url = QString("rtsp://").append(server);

    if (STREAM_H264 == stream)
        url.append(":8557/H264");
    else if (STREAM_MJPEG == stream)
        url.append(":8555/MJPEG");

    player->open(url);
    player->play();

    setFixedSize(res);
    ui->video->resize(res);
    show();
}

void VLC::stop()
{
    if (player->isActive())
        player->stop();
    qDebug() << "isActive" << player->isActive();
}

Итак, если я при просмотре потока закрываю его используя пункт меню ui->actionRtsp всё закрывается корректно и вывод в консоль следующий:

Код: Выделить всё

run on_actionRtsp_triggered
before delete vlc
isActive false
after player
after inst
after ui
after delete vlc
end on_actionRtsp_triggered

Если я просто закрываю окно просмотра потока, то всё приложение падает с Segmentation fault:

Код: Выделить всё

after ui->actionRtsp->setChecked
run on_actionRtsp_triggered
before delete vlc
isActive false
after player
after inst
after ui
after delete vlc
end on_actionRtsp_triggered
after on_actionRtsp_triggered
Segmentation fault

Я не могу понять такого различия в поведении, если в обоих случаях вызывается одна и тажа функция on_actionRtsp_triggered.
Подскажите?
Спасибо.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Qt: закрытие дочернего окна

Сообщение NickLion »

попробуйте vlc->deleteLater() вместо delete vlc
Спасибо сказали:
IMB
Сообщения: 2561
ОС: Debian

Re: Qt: закрытие дочернего окна

Сообщение IMB »

Похоже это решило проблему, но я хочу попросить Вас объяснить эту ситуацию, так как для меня она не понятна.
Непонятность усугубляется ещё тем, что подобным образом я закрываю все дочерние окна, в приложение из три - отладочный вывод, просмотр JPEG и просмотр RTSP, и такая проблема есть только у окна отладочного вывода и просмотра RTSP.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Qt: закрытие дочернего окна

Сообщение NickLion »

Проблема зарылась в том, что производится удаление объекта при работе в слоте из сигнала этого самого объекта. Почему там работает - там нет, сказать трудно - я сам в этом вопросе не очень просвещён :(
Спасибо сказали:
IMB
Сообщения: 2561
ОС: Debian

Re: Qt: закрытие дочернего окна

Сообщение IMB »

Хорошо, а какой тогда способ закрытия рекомендуется?
Мне пока в голову приходит только отсылка сигнала в дочернее окно по которому вызывать close().
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Qt: закрытие дочернего окна

Сообщение NickLion »

Мне кажется, ставить Qt::WA_DeleteOnClose. А close - просто вызвать можно из главного окна.
Спасибо сказали:
Ответить