Programmatically select a layer

Dear all,

As a way to learn programming plugins, I’m trying to modify the “Snap !” plugin ( GitHub - opengisch/qfield-snap: Allow for snapping of photos to create a feature at the current device location. · GitHub ) so that I can define the target layer in plugin settings; and then, when I click on the button, the photo is added to the appropriate layer even if I did not select it manually.

So I probably need something like (pseudocode)

  • In plugin settings (I know how to edit plugin settings) :
    • List all loaded layers
    • Find out which ones have point geometries
    • Built a combboox allowing to select one
    • Save the name of the target layer
  • In main code:
    • Preserve the currently selected layer
    • Select the target layer (probably with some guards, e.g. does it exist in this project, etc)
    • Do what is to be done :slight_smile:
    • Select back the originally selected layer

The programmatic logic seems quite simple to me but I cannot find the actual syntax/API calls to use it.

I am, in fact, struggling to find a comprehensive reference to the API, partly because I do not understand fully the logic of the code, I’m learning QML as I go, I don’t know what belongs to QField and what belongs to QGIS; and I’m afraid, partly because QField API documentation is rather skeletal. So as a bonus, any pointer to good places to find answers to such questions would be very welcome !

Thanks

Greetings Jean-Francois.

I assume you’ve stumbled on https://api.qfield.org/ already? As part of the QField 4.3 release, we’ve restructured the source tree into distinct core/gui/app/3d modules. It had I think a slight positive impact on the way the API documentation is categorized. Still, I’ll give you that, it’s bare bone :slight_smile:

Is the snippets section in that API documentation website useful?

I’m happy to provider answers slightly more targeted / specific questions here :slight_smile: You’re definitively doing the right thing by looking at preexisting plugin code. QML is a bit of a weird language to begin with, but once you can the hang of it, it can be quite enjoyable.

If you are coming to the QGIS UC 2026 in Laax, I’ll be there, we can chat about this offline too.

Hi Mathieu,

Thanks for the answer. No, I won’t be in Laax (busy with other things, and QField is only a small part of my day job). I would have been interested though.

Re. my immediate question : I’m looking for a way to (i) list all point layers loaded in the project and (ii) select a layer, as if it had been selected by the user. See my pseudocode above.

Re. the larger question … as a way of illustration, consider for instance the following line, that occurs regularly at the start of plugins:

property var overlayFeatureFormDrawer: iface.findItemByObjectName('overlayFeatureFormDrawer')

and then, for instance we see
overlayFeatureFormDrawer.featureModel.feature = feature
overlayFeatureFormDrawer.open()

I have some programming experience (in particular I understand about classes, objects, methods and so on), so from this, I gather

  • that the interface (iface) has a method findItemByObjectName() to return objects (whatever than mean in this context) with a given name
    → however, I don’t know where to look to find all the methods associated to iface (and in fact to find an explanation of how the iface object is meant to be used - remember, I’m a beginner).

  • that there is an object by the name of overlayFeatureFormDrawer
    → Cool ! So what is this object ? Which part of the interface does it refer to ?
    Are there any other cool objects ? Where can I find a list of the “named” objects ?

  • that overlayFeatureFormDrawer has a method called open(), and a property called featureModel
    → Sounds great ! Where can I find a list of the properties of this object (and how to use them) ? How do I use the open() method: it is quite clear that it opens the feature form drawer, but does it take any argument, return anything useful ?

Most probably, I don’t know where to look (not on the API site you mention, or I did not look in the right place), and also some of these things belong to QGIS and some to QField. But right now, my programming is really cargo cult - sieving the examples to find nuggets of code that look like they do what I need, without fully understanding if it is the right or the best way…

Heya!

To answer some of your questions from my own experience developing plugins:

Everything green in the docs is clickable (which is not super obvious since links are usually blue), so you can click the “iface” on the Home page in the docs to get to its class definition, which gives you all of its available functions.

You already found the open() function, so why not just give it a try :grin:
But even tho you can kind of infer what an object is by its code, I do agree it would be nice if the docs had ways to make it more obvious, e.g., with screenshots or some manually written description.

That one is a bit trickier. I believe the easiest way to find most available named objects is through your browser search on the corresponding source file (search for “ObjectName”):

I believe QField also adds some less useful named objects dynamically at runtime, but I would stick to those you find there.

Most things you find by ObjectName are QML items named after their exact class/origin file, so you can just search for them in the docs:

Now the open() function specifically is a bit more complicated, since it’s inherited from its parent class Drawer, which in turn inherits it from Popup, which are both native QML classes.

I do agree that the QField documentation still needs some work, but they have made significant progress over the past one and a half years since I started working with the plugin framework, so I have faith it will be improved even more over time! :blush:

You will get a feel for where to find which pieces of information over time while working with plugins, and don’t hesitate to ask right here in the community if you are stuck on specific issues or implementations!

Since you also mentioned examples, most plugins published on GitHub can be found by searching for this topic: qfield-plugin · GitHub Topics · GitHub

