QWidget: Must construct a QApplication before a QWidget



  • I am building a qt application example using the libvlc library, The compilation happens successful but the problem occurs when i try and run the application, i receive this Error on the application output :

    "QWidget: Must construct a QApplication before a QWidget "

    The application immediately crashes after that. Does anyone has an idea as to what causes this ?


  • Moderators

    @Bongani Hi, and welcome to the Qt forum! Please show us your main.cpp.



  • main.cpp

    #include <QtCore/QCoreApplication>
    #include <QDebug>
    #include <QApplication>
    
    #include <VLCQtCore/Common.h>
    
    #include "SimplePlayer.h"
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        QCoreApplication::setApplicationName("VLC-Qt Simple Player");
        QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
    
        VlcCommon::setPluginPath(app.applicationDirPath() + "/plugins");
    
        SimplePlayer mainWindow;
        qDebug() << "Showing window";
        mainWindow.show();
    
        return app.exec();
    }
    
    

    SimplePlayer.cpp'

    #include <QFileDialog>
    #include <QInputDialog>
    #include <QApplication>
    
    #include <VLCQtCore/Common.h>
    #include <VLCQtCore/Instance.h>
    #include <VLCQtCore/Media.h>
    #include <VLCQtCore/MediaPlayer.h>
    
    #include "EqualizerDialog.h"
    
    #include "SimplePlayer.h"
    #include "ui_SimplePlayer.h"
    
    SimplePlayer::SimplePlayer(QWidget *parent)
        : QMainWindow(parent),
          ui(new Ui::SimplePlayer),
          _media(0),
          _equalizerDialog(new EqualizerDialog(this))
    {
        ui->setupUi(this);
    
        _instance = new VlcInstance(VlcCommon::args(), this);
        _player = new VlcMediaPlayer(_instance);
        _player->setVideoWidget(ui->video);
        _equalizerDialog->setMediaPlayer(_player);
    
        ui->video->setMediaPlayer(_player);
        ui->volume->setMediaPlayer(_player);
        ui->volume->setVolume(50);
        ui->seek->setMediaPlayer(_player);
    
        connect(ui->actionOpenLocal, &QAction::triggered, this, &SimplePlayer::openLocal);
        connect(ui->actionOpenUrl, &QAction::triggered, this, &SimplePlayer::openUrl);
        connect(ui->actionPause, &QAction::toggled, _player, &VlcMediaPlayer::togglePause);
        connect(ui->actionStop, &QAction::triggered, _player, &VlcMediaPlayer::stop);
        connect(ui->openLocal, &QPushButton::clicked, this, &SimplePlayer::openLocal);
        connect(ui->openUrl, &QPushButton::clicked, this, &SimplePlayer::openUrl);
        connect(ui->pause, &QPushButton::toggled, ui->actionPause, &QAction::toggle);
        connect(ui->stop, &QPushButton::clicked, _player, &VlcMediaPlayer::stop);
        connect(ui->equalizer, &QPushButton::clicked, _equalizerDialog, &EqualizerDialog::show);
    }
    
    SimplePlayer::~SimplePlayer()
    {
        delete _player;
        delete _media;
        delete _instance;
        delete ui;
    }
    
    void SimplePlayer::openLocal()
    {
        QString file =
                QFileDialog::getOpenFileName(this, tr("Open file"),
                                             QDir::homePath(),
                                             tr("Multimedia files(*)"));
    
        if (file.isEmpty())
            return;
    
        _media = new VlcMedia(file, true, _instance);
    
        _player->open(_media);
    }
    
    void SimplePlayer::openUrl()
    {
        QString url =
                QInputDialog::getText(this, tr("Open Url"), tr("Enter the URL you want to play"));
    
        if (url.isEmpty())
            return;
    
        _media = new VlcMedia(url, _instance);
    
        _player->open(_media);
    }
    

    SimplePlayer.h

    
    /*
    * VLC-Qt Simple Player
    * Copyright (C) 2015 Tadej Novak <tadej@tano.si>
    */
    
    #ifndef SIMPLEPLAYER_H_
    #define SIMPLEPLAYER_H_
    
    #include <QMainWindow>
    
    namespace Ui {
        class SimplePlayer;
    }
    
    class VlcInstance;
    class VlcMedia;
    class VlcMediaPlayer;
    
    class EqualizerDialog;
    
    class SimplePlayer : public QMainWindow
    {
        Q_OBJECT
    public:
        explicit SimplePlayer(QWidget *parent = 0);
        ~SimplePlayer();
    
    private slots:
        void openLocal();
        void openUrl();
    
    private:
        Ui::SimplePlayer *ui;
    
        VlcInstance *_instance;
        VlcMedia *_media;
        VlcMediaPlayer *_player;
    
        EqualizerDialog *_equalizerDialog;
    };
    
    #endif // SIMPLEPLAYER_H_
    
    
    


  • EqualizerDialog.h

    
    /*
    * VLC-Qt Simple Player
    * Copyright (C) 2015 Tadej Novak <tadej@tano.si>
    */
    
    #include <VLCQtCore/Audio.h>
    #include <VLCQtCore/Equalizer.h>
    #include <VLCQtCore/MediaPlayer.h>
    #include <QApplication>
    
    #include "EqualizerDialog.h"
    
    EqualizerDialog::EqualizerDialog(QWidget *parent)
        : QDialog(parent),
          _mediaPlayer(0)
    {
        this->setupUi(this);
    
        // Default equalizer has ten bands
        _mapSliders.insert(firstBand, 0);
        _mapSliders.insert(secondBand, 1);
        _mapSliders.insert(thirdBand, 2);
        _mapSliders.insert(fourthBand, 3);
        _mapSliders.insert(fifthBand, 4);
        _mapSliders.insert(sixthBand, 5);
        _mapSliders.insert(seventhBand, 6);
        _mapSliders.insert(eighthBand, 7);
        _mapSliders.insert(ninethBand, 8);
        _mapSliders.insert(tenthBand, 9);
    
        // Set sliders value with unit
        for (QSlider *slider : findChildren<QSlider*>()) {
            QLabel *valueLabel = findChild<QLabel*>(slider->objectName() + "Label");
            connect(slider, &QSlider::valueChanged, this, [=](int value) {
                valueLabel->setText(QString::number(value) + " dB");
            });
        }
    
        connect(toggleEqualizer, &QCheckBox::toggled, this, &EqualizerDialog::toggle);
    }
    
    void EqualizerDialog::setMediaPlayer(VlcMediaPlayer *mediaPlayer)
    {
        _mediaPlayer = mediaPlayer;
        auto equalizer = _mediaPlayer->equalizer();
        for (uint i = 0; i < equalizer->presetCount(); i++) {
            presetComboBox->addItem(equalizer->presetNameAt(i));
        }
    
        // Create local connections
        connect(presetComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), _mediaPlayer->equalizer(), &VlcEqualizer::loadFromPreset);
        connect(_mediaPlayer->equalizer(), &VlcEqualizer::presetLoaded, this, &EqualizerDialog::applySelectedPreset);
    
        connect(preamp, &QSlider::valueChanged, equalizer, &VlcEqualizer::setPreamplification);
        for (QSlider *slider : findChildren<QSlider*>()) {
            if (slider != preamp) {
                connect(slider, &QSlider::valueChanged, this, &EqualizerDialog::applyChangesForBand);
            }
        }
    }
    
    void EqualizerDialog::applyChangesForBand(int value)
    {
        int bandIndex = _mapSliders.value(static_cast<QSlider*>(sender()));
        _mediaPlayer->equalizer()->setAmplificationForBandAt((float)value, bandIndex);
    }
    
    void EqualizerDialog::applySelectedPreset()
    {
        auto equalizer = _mediaPlayer->equalizer();
    
        disconnect(preamp, 0, equalizer, 0);
        for (QSlider *slider : findChildren<QSlider*>()) {
            if (slider == preamp) {
                slider->setValue(equalizer->preamplification());
            } else {
                disconnect(slider, &QSlider::valueChanged, this, &EqualizerDialog::applyChangesForBand);
                slider->setValue(equalizer->amplificationForBandAt(_mapSliders.value(slider)));
                connect(slider, &QSlider::valueChanged, this, &EqualizerDialog::applyChangesForBand);
            }
        }
        connect(preamp, &QSlider::valueChanged, equalizer, &VlcEqualizer::setPreamplification);
    }
    
    void EqualizerDialog::toggle(bool checked)
    {
        for (QSlider *slider : findChildren<QSlider*>()) {
            slider->setEnabled(checked);
        }
        presetComboBox->setEnabled(checked);
        _mediaPlayer->equalizer()->setEnabled(checked);
    }
    
    

    EqualizerDialog.h

    
    /*
    * VLC-Qt Simple Player
    * Copyright (C) 2015 Tadej Novak <tadej@tano.si>
    */
    
    #ifndef EQUALIZERDIALOG_H
    #define EQUALIZERDIALOG_H
    
    #include <QDialog>
    
    #include "ui_EqualizerDialog.h"
    
    class VlcMediaPlayer;
    
    class EqualizerDialog : public QDialog, Ui::EqualizerDialog
    {
        Q_OBJECT
    public:
        explicit EqualizerDialog(QWidget *parent = 0);
    
        void setMediaPlayer(VlcMediaPlayer *mediaPlayer);
    
    public slots:
        void applyChangesForBand(int value);
    
        void applySelectedPreset();
    
        void toggle(bool checked);
    
    private:
        QMap<QSlider*, int> _mapSliders;
        VlcMediaPlayer *_mediaPlayer;
    };
    
    #endif // EQUALIZERDIALOG_H
    
    
    

  • Moderators

    One comment: why do you use QCoreApplication to set application name and attributes? You can use QApplication.


  • Moderators

    @Bongani said:

    "QWidget: Must construct a QApplication before a QWidget "

    The application immediately crashes after that. Does anyone has an idea as to what causes this ?

    Did you create a widget in a global variable? That's not supported.

    Add qDebug("Hello"); before your QApplication constructor. Which message appears first? "QWidget: Must construct a QApplication before a QWidget ", or "Hello"?

    @jsulm said:

    One comment: why do you use QCoreApplication to set application name and attributes? You can use QApplication.

    That's not a problem, since calling QApplication::setApplicationName() will actually call QCoreApplication::setApplicationName(). QApplication inherits those methods from QCoreApplication but doesn't override them.


  • Moderators

    @JKSH I know. But it would be cleaner to use QApplication, then there is no need to include QCoreApplication header file.



  • This post is deleted!


  • @JKSH The program crashes immediately when i call the "SimplePlayer" Class or Window, when i debug the program, it crashes at the ui->setupUi(this); function in the "SimplePlayer" class. I did declare the Widget locally but the same thing happens, Its still crashes with the same error message.



  • I finally solved it. The problem was not in the code, It was the VLCQT library debug version. Apparently my VLCQT debug version was not the same version as my QT build. Thank you very much for your suggestions.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.