How could I call a function after the function that loads the layers ends up loading the layers?











up vote
1
down vote

favorite












I'm using pyqt5 to make a Qgis 3.4 plugin, this plugin is supposed to load pair o layers and zoom to the selected one, but the code executes too fast and passes the zooming line before the layers are loaded into Qgis.



the code is the following:



def openFileNameDialog(self):

options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
fileName, _ = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;Shapefile's (*.shp)", options=options)
if fileName:
shape_name = fileName

shapelayer = QgsVectorLayer(shape_name, "project's shapefile", "ogr")
if not shapelayer:
self.statusBar().showMessage('shapefile is invalid')

else:


urlWithParams = 'url=urltoBaseMap'

rlayer = QgsRasterLayer(urlWithParams, 'BaseMap', 'wms')

if not rlayer.isValid():
self.statusBar().showMessage('Layer failed to load!')

QgsProject.instance().addMapLayer(rlayer)
QgsProject.instance().addMapLayer(shapelayer)

self.iface.setActiveLayer(shapelayer)

def layerzoom(self):

self.iface.zoomToActiveLayer()

def runboth(self):

self.openFileNameDialog()
#time.sleep(5)
self.layerzoom()


how could I call a function to zoom after the function that loads the layers finishes the layers' loading?



I've tried time.sleep() but it doesn't wait for openFileNameFialog() to finish so the problem presist.










share|improve this question
























  • the problem is not as generic as your title indicates, the solution depends on qgis, for example, check if qgis emits a signal that indicates that the resource has been fully loaded, and that signal is connected to a slot that zooms.
    – eyllanesc
    Nov 19 at 16:20










  • (not expert in qgis) try with drawingProgress signal
    – eyllanesc
    Nov 19 at 16:23












  • Maybe I am not asking correctly, my real question is how to chain a function after another one has been called without having to call it inside the first function in this case openFileNameDialog() and avoid using runboth That's why the title was written the way it was before the edit.
    – Thriskel
    Nov 19 at 16:42










  • @eyllanesc drawingProgress cannot be used in this version.
    – Thriskel
    Nov 19 at 16:46






  • 1




    @Thriskel There are operations in openFileNameDialog() that execute asynchronously, so there is no way for the caller to know when it will complete. That is why signals and/or events are required in cases like this. Chaining the calls will not solve the problem at all.
    – ekhumoro
    Nov 19 at 16:57















up vote
1
down vote

favorite












I'm using pyqt5 to make a Qgis 3.4 plugin, this plugin is supposed to load pair o layers and zoom to the selected one, but the code executes too fast and passes the zooming line before the layers are loaded into Qgis.



the code is the following:



def openFileNameDialog(self):

options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
fileName, _ = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;Shapefile's (*.shp)", options=options)
if fileName:
shape_name = fileName

shapelayer = QgsVectorLayer(shape_name, "project's shapefile", "ogr")
if not shapelayer:
self.statusBar().showMessage('shapefile is invalid')

else:


urlWithParams = 'url=urltoBaseMap'

rlayer = QgsRasterLayer(urlWithParams, 'BaseMap', 'wms')

if not rlayer.isValid():
self.statusBar().showMessage('Layer failed to load!')

QgsProject.instance().addMapLayer(rlayer)
QgsProject.instance().addMapLayer(shapelayer)

self.iface.setActiveLayer(shapelayer)

def layerzoom(self):

self.iface.zoomToActiveLayer()

def runboth(self):

self.openFileNameDialog()
#time.sleep(5)
self.layerzoom()


how could I call a function to zoom after the function that loads the layers finishes the layers' loading?



I've tried time.sleep() but it doesn't wait for openFileNameFialog() to finish so the problem presist.










share|improve this question
























  • the problem is not as generic as your title indicates, the solution depends on qgis, for example, check if qgis emits a signal that indicates that the resource has been fully loaded, and that signal is connected to a slot that zooms.
    – eyllanesc
    Nov 19 at 16:20










  • (not expert in qgis) try with drawingProgress signal
    – eyllanesc
    Nov 19 at 16:23












  • Maybe I am not asking correctly, my real question is how to chain a function after another one has been called without having to call it inside the first function in this case openFileNameDialog() and avoid using runboth That's why the title was written the way it was before the edit.
    – Thriskel
    Nov 19 at 16:42










  • @eyllanesc drawingProgress cannot be used in this version.
    – Thriskel
    Nov 19 at 16:46






  • 1




    @Thriskel There are operations in openFileNameDialog() that execute asynchronously, so there is no way for the caller to know when it will complete. That is why signals and/or events are required in cases like this. Chaining the calls will not solve the problem at all.
    – ekhumoro
    Nov 19 at 16:57













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I'm using pyqt5 to make a Qgis 3.4 plugin, this plugin is supposed to load pair o layers and zoom to the selected one, but the code executes too fast and passes the zooming line before the layers are loaded into Qgis.