Hope I could help! :blush:

Hi Pascal,

Thanks for taking the time ! Developing plugins for QField is a bit frustrating, but indeed quite rewarding, as I’m already getting cool (and usable) results.

Many thanks for your detailed replies, although my questions were also, in part, an example of what I find difficult and what I would need. From your answers, I gather it is pretty much UTSL (or RTFS if you prefer). There is indeed scope for improvement - don’t get me wrong, I’m greatly appreciative of the job done by the QField team, and I know that writing documentation is tough, unrewarding, boring … and often pushed on the back burner in favour of most interesting things. Still, this makes for a steep learning curve (I’m an experienced R programmer, I can do some python and a bit of js in a pinch, so I’m not totally clueless, but even so…).

To be complete, I found that google’s AI does a fair job at giving me usable code snippets. To be taken with a large pinch of salt of course (and probably a dash of pepper as well) but at least it is a starting point.

Since you offer, there is one general question I’d like to ask - how do you setup your working environment ? Yes I did read the dev docs and I’m not any wiser, because I have no ideas what is a kit, cmake, vcpkg etc, so I get a lot of errors and I cannot even start to understand what I may be doing wrong.

Right now I’m developing in QT Design studio (that complains about not finding the Qfield functions, so I cannot see the GUI I’m writing, but at least I have syntax colouring, static debugger and automatic completion) and I copy and test on my device - very inefficient. What I really need is a REPL loop or a monitor that can allow me to see the value of different symbols…

Happy coding,

Jeff

@fggs-pascal , thanks for the detailed help you’ve provided, I’m sure it’ll be helpful for more than one member of our community :slight_smile:

@Jean-Francois_Moyen , the documentation could indeed be improved, and the code snippets section expanded. One thing could be super helpful as you journey into the world of QField plugin: if you come up with additional documentation you think would have saved you time, open a PR and submit it :slight_smile: I’ll be happy to review. It could be .h[eader] documentation additions, etc.

I’m glad you have reached a point where you feel rewarded by your results :slight_smile:

I was not aware of the terms UTSL or RTFS, but I’ll for sure add them to my IT jargon :joy:.
I do use GitHub Copilot a lot to help me find specific functionality I am looking for. The code it generates often doesn’t work since, for example, it’s often unaware of what native QML the plugin API exposes, how to import some QField classes, or it tries to tell me to “just write a C++ wrapper” (no, I won’t open a PR just to make my stupid button work). But it’s a lot more efficient at searching the repository for stuff I need than I would be.

I’m not aware of a way to set up your environment so your IDE knows about QField classes and functions, although when I looked into it, I was very new to the entire ecosystem, so there is a chance I’ve missed something.
I use VSCode and have my project files directly in the QField Windows plugin folder, so I can instantly test changes using the QField Plugin Reloader (only works as long as you only have 1 QML file. For bigger plugins with 2+ files, you have to restart QField after every change)
Only a few specific things, like, e.g., file handling, work differently between different operating systems, so for most plugins, mainly testing on Windows during development is sufficient.

I think the dev docs you mentioned are mainly for QField contributors, not for us plugin developers. I’m no C++ developer, so I too would not know what exactly the files you mentioned are - all I know is they are required to build/compiling a C++ application.

@Mathieu_Pellerin
A few things I think could be helpful (and I wasn’t able to find) gathered from this thread and my own experience:

  • a list of plugin-wide available singletons
  • a list of accessible named objects + a description of what QField uses them for, and maybe even screenshots for UI elements so they are easier to identify
  • include functions and properties from the parent classes in the QField API doc (maybe via a drop-down)

Hi Pascal, Mathieu,

A few things I think could be helpful (and I wasn’t able to find) gathered from this thread and my own experience:

  • a list of plugin-wide available singletons
  • a list of accessible named objects + a description of what QField uses them for, and maybe even screenshots for UI elements so they are easier to identify
  • include functions and properties from the parent classes in the QField API doc (maybe via a drop-down)

Yes, I was going to suggest something along these lines. A list of QField objects with their properties and what they are used for would be great.
Perhaps also with some pointers to “parent” QGIS objects; I do not always know what belongs to QGIS and what belongs to QField !

I would also value a walkthrough of what happens when QField does specific actions (allowing you to tap into this workflow). For instance, when you create a feature, an object of class feature is created, the featureFormDrawer opens, its results are used to update the feature’s fields, which is then committed to the layer (I guess). If I knew which function is used and how, it would have educational value, but also empower me to tweak the workflow or do the same thing myself or …

Thanks to both, anyway ! This conversation really makes me sorry I cannot attend the meeting in Laax! Sadly my day job takes precedence … However, if there was a QField user meeting closer to home (~ Lyon), even an informal one, I’d be keen…

3 Likes

@fggs-pascal , @Jean-Francois_Moyen , it’s a good idea. The list could be added into this part of the API documentation: QField API Documentation

That’s the relevant part on the repository: QField/docs/index.md at master · opengisch/QField · GitHub – contributions most welcome :slight_smile: