Related Plugins and Tags

QGIS Planet

QGIS gets Oracle support!

Seems this is a good day for QGIS Oracle users. According this commit made by Jürgen QGIS now has built-in Oracle support. Win!

Native Oracle support can now see QGIS being opened up to a wider user base yet again. A large user base normally means more people willing to sponsor awesome new features and bug fixes. Having seen the growth in the user base from having native MS SQL Server 2008+ support I can imagine what it will be like with Oracle.

The list of formats QGIS can open and edit is getting larger and larger with each release. Is there a future for vendor lock in? I can’t see it.

Standard disclaimer about latest dev build and new features :)


Filed under: Open Source, qgis Tagged: FOSSGIS, gis, Open Source, oracle, osgeo, qgis, qgis-editing, Quantum GIS

Custom QGIS feature forms – Value Binding

One thing I didn’t explain very well  in my other post was how to correctly set up value binding between your custom form and QGIS.  I didn’t explain it because at the time I didn’t know how.

The other day I was building a custom form QGIS for a project I am working on. I had named all the fields right, set the ui as the edit form for the layer, but only the line edits were getting bound to the correct values.

 So having a dig around in the code I noticed that QGIS uses the same methods to bind the built-in edit forms as it does for the custom forms, meaning that you must set what kind of control you want to use in Layer Properties -> Fields 

Correctly binding values

First create the form with the controls you need, remember to name them the same as your fields.

Custom form with controls using the same name as the fields

Note that here I have a QComboBox with the FeatureCla name, this will bind the combo box to the FeatureCla field in my dataset in QGIS.

Now set the custom form as the Edit UI for the layer

Set the Edit UI to your form

Tip: You can use relative paths if you store the form along side your project file

 Flick to the Fields tab and set up the Edit Widget type for each field that you have used on the custom feature form.

Set the Edit Widget that matches your control

I have set the FeatueCla field to use Unique values widget, this tells QGIS to collect all the unique values from that column and add them to the QComboBox.  There are a range of different edit widgets you can set

Each will map to a different set of control types (Widgets) e.g. If you want to have a checkbox on your form you must select Checkbox in the Edit Widget list to get it to bind correctly.

Save the properties and head back to you map.  Use the Identify Tool to select a feature.

Values bound to form

And that is it. Pretty cool hey!

Final thoughts

This is one feature I really like in QGIS.  The ability to create custom forms for people to do data entry without the need to build a plugin is very cool.  Couple this the built-in GPS module for QGIS and you have yourself a nice simple field data collection program.

I have some ideas to make this feature even more powerful, but more on that later once I get some time to add it in.


Filed under: Open Source, qgis Tagged: FOSSGIS, gis, Open Source, osgeo, qgis-editing, Quantum GIS

QGIS Tips – Custom feature forms with Python logic

Last week I found a nice little undocumented feature of QGIS. I plan on writing documentation, so it won’t stay that way for long but I thought I would post about it first and run though it step by step.

This post is going to be a follow up post based on what Tim Sutton did for the same subject back in 2009 at http://linfiniti.com/2009/11/creating-dynamic-forms-a-new-feature-headed-for-qgis-1-4/

For data entry one feature I really like in QGIS is the automatic feature edit forms with support for textboxs, dropdowns and all sorts of other cool Qt controls to make data entry a breeze.

However one thing that people might not be aware of is that you can have a custom forms for data entry. QGIS will take care of setting all the fields and then saving the values back to your layer.

This could be handy if you want to have say a logo, some validation and maybe some text to help the user fill in the form correctly. Or just a custom form layout because you can.

One thing Tim didn’t follow up on was a post about how to add custom Python logic to the form, which I think is the coolest feature of having these custom forms.

So lets get started.

Creating the custom form

This process is pretty much the same as what Tim outlined in his blog post however I’m going to go over it again for completeness.

In order to create the custom form you will need to install Qt Desinger. For windows I haven’t found a way to just install the desinger although if you have QGIS installed it is normally installed with the Qt framework and can be found at C:\OSGeo4w\bin\designer.exe. If you’re on Linux you can run something like

sudo apt-get install qt4-designer

Ohh how I wish windows had a package management system :(

Fire up Qt Desinger and select “Dialog with Buttons Bottom”.

Lets throw on a couple of Labels and a few Line Edits for the data. Now set the form to use a Grid Layout (Right Click on empty space on form->Layout->Layout in Grid).

Now the trick in making a custom form for QGIS is naming the object the same as the field. So I my case I have a road layer with the following fields.

- Segment_ID
- Parcel_ID
- Name
- Alias_Name
- Locality
- Parcel_type

For my custom form I only care about Segment_ID and Name, so my form looks like:

Custom form in Qt Designer

Note that I have set the read only property of the Segment ID line edit to True so that it can’t be edited. I don’t want people messing around with the ID.

As I said above the tick is in the naming so right click on each line edit and select Change objectName, naming each line edit using the same name as the field. For me the first control is called Segment_ID and the other is called Name.

Make sure the objects are the same name as the field.

Save the form into a new folder, I have put mine in C:\Temp\Roads. Jump back into QGIS, load the properties dialog for the layer. Select the General tab and set Edit UI to the new form .ui file.

Setting the edit form UI file.

Save and exit the properties window. Enable the layer for editing (or not) and select an object with the Identify Feature tool.

Woot! Custom edit form in QGIS.

Magic! As I’m in edit mode any changes I make to the Name line edit will be reflected back on the layer (but not the Segment ID as it’s read only). If you are in non-edit mode then you are given the custom form with everything disabled and a cancel button.

With Python validation and custom logic.

Now creating a custom form like above is pretty cool although having some custom Python validation behind it would be even cooler.

What I want to do is add some validation to the Name field so the user can’t enter null road names.

First save your QGIS project (as the Python code runner will look where the project is saved for the Python module). Again I have saved mine in C:\Temp\Roads as Roads.qgs. Now lets make a new python file in your favourite text editor and add the following code.

from PyQt4.QtCore import *
from PyQt4.QtGui import *

nameField = None
myDialog = None

def formOpen(dialog,layerid,featureid):
	global myDialog
	myDialog = dialog
	global nameField
	nameField = dialog.findChild(QLineEdit,"Name")
	buttonBox = dialog.findChild(QDialogButtonBox,"buttonBox")

	# Disconnect the signal that QGIS has wired up for the dialog to the button box.
	buttonBox.accepted.disconnect(myDialog.accept)

	# Wire up our own signals.
	buttonBox.accepted.connect(validate)
	buttonBox.rejected.connect(myDialog.reject)

def validate():
  # Make sure that the name field isn't empty.
	if not nameField.text().length() > 0:
		msgBox = QMessageBox()
		msgBox.setText("Name field can not be null.")
		msgBox.exec_()
	else:
		# Return the form as accpeted to QGIS.
		myDialog.accept()

Wow! What the hell is all that! I’ll step though the code to explain each bit.

Code break down.

First import the modules from Qt and set up a few global variables to hold the dialog and name field.

from PyQt4.QtCore import *
from PyQt4.QtGui import *

nameField = None
myDialog = None

Now we create a method that QGIS will call when it loads the form. This method takes an instance of our custom dialog, the Layer ID, and the Feature ID.

def formOpen(dialog,layerid,featureid):

Then using the findChild method we want to grab the reference to the Name field and the button box. We are also calling buttonBox.accepted.disconnect() to disconnect the slots that QGIS has auto wired up to our button box, we do this so we can hook up our own accepted logic.

After we have disconnected the accepted signal we can wire up our own call to the validate method using buttonBox.accepted.connect(validate).

global myDialog
myDialog = dialog
global nameField
nameField = dialog.findChild(QLineEdit,"Name")
buttonBox = dialog.findChild(QDialogButtonBox,"buttonBox")

# Disconnect the signal that QGIS has wired up for the dialog to the button box.
buttonBox.accepted.disconnect(myDialog.accept)
# Wire up our own signals.
buttonBox.accepted.connect(validate)
buttonBox.rejected.connect(myDialog.reject)

We need a method to validate the logic. This will be called when the signal buttonBox.accepted() is called. The logic in this method should be pretty streight forward. If the Name line edit has a length > 0 then we accept the dialog, if not then we give the user a message and let them fix the mistake.

def validate():
  # Make sure that the name field isn't empty.
	if not nameField.text().length() > 0:
		msgBox = QMessageBox()
		msgBox.setText("Name field can not be null.")
		msgBox.exec_()
	else:
		# Return the form as accpeted to QGIS.
		myDialog.accept()

Almost done!

Now that you have a Python file with the custom validation logic we need to tell QGIS to use this logic for the form. First save the Python file in the same directory as your project. I have called mine C:\Temp\Roads\RoadForm.py.

Back on the General tab in the layer properties we can set the Init function field. We set this to call the module and function we just made. The syntax is {module name}.{function name}. In my case my module (the Python file we made before) is called RoadForm and the function is called formOpen, so it will be RoadForm.formOpen.

Set the Init function field to moduleName.functionName

Save and use the Identify Feature tool to select a feature. You shouldn’t get any errors if everything worked ok. Now delete everything in the Name field and hit Ok.

Validation in action

Sweet! The form can now not be accepted if the name field is null.

And that’s that. Pretty simple but powerful feature once you know how to set it up.

Enjoy!

If you do end up using this custom form with python logic stuff in the real world, leave a comment and maybe a picture. It would be good to see use cases for this cool QGIS feature.

Bonus

Why not add a red highlight to the textbox if something is not valid.

from PyQt4.QtCore import *
from PyQt4.QtGui import *

nameField = None
myDialog = None

def formOpen(dialog,layerid,featureid):
  global myDialog
  myDialog = dialog
  global nameField
  nameField = dialog.findChild(QLineEdit,"Name")
  buttonBox = dialog.findChild(QDialogButtonBox,"buttonBox")

  nameField.textChanged.connect(Name_onTextChanged)
  # Disconnect the signal that QGIS has wired up for the dialog to the button box.
  buttonBox.accepted.disconnect(myDialog.accept)
  # Wire up our own signals.
  buttonBox.accepted.connect(validate)
  buttonBox.rejected.connect(myDialog.reject)

def validate():
  # Make sure that the name field isn't empty.
  if not nameField.text().length() > 0:
    nameField.setStyleSheet("background-color: rgba(255, 107, 107, 150);")
    msgBox = QMessageBox()
    msgBox.setText("Name field can not be null.")
    msgBox.exec_()
  else:
  # Return the form as accpeted to QGIS.
    myDialog.accept()

def Name_onTextChanged(text):
  if not nameField.text().length() > 0:
    nameField.setStyleSheet("background-color: rgba(255, 107, 107, 150);")
  else:
    nameField.setStyleSheet("")

The key part of of this is nameField.textChanged.connect(Name_onTextChanged) and the Name_onTextChanged(text) method. Give it a try, I think it looks quite nice.

Change text background to red on invalid input.


Filed under: Open Source, qgis Tagged: FOSSGIS, gis, Open Source, qgis, qgis-editing, Quantum GIS

QGIS edit tools brainstorming or What edit tools should QGIS have?

One trend that come up a lot in the poll I recently ran (results will be out soon, just writing a summary blog post) is “Needs more powerful edit tools“.  And I agree.

Coming from a MapInfo background nothing much changes when you move to QGIS, MapInfo had the simple Add Point, Add Region, Add Line kind of tools and then you need to use plugins to do anything a bit more advanced (MapCAD).  QGIS has the start of a kind of MapCAD thing happening although not as complete.

Why not just let people write plugins?

However I think in order to make QGIS a more attractive package to a lot of people it needs to get some built in semi-advanced to advanced editing tools;  getting back to those poll results of “Needs more powerful edit tools”.

I thought to myself “What would I like QGIS to be able to do when it came to editing?” although I came up with a small set my editing needs are only relatively small.  I then thought the best way to find out what people need is to just create a blank canvas for people to throw their ideas around on and then go from there.

Why not just create a ticket?

My idea is to get a larger idea of what people need and want rather than just one-off tickets. Although the ideas will be at the edit tool idea level it will be easier to see how they should all fit together if they are all in one place and editable by other people.  You can then start asking questions like: Do we really need that UI there?  Can we merge these tools?  How should the output be handled?

The overall goal is to have a tight, thought out, group of edit tools rather then someone creating a plugin over here for one thing and some else creating something else over there.

So how do we get this going?

Well I have created a Google Document that anyone can edit and view in order to start brainstorming ideas. The link can be found here.

I have already created an example of two ideas that I would like to see.

So go ahead, throw some ideas up.  I’m interested to see where this can head.

Why use Google Docs and not the QGIS wiki?

Mainly because Google Docs makes it very easy to do frictionless editing of a document together.  No need for user names or passwords or overwriting someone else’s changes (Google Docs is all real time).


Filed under: Open Source, qgis Tagged: FOSSGIS, gis, mapping, Open Source, OSS, poll, qgis, qgis-editing, Quantum GIS

Back to Top

Sustaining Members