the code is the following:



def openFileNameDialog(self):

options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
fileName, _ = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;Shapefile's (*.shp)", options=options)
if fileName:
shape_name = fileName

shapelayer = QgsVectorLayer(shape_name, "project's shapefile", "ogr")
if not shapelayer:
self.statusBar().showMessage('shapefile is invalid')

else:


urlWithParams = 'url=urltoBaseMap'

rlayer = QgsRasterLayer(urlWithParams, 'BaseMap', 'wms')

if not rlayer.isValid():
self.statusBar().showMessage('Layer failed to load!')

QgsProject.instance().addMapLayer(rlayer)
QgsProject.instance().addMapLayer(shapelayer)

self.iface.setActiveLayer(shapelayer)

def layerzoom(self):

self.iface.zoomToActiveLayer()

def runboth(self):

self.openFileNameDialog()
#time.sleep(5)
self.layerzoom()


how could I call a function to zoom after the function that loads the layers finishes the layers' loading?



I've tried time.sleep() but it doesn't wait for openFileNameFialog() to finish so the problem presist.










share|improve this question















I'm using pyqt5 to make a Qgis 3.4 plugin, this plugin is supposed to load pair o layers and zoom to the selected one, but the code executes too fast and passes the zooming line before the layers are loaded into Qgis.



the code is the following:



def openFileNameDialog(self):

options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
fileName, _ = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;Shapefile's (*.shp)", options=options)
if fileName:
shape_name = fileName

shapelayer = QgsVectorLayer(shape_name, "project's shapefile", "ogr")
if not shapelayer:
self.statusBar().showMessage('shapefile is invalid')

else:


urlWithParams = 'url=urltoBaseMap'

rlayer = QgsRasterLayer(urlWithParams, 'BaseMap', 'wms')

if not rlayer.isValid():
self.statusBar().showMessage('Layer failed to load!')

QgsProject.instance().addMapLayer(rlayer)
QgsProject.instance().addMapLayer(shapelayer)

self.iface.setActiveLayer(shapelayer)

def layerzoom(self):

self.iface.zoomToActiveLayer()

def runboth(self):

self.openFileNameDialog()
#time.sleep(5)
self.layerzoom()


how could I call a function to zoom after the function that loads the layers finishes the layers' loading?



I've tried time.sleep() but it doesn't wait for openFileNameFialog() to finish so the problem presist.







python python-3.x pyqt pyqt5 qgis






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 at 16:18









eyllanesc

71.3k93053




71.3k93053










asked Nov 19 at 16:03









Thriskel

419




419












  • the problem is not as generic as your title indicates, the solution depends on qgis, for example, check if qgis emits a signal that indicates that the resource has been fully loaded, and that signal is connected to a slot that zooms.
    – eyllanesc
    Nov 19 at 16:20










  • (not expert in qgis) try with drawingProgress signal
    – eyllanesc
    Nov 19 at 16:23












  • Maybe I am not asking correctly, my real question is how to chain a function after another one has been called without having to call it inside the first function in this case openFileNameDialog() and avoid using runboth That's why the title was written the way it was before the edit.
    – Thriskel
    Nov 19 at 16:42










  • @eyllanesc drawingProgress cannot be used in this version.
    – Thriskel
    Nov 19 at 16:46






  • 1




    @Thriskel There are operations in openFileNameDialog() that execute asynchronously, so there is no way for the caller to know when it will complete. That is why signals and/or events are required in cases like this. Chaining the calls will not solve the problem at all.
    – ekhumoro
    Nov 19 at 16:57


















  • the problem is not as generic as your title indicates, the solution depends on qgis, for example, check if qgis emits a signal that indicates that the resource has been fully loaded, and that signal is connected to a slot that zooms.
    – eyllanesc
    Nov 19 at 16:20










  • (not expert in qgis) try with drawingProgress signal
    – eyllanesc
    Nov 19 at 16:23












  • Maybe I am not asking correctly, my real question is how to chain a function after another one has been called without having to call it inside the first function in this case openFileNameDialog() and avoid using runboth That's why the title was written the way it was before the edit.
    – Thriskel
    Nov 19 at 16:42










  • @eyllanesc drawingProgress cannot be used in this version.
    – Thriskel
    Nov 19 at 16:46






  • 1




    @Thriskel There are operations in openFileNameDialog() that execute asynchronously, so there is no way for the caller to know when it will complete. That is why signals and/or events are required in cases like this. Chaining the calls will not solve the problem at all.
    – ekhumoro
    Nov 19 at 16:57
















the problem is not as generic as your title indicates, the solution depends on qgis, for example, check if qgis emits a signal that indicates that the resource has been fully loaded, and that signal is connected to a slot that zooms.
– eyllanesc
Nov 19 at 16:20




the problem is not as generic as your title indicates, the solution depends on qgis, for example, check if qgis emits a signal that indicates that the resource has been fully loaded, and that signal is connected to a slot that zooms.
– eyllanesc
Nov 19 at 16:20












(not expert in qgis) try with drawingProgress signal
– eyllanesc
Nov 19 at 16:23






(not expert in qgis) try with drawingProgress signal
– eyllanesc
Nov 19 at 16:23














Maybe I am not asking correctly, my real question is how to chain a function after another one has been called without having to call it inside the first function in this case openFileNameDialog() and avoid using runboth That's why the title was written the way it was before the edit.
– Thriskel
Nov 19 at 16:42




Maybe I am not asking correctly, my real question is how to chain a function after another one has been called without having to call it inside the first function in this case openFileNameDialog() and avoid using runboth That's why the title was written the way it was before the edit.
– Thriskel
Nov 19 at 16:42












@eyllanesc drawingProgress cannot be used in this version.
– Thriskel
Nov 19 at 16:46




@eyllanesc drawingProgress cannot be used in this version.
– Thriskel
Nov 19 at 16:46




1




1




@Thriskel There are operations in openFileNameDialog() that execute asynchronously, so there is no way for the caller to know when it will complete. That is why signals and/or events are required in cases like this. Chaining the calls will not solve the problem at all.
– ekhumoro
Nov 19 at 16:57




@Thriskel There are operations in openFileNameDialog() that execute asynchronously, so there is no way for the caller to know when it will complete. That is why signals and/or events are required in cases like this. Chaining the calls will not solve the problem at all.
– ekhumoro
Nov 19 at 16:57












1 Answer
1






active

oldest

votes

















up vote
0
down vote













Adding these two lines to the code it was possible to wait for the layer load to zoomIn, thanks to eyllanesc and ekhumoro for the guidence



def stop_signal():  self.layeropen()
self.iface.mapCanvas().renderComplete.connect(stop_signal)


the code would look like this:



def openFileNameDialog(self):

options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
fileName, _ = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;Shapefile's (*.shp)", options=options)
if fileName:
shape_name = fileName

shapelayer = QgsVectorLayer(shape_name, "project's shapefile", "ogr")
if not shapelayer:
self.statusBar().showMessage('shapefile is invalid')

else:


urlWithParams = 'url=urltoBaseMap'

rlayer = QgsRasterLayer(urlWithParams, 'BaseMap', 'wms')

if not rlayer.isValid():
self.statusBar().showMessage('Layer failed to load!')
def stop_signal():
self.layeropen()
self.istft = 'yes'

QgsProject.instance().addMapLayer(rlayer)
QgsProject.instance().addMapLayer(shapelayer)

self.iface.mapCanvas().renderComplete.connect(stop_signal)

def layerzoom(self):
if self.istft == 'yes':
self.iface.zoomToActiveLayer()
if self.istft != 'yes':
pass

def mainprocess(self):

