Planned maintenance has been done but it did not solve the problem. So work will continue on this and a new time for trying updates will be announced asap.

Launch a second view on a pushed button



  • I have try everything, it doesn't work. Every time creates a new window but is empty.
    I don't understand why doesn't work..
    If i remove

    this->proc->start("some_executabele", QIODevice::ReadWrite);
    this->proc->waitForFinished(-1);
    

    Works ok...
    My function in pushed button now looks like this:

        QQuickView* view
        view = new QQuickView();
        view->setSource(QUrl("qrc:/loading.qml"));
        view->setResizeMode(QQuickView::SizeRootObjectToView);
        view->show();
        this->proc->start("some_executabele", QIODevice::ReadWrite);
        this->proc->waitForFinished(-1);
    

    Thank you for your help @mrjj


  • Lifetime Qt Champion

    @Lucian
    Hi
    It looks ok.
    ( Note, u create a new QQuickView each time. So its a leak but that u can fix later )

    I would look at what
    http://doc.qt.io/qt-5/qquickview.html#errors
    returns.

    To see if it has some issue running/loading.

    Update:
    Just to be sure. We are debugging the QQuickView and setSource
    and nothing related to waitForFinished ?

    Or are you saying that it works until you use QProcess then windows is empty?



  • Yes,,works until i use QProcess.
    If i let the button handle without QProcess it works.
    It is possible so lunch a QQuickView in a new QProcess? Maybe current process is the reason why doesn't work .


  • Lifetime Qt Champion

    @Lucian

    Then i think is what happens.
    The setSource starts to load. its still loading when functions returns.

    then waitForFinished blocks the event loop
    so there is no time to draw when the QML is ready.

    so I would try to use the
    http://doc.qt.io/qt-5/qquickview.html#statusChanged

    and if status is ready, then there in that slot i would run the QProcess.

    In that way you first block the event loop when the
    QML is 100% finished loading and that should work better.



  • Ok, i will try to find an example and i will post if i solve this.



  • Hey @mrjj

    Can you give me one last hand of help ?:D
    Look what i have done

    class Process : public QObject
    {
        Q_OBJECT
    private:
        QProcess* proc = new QProcess(this);
        QQuickView* view = new QQuickView();
    
    public slots:
        void startProcess();
    };
    

    In process.cpp

    void Process::startProcess()
    {
        this->proc->start("C:\\Windows\\System32\\calc.exe", QIODevice::ReadWrite);
        this->proc->waitForFinished(-1);
    }
    
    void Process::run() {
        view->setSource(QUrl("qrc:/loading.qml"));
        view->setResizeMode(QQuickView::SizeRootObjectToView);
        view->show();
    
        QObject::connect(view,SIGNAL(view::statusChanged),this, SLOT(Process::startProcess()));
    }
    

    Now the qml is show correct but doesn't start the calc.exe after the qml is load.
    Is corect how i use QObject::connect?


  • Lifetime Qt Champion

    @Lucian said in Launch a second view on a pushed button:

    Hi
    Good work
    There is a slight adjustment

    QObject::connect(view,SIGNAL(view::statusChanged),this, SLOT(Process::startProcess()));

    should be

    QObject::connect(view,SIGNAL(statusChanged() ),this, SLOT(startProcess() ) );
    ( no class:: in front when using the old syntax)

    And i would love if you did

    qDebug() << "status sig:" << QObject::connect(view,SIGNAL(statusChanged() ),this, SLOT(startProcess() ) );

    so you can check it says TRUE;

    Also
    void Process::startProcess() {
    qDebug() << "startProcess called";
    ...

    So we know it connects works and the startProcess is called.



  • Something is wrong.
    It say : "status sig: false"
    So the signal is not generated.

    Also say:
    QObject::connect: No such signal QQuickView::statusChanged()


  • Lifetime Qt Champion

    @Lucian
    ahh sorry.
    Didnt check the docs. ( shame on me)

    its just missing the parameter.

    void QQuickView::statusChanged(QQuickView::Status status)

    so its
    QObject::connect(view,SIGNAL(statusChanged(QQuickView::Status) ),this, SLOT(startProcess(QQuickView::Status) ) );

    NOte. only Type is added. NOT the paramtername

    and u need/could to change slot too

    void Process::startProcess( QQuickView::Status thesatus) {
    so here u can actually see if its ready etc.

    but u dont need to use the status :)


  • Qt Champions 2018

    @Lucian
    Please check documentation: http://doc.qt.io/qt-5/qquickview.html#statusChanged
    The signal has a parameter, so it should be:

    qDebug() << "status sig:" << QObject::connect(view,SIGNAL(statusChanged(QQuickView::Status) ),this, SLOT(startProcess() ) );
    


  • Thanks @mrjj , @jsulm
    Now it's better.
    "status sig: true"

    But the startProcess() still isn't call yet.
    The message from slot is not printed and the calc.exe doesn't show up, but at lest the status from QQuickView is changed.


  • Qt Champions 2018

    @Lucian Try to connect first:

    void Process::run() {
        QObject::connect(view,SIGNAL(view::statusChanged),this, SLOT(Process::startProcess()));
        view->setSource(QUrl("qrc:/loading.qml"));
        view->setResizeMode(QQuickView::SizeRootObjectToView);
        view->show();
    }


  • Yes @jsulm .
    It work but this doesn't solve my problem.
    I try to connect status change with startProcess because the progress bar (loading.qml) was block by waitForFinish(-1).
    Now is happening the same.
    The signal and the slot are called in the right order but also loading.qml doesn't popup until i close the calc.exe.


  • Qt Champions 2018

    @Lucian Why do you wait for the process to finish?

    this->proc->waitForFinished(-1);
    

    Are you aware that this call blocks the event loop (so your app is blocked)?



  • Yes @jsulm .
    I need to do that because the process what will be launch will create a txt file. This file will be use farder so i need to be sore the process has finished his job and has created the txt.


  • Qt Champions 2018

    @Lucian No need to wait for this! Just connect to http://doc.qt.io/qt-5/qprocess.html#finished signal - when it is called the process has finished...
    Qt is an asynchronous framework - you should adapt to asynchronous programming.



  • But how will wait my application to create the txt file ? Because after the process is finished i want to read from that .txt file created by him and if i read before creation the application will fail.
    So i need to connect the finish signal from QProcess with a slot that make the read from .txt file? :D


  • Qt Champions 2018

    @Lucian Yes, you simply connect a slot to that signal and do what you want with that file in this slot.



  • I have made some changes and now look like this:

    void Process::startProcess()
    {
        qDebug() << "startProcess called";
        this->proc->start("C:\\Windows\\System32\\calc.exe", QIODevice::ReadWrite);
        qDebug() << "connect status :" << QObject::connect(proc,SIGNAL(QProcess::finished()),this, SLOT(addData()));
    }
    

    And the slot:

    void Process::addData()
    {
        qDebug() << "addData call:";
        SomeClasss c;    
        c.read();
    }
    

    The problem is again with type of the signal:
    *QObject::connect: No such signal QProcess::QProcess::finished()

    From documentation (Qt doc) doesn't seems to be something wrong.



  • I have solved the problem like this:

        qDebug() << "connect status :" << QObject::connect(proc,SIGNAL(finished(int, QProcess::ExitStatus)),this, SLOT(addData()));
    

    I will mark this as Solved.
    Thank you for your help @jsulm , @mrjj .


Log in to reply