8

I've just begun exploring QGIS relations option, now in version QGIS 2.2, details here: http://blog.vitu.ch/10112013-1201/qgis-relations

This is a great implementation of something I've been attempting to manually organize for a while now. Now, i'm wondering how to integrate the relations widget into a custom form (currently, it automatically adds only if using the auto generated form). I'm new to PyQt Designer, so i'm not sure where to start.

4
  • small addition: besides the layer property Attribute Editor "Autogenerate" you can also use "Drag and Drop designer" which creates a Tab Page layout (gives you bit more layout possibilities), although there is an error, see [gis.stackexchange.com/questions/91991 ](gis.stackexchange.com/questions/91991) But it would be good to know (i'm also looking for that) how to design (something special) yourself in Qt Designer with something like a "Relations Widget" to achieve master-detail / parent-child UI in Qt Designer based on QGIS defined project "relations".
    – Jan
    Commented Apr 4, 2014 at 13:54
  • this is not an answer. I could not add a comment or a private question because I do not have a reputation :-) But, after I followed this steps, adding the widget, I try to edit my parent layer using my custom form. I thought adding this widget will have the same effect of seeing the children attribute table as it does in the autogenerated form, but nothing shows up this time. I appreciate your time
    – nanunga
    Commented Apr 24, 2014 at 17:45
  • I am so sorry, there was a typo on the name of one field and that's the reason it did not worked.
    – nanunga
    Commented Apr 24, 2014 at 18:46
  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. Commented Feb 12, 2015 at 17:11

2 Answers 2

10

In Qt Designer:

  1. Create a new QWidget
  2. Add a custom property and name it qgisRelation
  3. Set the value of the new qgisRelation-property to the id of the relation.

Adding a custom property in Qt Designer

7
  • Can you please elaborate on naming the custom property "qgisRelation"? Is this related to QgsMapLayer.setCustomProperty()? If i'm understanding well, by "add a custom property," you mean adding python logic to the dialog and "set its value" is naming the object in PyQt.
    – user25976
    Commented Apr 4, 2014 at 19:04
  • No python, pure QtDesigner. Select the created QWidget, click the green plus-symbol, choose "String" and name the new property qgisRelation. Commented Apr 4, 2014 at 21:53
  • Okay, I'm following you. Custom property created and object named as relation ID, but it's still not synching up. I wonder if there's something to be done under Properties > Fields > Edit widget. I've experimented with Relation Reference and Value relation with no success. Thank you for your patience and help.
    – user25976
    Commented Apr 4, 2014 at 23:19
  • Relation reference is for the child table and has to be set for the foreign key field. The method explained in this answer has to be done on the parent table's form. Commented Apr 6, 2014 at 19:29
  • 1
    Quote qgisRelation widget named foreign key. The name doesn't matter. It's an arbitrarily named QWidget with a dynamic property called qgisRelation which has the relation id as its value. (Still no python involved and no need to install it if you don't mind having no plugins) Commented Apr 9, 2014 at 6:21
7

Use a custom form designed using Qt designer.

Completed form and sub form

(I've been successful doing this on QGIS 2.6 on Windows, but my Linux QGIS version crashes. I'm writing this having worked things out for the first time so this answer may well benefit from corrections).

You should have the relationship set up in project properties. Choose the relations sub-menu and add a relation. The 'referencing layer' is the child/'many' side of the one-to-many relationship - and the 'referencing field' is the field in that table which has matching values on the parent/'one' side of the relationship. The referenced layer/field entries refer to the parent/'one' side of the relationship.

Before closing this dialogue note that the bottom box allows you to define your own name for the relationship. Do this, and copy the name exactly for later.
Image of relationship dialogue

If you've let QGIS automatically give the relationship a name I've found it challenging to copy the name (which is very long) because there is no obvious way to select it.

Unless you already know your way around Qt Designer, consider starting with the QT file I supply at the end of this answer: put the code in a text editor and save it with an appropriate name with the ending ".ui" (e.g. MyForm.ui).

You can edit the form in Qt Designer (probably downloaded with QGIS) - but it's probably worth doing the following edits in the text editor first:

Change the line

<string notr="true">LocToInspRelnID</string>

so that "LocToInspRelnID" is replaced with whatever ID you set up for the relationship.

Edit the line:

  <widget class="QLineEdit" name="LocationID">

So that "LocationID" refers to an appropriate field in your parent table (this has no function beyond displaying the data on the form).

There are two modes for the sub-form (displaying data from the child/many side of the relationship). It can either display data in a simple table showing all data at once, or with its own form for each entry. Leave the following in the code if you want the data displayed in the simple table form - delete it otherwise.

   <property name="viewMode">
    <enum>QgsDualView::AttributeTable</enum>
   </property> 

There are labels on my form which you'll want to change, either now or later:

   <string>Location inspections</string>

Now, with this file saved (with or without further edits, with or without using Qt Designer), and back in QGIS, go to the parent layer's properties and set the 'Attribute editor layout' drop down to 'Provide ui-file' and in the Edit UI field put the path to your new form.

Attribute form window image

Now ensure that on QGIS you have the parent layer selected, and with the identify tool click on an appropriate object. You should see your form. (You may need to have 'auto open form' selected to ensure it opens without further mouse clicking:

Auto open image

Lastly - take note, you can use Qt Designer also to create a custom form for displaying the data in your second table (the child/many side of the relationship). This will be a much simpler form - taking data only from the one table. In the layer properties set QGIS up to use this form for this layer. This custom form will now also appear as the sub-form when inspecting the parent data.

Code for the form follows:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>745</width>
    <height>389</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <widget class="QLineEdit" name="LocationID">
   <property name="geometry">
    <rect>
     <x>290</x>
     <y>10</y>
     <width>113</width>
     <height>27</height>
    </rect>
   </property>
  </widget>
  <widget class="QgsRelationEditorWidget" name="mRelationEditor">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>50</y>
     <width>741</width>
     <height>291</height>
    </rect>
   </property>
   <property name="qgisRelation">
    <string notr="true">LocToInspRelnID</string>
   </property>
   <property name="viewMode">
    <enum>QgsDualView::AttributeTable</enum>
   </property>
  </widget>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>10</y>
     <width>201</width>
     <height>21</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>Noto Sans [unknown]</family>
     <pointsize>14</pointsize>
    </font>
   </property>
   <property name="text">
    <string>Location inspections</string>
   </property>
  </widget>
  <widget class="QLabel" name="label_2">
   <property name="geometry">
    <rect>
     <x>240</x>
     <y>10</y>
     <width>56</width>
     <height>17</height>
    </rect>
   </property>
   <property name="text">
    <string>Location:</string>
   </property>
  </widget>
  <widget class="QLabel" name="label_3">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>30</y>
     <width>71</width>
     <height>16</height>
    </rect>
   </property>
   <property name="text">
    <string>Inspections:</string>
   </property>
  </widget>
 </widget>
 <customwidgets>
  <customwidget>
   <class>QgsCollapsibleGroupBox</class>
   <extends>QGroupBox</extends>
   <header>qgscollapsiblegroupbox.h</header>
   <container>1</container>
  </customwidget>
  <customwidget>
   <class>QgsRelationEditorWidget</class>
   <extends>QgsCollapsibleGroupBox</extends>
   <header>qgsrelationeditorwidget.h</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.