self.istft = None





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53378498%2fhow-could-i-call-a-function-after-the-function-that-loads-the-layers-ends-up-loa%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    Adding these two lines to the code it was possible to wait for the layer load to zoomIn, thanks to eyllanesc and ekhumoro for the guidence



    def stop_signal():  self.layeropen()
    self.iface.mapCanvas().renderComplete.connect(stop_signal)


    the code would look like this:



    def openFileNameDialog(self):

    options = QFileDialog.Options()
    options |= QFileDialog.DontUseNativeDialog
    fileName, _ = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;Shapefile's (*.shp)", options=options)
    if fileName:
    shape_name = fileName

    shapelayer = QgsVectorLayer(shape_name, "project's shapefile", "ogr")
    if not shapelayer:
    self.statusBar().showMessage('shapefile is invalid')

    else:


    urlWithParams = 'url=urltoBaseMap'

    rlayer = QgsRasterLayer(urlWithParams, 'BaseMap', 'wms')

    if not rlayer.isValid():
    self.statusBar().showMessage('Layer failed to load!')
    def stop_signal():
    self.layeropen()
    self.istft = 'yes'

    QgsProject.instance().addMapLayer(rlayer)
    QgsProject.instance().addMapLayer(shapelayer)

    self.iface.mapCanvas().renderComplete.connect(stop_signal)

    def layerzoom(self):
    if self.istft == 'yes':
    self.iface.zoomToActiveLayer()
    if self.istft != 'yes':
    pass

    def mainprocess(self):

    self.istft = None





    share|improve this answer



























      up vote
      0
      down vote













      Adding these two lines to the code it was possible to wait for the layer load to zoomIn, thanks to eyllanesc and ekhumoro for the guidence



      def stop_signal():  self.layeropen()
      self.iface.mapCanvas().renderComplete.connect(stop_signal)


      the code would look like this:



      def openFileNameDialog(self):

      options = QFileDialog.Options()
      options |= QFileDialog.DontUseNativeDialog
      fileName, _ = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;Shapefile's (*.shp)", options=options)
      if fileName:
      shape_name = fileName

      shapelayer = QgsVectorLayer(shape_name, "project's shapefile", "ogr")
      if not shapelayer:
      self.statusBar().showMessage('shapefile is invalid')

      else:


      urlWithParams = 'url=urltoBaseMap'

      rlayer = QgsRasterLayer(urlWithParams, 'BaseMap', 'wms')

      if not rlayer.isValid():
      self.statusBar().showMessage('Layer failed to load!')
      def stop_signal():
      self.layeropen()
      self.istft = 'yes'

      QgsProject.instance().addMapLayer(rlayer)
      QgsProject.instance().addMapLayer(shapelayer)

      self.iface.mapCanvas().renderComplete.connect(stop_signal)

      def layerzoom(self):
      if self.istft == 'yes':
      self.iface.zoomToActiveLayer()
      if self.istft != 'yes':
      pass

      def mainprocess(self):

      self.istft = None





      share|improve this answer

























        up vote
        0
        down vote










        up vote
        0
        down vote









        Adding these two lines to the code it was possible to wait for the layer load to zoomIn, thanks to eyllanesc and ekhumoro for the guidence



        def stop_signal():  self.layeropen()
        self.iface.mapCanvas().renderComplete.connect(stop_signal)


        the code would look like this:



        def openFileNameDialog(self):

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;Shapefile's (*.shp)", options=options)
        if fileName:
        shape_name = fileName

        shapelayer = QgsVectorLayer(shape_name, "project's shapefile", "ogr")
        if not shapelayer:
        self.statusBar().showMessage('shapefile is invalid')

        else:


        urlWithParams = 'url=urltoBaseMap'

        rlayer = QgsRasterLayer(urlWithParams, 'BaseMap', 'wms')

        if not rlayer.isValid():
        self.statusBar().showMessage('Layer failed to load!')
        def stop_signal():
        self.layeropen()
        self.istft = 'yes'

        QgsProject.instance().addMapLayer(rlayer)
        QgsProject.instance().addMapLayer(shapelayer)

        self.iface.mapCanvas().renderComplete.connect(stop_signal)

        def layerzoom(self):
        if self.istft == 'yes':
        self.iface.zoomToActiveLayer()
        if self.istft != 'yes':
        pass

        def mainprocess(self):

        self.istft = None





        share|improve this answer














        Adding these two lines to the code it was possible to wait for the layer load to zoomIn, thanks to eyllanesc and ekhumoro for the guidence



        def stop_signal():  self.layeropen()
        self.iface.mapCanvas().renderComplete.connect(stop_signal)


        the code would look like this:



        def openFileNameDialog(self):

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;Shapefile's (*.shp)", options=options)
        if fileName:
        shape_name = fileName

        shapelayer = QgsVectorLayer(shape_name, "project's shapefile", "ogr")
        if not shapelayer:
        self.statusBar().showMessage('shapefile is invalid')

        else:


        urlWithParams = 'url=urltoBaseMap'

        rlayer = QgsRasterLayer(urlWithParams, 'BaseMap', 'wms')

        if not rlayer.isValid():
        self.statusBar().showMessage('Layer failed to load!')
        def stop_signal():
        self.layeropen()
        self.istft = 'yes'

        QgsProject.instance().addMapLayer(rlayer)
        QgsProject.instance().addMapLayer(shapelayer)

        self.iface.mapCanvas().renderComplete.connect(stop_signal)

        def layerzoom(self):
        if self.istft == 'yes':
        self.iface.zoomToActiveLayer()
        if self.istft != 'yes':
        pass

        def mainprocess(self):

        self.istft = None






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 19 at 19:49

























        answered Nov 19 at 17:23









        Thriskel

        419




        419






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53378498%2fhow-could-i-call-a-function-after-the-function-that-loads-the-layers-ends-up-loa%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            If I really need a card on my start hand, how many mulligans make sense? [duplicate]

            Alcedinidae

            Can an atomic nucleus contain both particles and antiparticles? [duplicate]