[libcalamares] Handle async QML loading
- The component isn't ready immediately, so instatiate once it is fully loaded and ready - Edge case if the execution view step is already visible, then start the show (because a previous call to onActivate() will have missed it).
This commit is contained in:
parent
193bcbde71
commit
f9bd0fba10
@ -42,6 +42,35 @@
|
|||||||
#include <QQuickWidget>
|
#include <QQuickWidget>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
/** @brief Calls the QML method @p method()
|
||||||
|
*
|
||||||
|
* Pass in only the name of the method (e.g. onActivate). This function
|
||||||
|
* checks if the method exists (with no arguments) before trying to
|
||||||
|
* call it, so that no warnings are printed due to missing methods.
|
||||||
|
*
|
||||||
|
* If there is a return value from the QML method, it is logged (but not otherwise used).
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
callQMLFunction( QQuickItem* qmlObject, const char* method )
|
||||||
|
{
|
||||||
|
QByteArray methodSignature( method );
|
||||||
|
methodSignature.append( "()" );
|
||||||
|
|
||||||
|
if ( qmlObject && qmlObject->metaObject()->indexOfMethod( methodSignature ) >= 0 )
|
||||||
|
{
|
||||||
|
QVariant returnValue;
|
||||||
|
QMetaObject::invokeMethod( qmlObject, method, Q_RETURN_ARG( QVariant, returnValue ) );
|
||||||
|
if ( !returnValue.isNull() )
|
||||||
|
{
|
||||||
|
cDebug() << "QML" << methodSignature << "returned" << returnValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( qmlObject )
|
||||||
|
{
|
||||||
|
cDebug() << "QML" << methodSignature << "is missing.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace Calamares
|
namespace Calamares
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -74,8 +103,8 @@ ExecutionViewStep::ExecutionViewStep( QObject* parent )
|
|||||||
cDebug() << "QML import paths:" << Logger::DebugList( m_qmlShow->engine()->importPathList() );
|
cDebug() << "QML import paths:" << Logger::DebugList( m_qmlShow->engine()->importPathList() );
|
||||||
if ( Branding::instance()->slideshowAPI() == 2 )
|
if ( Branding::instance()->slideshowAPI() == 2 )
|
||||||
{
|
{
|
||||||
cDebug() << "QML load on startup.";
|
cDebug() << "QML load on startup, API 2.";
|
||||||
loadQml();
|
loadQmlV2();
|
||||||
}
|
}
|
||||||
|
|
||||||
connect( JobQueue::instance(), &JobQueue::progress, this, &ExecutionViewStep::updateFromJobQueue );
|
connect( JobQueue::instance(), &JobQueue::progress, this, &ExecutionViewStep::updateFromJobQueue );
|
||||||
@ -138,7 +167,7 @@ ExecutionViewStep::isAtEnd() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExecutionViewStep::loadQml()
|
ExecutionViewStep::loadQmlV2()
|
||||||
{
|
{
|
||||||
if ( !m_qmlComponent && !Calamares::Branding::instance()->slideshowPath().isEmpty() )
|
if ( !m_qmlComponent && !Calamares::Branding::instance()->slideshowPath().isEmpty() )
|
||||||
{
|
{
|
||||||
@ -146,9 +175,19 @@ ExecutionViewStep::loadQml()
|
|||||||
QUrl::fromLocalFile( Calamares::Branding::instance()->slideshowPath() ),
|
QUrl::fromLocalFile( Calamares::Branding::instance()->slideshowPath() ),
|
||||||
QQmlComponent::CompilationMode::Asynchronous
|
QQmlComponent::CompilationMode::Asynchronous
|
||||||
);
|
);
|
||||||
|
connect( m_qmlComponent, &QQmlComponent::statusChanged, this, &ExecutionViewStep::loadQmlV2Complete );
|
||||||
}
|
}
|
||||||
if ( m_qmlComponent && !m_qmlObject )
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExecutionViewStep::loadQmlV2Complete()
|
||||||
|
{
|
||||||
|
if ( m_qmlComponent && m_qmlComponent->isReady() && !m_qmlObject )
|
||||||
{
|
{
|
||||||
|
cDebug() << "QML loading complete, API 2";
|
||||||
|
// Don't do this again
|
||||||
|
disconnect( m_qmlComponent, &QQmlComponent::statusChanged, this, &ExecutionViewStep::loadQmlV2Complete );
|
||||||
|
|
||||||
QObject* o = m_qmlComponent->create();
|
QObject* o = m_qmlComponent->create();
|
||||||
m_qmlObject = qobject_cast< QQuickItem* >( o );
|
m_qmlObject = qobject_cast< QQuickItem* >( o );
|
||||||
if ( !m_qmlObject )
|
if ( !m_qmlObject )
|
||||||
@ -160,39 +199,16 @@ ExecutionViewStep::loadQml()
|
|||||||
// what is needed: sets up visual parent by replacing the root
|
// what is needed: sets up visual parent by replacing the root
|
||||||
// item, and handling resizes.
|
// item, and handling resizes.
|
||||||
m_qmlShow->setContent( QUrl::fromLocalFile( Calamares::Branding::instance()->slideshowPath() ), m_qmlComponent, m_qmlObject );
|
m_qmlShow->setContent( QUrl::fromLocalFile( Calamares::Branding::instance()->slideshowPath() ), m_qmlComponent, m_qmlObject );
|
||||||
|
if ( ViewManager::instance()->currentStep() == this )
|
||||||
|
{
|
||||||
|
// We're alreay visible! Must have been slow QML loading, and we
|
||||||
|
// passed onActivate already.
|
||||||
|
callQMLFunction( m_qmlObject, "onActivate" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Calls the QML method @p method()
|
|
||||||
*
|
|
||||||
* Pass in only the name of the method (e.g. onActivate). This function
|
|
||||||
* checks if the method exists (with no arguments) before trying to
|
|
||||||
* call it, so that no warnings are printed due to missing methods.
|
|
||||||
*
|
|
||||||
* If there is a return value from the QML method, it is logged (but not otherwise used).
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
callQMLFunction( QQuickItem* qmlObject, const char* method )
|
|
||||||
{
|
|
||||||
QByteArray methodSignature( method );
|
|
||||||
methodSignature.append( "()" );
|
|
||||||
|
|
||||||
if ( qmlObject && qmlObject->metaObject()->indexOfMethod( methodSignature ) >= 0 )
|
|
||||||
{
|
|
||||||
QVariant returnValue;
|
|
||||||
QMetaObject::invokeMethod( qmlObject, method, Q_RETURN_ARG( QVariant, returnValue ) );
|
|
||||||
if ( !returnValue.isNull() )
|
|
||||||
{
|
|
||||||
cDebug() << "QML" << methodSignature << "returned" << returnValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( qmlObject )
|
|
||||||
{
|
|
||||||
cDebug() << "QML" << methodSignature << "is missing.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ExecutionViewStep::onActivate()
|
ExecutionViewStep::onActivate()
|
||||||
{
|
{
|
||||||
|
@ -60,6 +60,9 @@ public:
|
|||||||
|
|
||||||
void appendJobModuleInstanceKey( const QString& instanceKey );
|
void appendJobModuleInstanceKey( const QString& instanceKey );
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void loadQmlV2Complete();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWidget* m_widget;
|
QWidget* m_widget;
|
||||||
QProgressBar* m_progressBar;
|
QProgressBar* m_progressBar;
|
||||||
@ -70,7 +73,7 @@ private:
|
|||||||
|
|
||||||
QStringList m_jobInstanceKeys;
|
QStringList m_jobInstanceKeys;
|
||||||
|
|
||||||
void loadQml(); //< Loads the slideshow QML (from branding)
|
void loadQmlV2(); //< Loads the slideshow QML (from branding) for API version 2
|
||||||
void updateFromJobQueue( qreal percent, const QString& message );
|
void updateFromJobQueue( qreal percent, const QString& message );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user