Solved Launch a second view on a pushed button
-
Hey guys,
I am new with Qt and i have a problem.
I try to make a nice interface and my interface has tow view. First one is launch from main. First view has a button that launch a process (QProces) and after the process is finished it start the second view.
Now i wold like when the process launch also start a new view with a progress bar.Right now i don't really want the process bar to reflect the real time that takes the process the finish. I just want to be able to start them at once.
In main i have something like this :
QQuickView firstview; view.setSource(QUrl("qrc:/firstView.qml")); view.setResizeMode(QQuickView::SizeRootObjectToView); firstview.show();
My QML for progress bar looks like this:
import QtQuick 2.3 import QtQuick.Controls 1.4 Item{ ProgressBar { id: pb1 minimumValue: 0 maximumValue: 100 value: 0 } // Timer to show off the progress bar Timer { id: simpletimer interval: 100 repeat: true running: true onTriggered: pb1.value < pb1.maximumValue ? pb1.value += 1.0 : pb1.value = pb1.minimumValue } }
If i replace in main firstview.qml with loding.qml it works.
But if i add them in the method that handle the pushed button it popup an empty window.
My button handle looks like this:void Test::Butt() { this->proc->start("some_executabele", QIODevice::ReadWrite); this->proc->waitForFinished(-1); }
If i modify the function like this
view->setSource(QUrl("qrc:/loading.qml")); view->setResizeMode(QQuickView::SizeRootObjectToView); view->show(); this->proc->start("some_executabele", QIODevice::ReadWrite); this->proc->waitForFinished(-1);
The output is something like this:
While if i run the some code from main:QQuickView view; view.setSource(QUrl("qrc:/test.qml")); view.setResizeMode(QQuickView::SizeRootObjectToView); view.show();
The output looks like this:
Can somebody give me a clue, why doesn't load ok the qml file when is call from button handler? :D
Thx :) -
Please...any idea are welcome. :(
-
@Lucian said in Launch a second view on a pushed button:
this->proc->start("some_executabele", QIODevice::ReadWrite);
this->proc->waitForFinished(-1);If you remove this from void Test::Butt()
does it work then ? -
Hey @mrjj ,
I have also try this but doesn't work eider. :( -
ok can u try
QQuickView * view = new QQuickView(this)
view->setSource(QUrl("qrc:/test.qml"));
view->setResizeMode(QQuickView::SizeRootObjectToView);
view->show();(it leaks but , just for test)
-
No @mrjj
Still have the same problem. I can't solve this thing. ( -
@Lucian
Ok then its not a variable running out of scope.And you have tested that
Test::Butt()
is called?Also try
QQuickView * view = new QQuickView;
instead of
QQuickView * view = new QQuickView()Not sure if u want the view to be inside something or in a window.
IF you dont give a Qwidget a parent it will become a window.
Else its inserted into parent.Also the code
QQuickView view; view.setSource(QUrl("qrc:/test.qml")); view.setResizeMode(QQuickView::SizeRootObjectToView); view.show();
Can work from main but if u do the same in a function, you have this problem that
as soon as functions ends, it will delete view
so right after view.show(); is called it will be deleted. ( so might not show at all)
That is why i showed
QQuickView * view = new QQuickView(this)
That wont run out of scope. -
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 removethis->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
-
@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 . -
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#statusChangedand 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 doneclass 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? -
@Lucian said in Launch a second view on a pushed button:
Hi
Good work
There is a slight adjustmentQObject::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() -
@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 :)
-
@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() ) );
-
-
@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.