>  Offhand, there's a couple of ways to approach something like this:

> 1. You add appropriate signals in the core classes which are emitted
>  at useful stages, e.g. "aboutToCalculateExtent",
>  "extentCalculationProgressChanged", "extentCalculationComplete". And
>  then the app/gui classes can listen out for these signals and respond
>  to them appropriately, i.e. by showing a progress bar somewhere.

That sounds reasonable.

I am experimenting to implement the signals and the connect() call into the 
concerning 
provider class. As I am not familiar with the QGIS architecture I am unsure
what class to put the slot function into that raises the QProgressDialog(). 
I was thinking if QgsProject:: would be a good place?

>  2. You could add a QgsFeedback* argument to the costly method, and use
>  that to report progress and support early cancellation.

I couldn't manage to fully understand the concept of QgsFeedback, especially 
how it causes QProgressDialog to be invoked. Sudden enlightenment or supportive
explanation provided I will update the docs.

>  (2 is a more flexible, "better" approach, but depending on the method
>  you may not be able to add this to an existing method without breaking
>  stable API.
     
    
Tobias
    

________________________________
Von: Nyall Dawson <nyall.daw...@gmail.com>
Gesendet: Montag, 7. März 2022 23:52
An: Schmetzer, Tobias
Cc: qgis-developer@lists.osgeo.org
Betreff: Re: [QGIS-Developer] How to access QgisApp::instance() from a core 
class
    
On Tue, 8 Mar 2022 at 07:23, Schmetzer, Tobias
<tobias.schmet...@zae-bayern.de> wrote:
>
> > Again, none of the core classes are allowed any GUI component, and the 
> > correct approach to handle this particular situation is to move that code 
> > from the provider level up to app level, specifically via the 
> > QgsDataItemGuiProvider class.
>
>
> I had a look into it. If I understood it correctly the class provides a 
> framework for functions to be registered and called by other functions placed 
> in the gui.
>
> But what to do when a progress dialog needs to be raised or an application 
> state needs to be read? (see description below)
>
>
> > So my question would be: why do you need to raise a user-facing message 
> > from QgsOgrProvider::extent?
>
>
> - One idea was is to inform the user via a simple progress dialog in cases of 
> very time-consuming extent calculations for large layers (I observed calc 
> time ranges from 10 min to hours) of what's going on and that QGIS hasn't 
> crashed yet. The design would  practically allow this to be implemented in 
> the provider . If that's also not how it is intended to be then I'd 
> appreciate a quick hint of how it is intended to be.

Offhand, there's a couple of ways to approach something like this:

1. You add appropriate signals in the core classes which are emitted
at useful stages, e.g. "aboutToCalculateExtent",
"extentCalculationProgressChanged", "extentCalculationComplete". And
then the app/gui classes can listen out for these signals and respond
to them appropriately, i.e. by showing a progress bar somewhere.

2. You could add a QgsFeedback* argument to the costly method, and use
that to report progress and support early cancellation.

(2 is a more flexible, "better" approach, but depending on the method
you may not be able to add this to an existing method without breaking
stable API.

> and I also saw the use of QProgressDialog in other parts of the core 
> components code

That's likely just outdated code which hasn't been removed yet.

>
>
> - The second idea was to display an additional message dependant on the 
> current QGIS instance's project state (whether it's 
> loading/loaded/saving/closed) for which I had planned to introduce an enum 
> QgisApp::ProjectState alongside with a private variable  mProjectState and a 
> public function QgisApp::getProjectState(). So would I make this accessible 
> to the provider?

That property sounds potentially useful! (Just a note that QGIS code
convention is to name a getter "projectState()", not
"getProjectState(). We follow Qt conventions for naming as much as
possible).

But... (there's always a catch!) You can't (well, shouldn't) access
QgsProject from a data provider*.  So you'd need to change the
behaviour at a higher level based on the project state instead. (e.g.
by not calling some expensive method which can be deferred from the
app level code)

Nyall

* the virtual data provider does this, but it's special, and really
shouldn't anyway.

>
>
> Best regards
>
> Tobias
>
> --
>
> ZAE Bayern
> Dipl.-Ing. Tobias Schmetzer
> Systementwicklung | Systems Engineering
> Bereich Energiespeicherung | Division Energy Storage
> Walther-Meißner-Straße 6
> 85748 Garching
>
> Tel.: +49 89 329442-65
> Fax: +49 89 329442-12
> Mobil | Cell: +49 151 56964756
> tobias.schmet...@zae-bayern.de
> https://www.zae-bayern.de
>
> ZAE Bayern
> Bayerisches Zentrum für Angewandte Energieforschung e. V. | Bavarian Center 
> for Applied Energy Research
> Vorstand | Board: Dr. Andreas Hauer (Vorsitzender | Chairman), Dr. Hans-Peter 
> Ebert
> Sitz | Registered Office: Würzburg
> Registergericht | Register Court: Amtsgericht Würzburg
> Registernummer | Register Number: VR 1386
>
> Hinweise zum Datenschutz unter  https://www.zae-bayern.de/datenschutz
>
>
>
> ________________________________
> Von: Nyall Dawson <nyall.daw...@gmail.com>
> Gesendet: Montag, 7. März 2022 00:03
> An: Schmetzer, Tobias
> Cc: qgis-developer@lists.osgeo.org
> Betreff: Re: [QGIS-Developer] How to access QgisApp::instance() from a core 
> class
>
> On Sun, 6 Mar 2022 at 00:16, Schmetzer, Tobias via QGIS-Developer
> <qgis-developer@lists.osgeo.org> wrote:
> >
> > Hello everyone,
> >
> >
> > I would like to access QgisApp::instance() (src/app/qgisapp.cpp) from a 
> > provider like QgsOgrProvider::extent() 
> > (src/core/providers/ogr/qgsogrprovider.cpp.
>
> You can't, by design.
>
> CORE classes must be completely non-gui, so that they work without
> issue on non-gui platforms like QGIS server (also for clients which
> have their own GUI, such as QFIeld/Input).
>
> Just to be super-blunt: There is 100% no way this will EVER change! ;)
>
>
> > When looking for this information I found some inactivating preprocessor 
> > code block comments like this one (qgswfsdataitems.cpp):
> >
> > #if 0
> >
> >     // TODO: how to emit message from provider (which does not know about 
> >QgisApp)
> >     QgisApp::instance()->messageBar()->pushMessage( tr( "Cannot copy style" 
> >),
> >         errorMsg,
> >         Qgis::MessageLevel::Critical, messageTimeout() );
> > #endif
>
> This is very old code (hence why it's disabled). Again, none of the
> core classes are allowed any GUI component, and the correct approach
> to handle this particular situation is to move that code from the
> provider level up to app level, specifically via the
> QgsDataItemGuiProvider class.
>
> So my question would be: why do you need to raise a user-facing
> message from QgsOgrProvider::extent?
>
> Nyall
    
_______________________________________________
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Reply via email to