Re: [Qgis-user] QCompleter in QGIS form
Hi Stefan, I am not answering your questions here but, if you are on a PostgreSQL database you might want to try out the DataDrivenInputMask plugin [1]. It auto-generates forms for you; ComboBoxes on lookup tables (e.g. species) feature auto-complete. Bernhard [1] http://plugins.qgis.org/plugins/DataDrivenInputMask/ Am 28.03.2015 20:32, schrieb Blumentrath, Stefan: Dear all, Thanks to Nathan`s excellent example here: http://nathanw.net/2011/09/05/qgis-tips-custom-feature-forms-with-python-logic/ I managed to implement a simple QCompleter for a LineEdit in my form where the completer items are being fetched from DB (see init function code at the end of my mail). This is very, very promising stuff which comes in quite handy for entering species names (from an official list of (thousands of) species names in my case)! Yet there are two things I am struggling with: 1) Would it be possible to use this QCompleter solution to an autogenerated form? The auto generated forms are more than good enough for most of my use-cases. When I tried the Init function on an autogenerated form I got “NameError: global name 'TextEdit' is not defined”… Any ideas how to fix that? 2) It seems to me that the query - which is used to fill the QCompleter - is executed each time the form is opened. Would it be possible to avoid this, I mean that the query is only run once (e.g. when I open the project)? I hoped this could speed up the start of the form (even if the query gets cached in PostgreSQL)… Many thanks in advance for helping. Kind regards, Stefan P.S.: Next thing I will have to do is understand SIGNALS and SLOTS so I can adjust the completer content depending on other data entered in the form (e.g. filter species by kingdom or known occurrence in a country (here Norway)) … P.P.S.: My form_init.py looks like this: from PyQt4.QtCore import * from PyQt4.QtGui import * from PyQt4.QtSql import * import psycopg2 nameField = None myDialog = None def formOpen(dialog,layerid,featureid): global myDialog myDialog = dialog global nameField nameField = dialog.findChild(QLineEdit,"latinsk_navn") #Initiate completer completer = QCompleter() nameField.setCompleter(completer) #Fetch data from DB to fill completer conn = psycopg2.connect("dbname='MYDB' user='MYUSERNAME' host='MYHOST' password='MYPASSWD'") cur = conn.cursor() cur.execute("""SELECT scientificname FROM kls.l_artsliste WHERE finnesinorge = 'Ja'""") completition_items = [] for row in cur.fetchall(): completition_items.append(row[0]) #Add data to Qt Model / QCompleter model = QStringListModel() model.setStringList(completition_items) completer.setModel(model) __ Information from ESET Mail Security, version of virus signature database 11396 (20150330) __ The message was checked by ESET Mail Security. http://www.eset.com ___ Qgis-user mailing list Qgis-user@lists.osgeo.org http://lists.osgeo.org/mailman/listinfo/qgis-user
Re: [Qgis-user] QCompleter in QGIS form
Hi Matthias, Wow, cool! Thanks for implementing that so fast! I just tested caching in a global variable. It works like a charm and speeds up the GUI significantly. And yes, the completer works fine with autogenerated forms too (I only had to restart QGIS). So all my problems in this regards are solved now. The only, minor issue is, that one has to set Settings->Options->Enable Macros to "Always", or "Only this session" (with "Ask" (the default setting) the startup macro does not load, see: http://hub.qgis.org/issues/9523) For those who are interested and who can`t wait for the next release with Matthias additions (and who like me are absolute Python beginners), here is how it works (quite simple actually once you know how to do it): The openProject() Python marco function (in my case named generate_completer.py, located in the project directory) looks like this (completer content could also be loaded from file of course): - #!/usr/bin/env python from PyQt4.QtCore import * from qgis.core import * import psycopg2 def fetch_citems(): global ci #Fetch data from DB to fill completer conn = psycopg2.connect("dbname='MYDB' user='MYUSER' host='MYHOST' password='MYDB'") cur = conn.cursor() cur.execute("""SELECT scientificname FROM kls.l_artsliste WHERE finnesinorge = 'Ja'""") ci = [] for row in cur.fetchall(): ci.append(row[0]) - It is referenced in the project like this: import generate_completer generate_completer.fetch_citems() And the form init function (in my case named completer.py, located in the project directory) looks like this: - from PyQt4.QtCore import * from PyQt4.QtGui import * import generate_completer nameField = None myDialog = None def formOpen(dialog,layerid,featureid): global myDialog myDialog = dialog global nameField nameField = dialog.findChild(QLineEdit,"latinn") #Initiate completer completer = QCompleter() nameField.setCompleter(completer) #Add data to Qt Model / QCompleter model = QStringListModel() model.setStringList(generate_completer.ci) completer.setModel(model) - It is referenced in the Fields tab as: completer.formOpen "latinn" is the name of the attribute column BTW for which the completer is used. I guess the global variable "ci" (Python list with Unicode strings) could also be used for data validation (in Nathan`s example)... Thanks for this amazing Software! Kind regards, Stefan From: qgis-user-boun...@lists.osgeo.org [mailto:qgis-user-boun...@lists.osgeo.org] On Behalf Of Matthias Kuhn Sent: 29. mars 2015 19:56 To: qgis-user@lists.osgeo.org Subject: Re: [Qgis-user] QCompleter in QGIS form Hi Stefan, I had some spare time on the Sunday evening train. So I have just added this possibility to the ValueRelation widget. You can now choose the option "Use Completer" there. The query is still run every time the form is opened at the moment. There is actually a caching mechanism for the value relation widget prepared, so it should be possible to make use of that and initialize the cache only once. But that will have to wait until I have some spare time again or one may speed up the process by funding this or tackling the issue if coding skills are available (for the last option, please get in touch first, there are a couple of different approaches to doing this), Testing is appreciated. Matthias On 03/28/2015 08:32 PM, Blumentrath, Stefan wrote: Dear all, Thanks to Nathan`s excellent example here: http://nathanw.net/2011/09/05/qgis-tips-custom-feature-forms-with-python-logic/ I managed to implement a simple QCompleter for a LineEdit in my form where the completer items are being fetched from DB (see init function code at the end of my mail). This is very, very promising stuff which comes in quite handy for entering species names (from an official list of (thousands of) species names in my case)! Yet there are two things I am struggling with: 1) Would it be possible to use this QCompleter solution to an autogenerated form? The auto generated forms are more than good enough for most of my use-cases. When I tried the Init function on an autogenerated form I got "NameError: global name 'TextEdit' is not defined"... Any ideas how to fix that? 2) It seems to me that the query - which is used to fill the QCompleter - is executed each time the form is opened. Would it be possible to avoid this, I mean that the query is only run once (e.g. when I open the project)? I hoped this could speed up the start of the form (even if the query gets cached in PostgreSQL)... Many thanks in advance for helping. Kind regards, Stefan P.S.: Next thing I will have
Re: [Qgis-user] QCompleter in QGIS form
PS: 1) couldn't reproduce the "global name is not defined" error... You script works here with .ui and autogenerated forms. 2) You may use a global variable to cache your completer (or its values) Best, Matthias On 03/28/2015 08:32 PM, Blumentrath, Stefan wrote: > > Dear all, > > > > Thanks to Nathan`s excellent example here: > > http://nathanw.net/2011/09/05/qgis-tips-custom-feature-forms-with-python-logic/ > > I managed to implement a simple QCompleter for a LineEdit in my form > where the completer items are being fetched from DB (see init function > code at the end of my mail). > > > > This is very, very promising stuff which comes in quite handy for > entering species names (from an official list of (thousands of) > species names in my case)! > > > > Yet there are two things I am struggling with: > > 1) Would it be possible to use this QCompleter solution to an > autogenerated form? The auto generated forms are more than good enough > for most of my use-cases. When I tried the Init function on an > autogenerated form I got “NameError: global name 'TextEdit' is not > defined”… Any ideas how to fix that? > > > > 2) It seems to me that the query - which is used to fill the > QCompleter - is executed each time the form is opened. Would it be > possible to avoid this, I mean that the query is only run once (e.g. > when I open the project)? I hoped this could speed up the start of the > form (even if the query gets cached in PostgreSQL)… > > Many thanks in advance for helping. > > > > Kind regards, > > Stefan > > > > P.S.: Next thing I will have to do is understand SIGNALS and SLOTS so > I can adjust the completer content depending on other data entered in > the form (e.g. filter species by kingdom or known occurrence in a > country (here Norway)) … > > > > P.P.S.: My form_init.py looks like this: > > > > from PyQt4.QtCore import * > > from PyQt4.QtGui import * > > from PyQt4.QtSql import * > > import psycopg2 > > nameField = None > > myDialog = None > > > > def formOpen(dialog,layerid,featureid): > > global myDialog > > myDialog = dialog > > global nameField > > nameField = dialog.findChild(QLineEdit,"latinsk_navn") > > > > #Initiate completer > > completer = QCompleter() > > nameField.setCompleter(completer) > > > > #Fetch data from DB to fill completer > > conn = psycopg2.connect("dbname='MYDB' user='MYUSERNAME' > host='MYHOST' password='MYPASSWD'") > > cur = conn.cursor() > > cur.execute("""SELECT scientificname FROM kls.l_artsliste WHERE > finnesinorge = 'Ja'""") > > completition_items = [] > > for row in cur.fetchall(): > > completition_items.append(row[0]) > > > >#Add data to Qt Model / QCompleter > >model = QStringListModel() > > model.setStringList(completition_items) > > completer.setModel(model) > > > > ___ > Qgis-user mailing list > Qgis-user@lists.osgeo.org > http://lists.osgeo.org/mailman/listinfo/qgis-user ___ Qgis-user mailing list Qgis-user@lists.osgeo.org http://lists.osgeo.org/mailman/listinfo/qgis-user
Re: [Qgis-user] QCompleter in QGIS form
Hi Stefan, I had some spare time on the Sunday evening train. So I have just added this possibility to the ValueRelation widget. You can now choose the option "Use Completer" there. The query is still run every time the form is opened at the moment. There is actually a caching mechanism for the value relation widget prepared, so it should be possible to make use of that and initialize the cache only once. But that will have to wait until I have some spare time again or one may speed up the process by funding this or tackling the issue if coding skills are available (for the last option, please get in touch first, there are a couple of different approaches to doing this), Testing is appreciated. Matthias On 03/28/2015 08:32 PM, Blumentrath, Stefan wrote: > > Dear all, > > > > Thanks to Nathan`s excellent example here: > > http://nathanw.net/2011/09/05/qgis-tips-custom-feature-forms-with-python-logic/ > > I managed to implement a simple QCompleter for a LineEdit in my form > where the completer items are being fetched from DB (see init function > code at the end of my mail). > > > > This is very, very promising stuff which comes in quite handy for > entering species names (from an official list of (thousands of) > species names in my case)! > > > > Yet there are two things I am struggling with: > > 1) Would it be possible to use this QCompleter solution to an > autogenerated form? The auto generated forms are more than good enough > for most of my use-cases. When I tried the Init function on an > autogenerated form I got “NameError: global name 'TextEdit' is not > defined”… Any ideas how to fix that? > > > > 2) It seems to me that the query - which is used to fill the > QCompleter - is executed each time the form is opened. Would it be > possible to avoid this, I mean that the query is only run once (e.g. > when I open the project)? I hoped this could speed up the start of the > form (even if the query gets cached in PostgreSQL)… > > Many thanks in advance for helping. > > > > Kind regards, > > Stefan > > > > P.S.: Next thing I will have to do is understand SIGNALS and SLOTS so > I can adjust the completer content depending on other data entered in > the form (e.g. filter species by kingdom or known occurrence in a > country (here Norway)) … > > > > P.P.S.: My form_init.py looks like this: > > > > from PyQt4.QtCore import * > > from PyQt4.QtGui import * > > from PyQt4.QtSql import * > > import psycopg2 > > nameField = None > > myDialog = None > > > > def formOpen(dialog,layerid,featureid): > > global myDialog > > myDialog = dialog > > global nameField > > nameField = dialog.findChild(QLineEdit,"latinsk_navn") > > > > #Initiate completer > > completer = QCompleter() > > nameField.setCompleter(completer) > > > > #Fetch data from DB to fill completer > > conn = psycopg2.connect("dbname='MYDB' user='MYUSERNAME' > host='MYHOST' password='MYPASSWD'") > > cur = conn.cursor() > > cur.execute("""SELECT scientificname FROM kls.l_artsliste WHERE > finnesinorge = 'Ja'""") > > completition_items = [] > > for row in cur.fetchall(): > > completition_items.append(row[0]) > > > >#Add data to Qt Model / QCompleter > >model = QStringListModel() > > model.setStringList(completition_items) > > completer.setModel(model) > > > > ___ > Qgis-user mailing list > Qgis-user@lists.osgeo.org > http://lists.osgeo.org/mailman/listinfo/qgis-user ___ Qgis-user mailing list Qgis-user@lists.osgeo.org http://lists.osgeo.org/mailman/listinfo/qgis-user
Re: [Qgis-user] QCompleter in QGIS form
Hi again, Now I spend some more thoughts on 2) and consider to write a Python macro for project start, which runs the query and writes results (completer items) kind of hard-coded into the form init function (meaning I will have to have a template for the form init function, which then is saved with the final name (overwriting earlier versions), while completer items are being injected). Do you think such a solution will cause the form to open faster (depending on the connection speed to the data base probably)? Or is it almost equally costly to load a rather long init-function (python script text fie)? Cheers, Stefan P.S.: Esp. help on 1) is still most welcome... P.P.S.: If it is of interest for others I could publish / document my QCompleter solution on github... >Yet there are two things I am struggling with: >1) Would it be possible to use this QCompleter solution to an autogenerated >form? The auto generated forms are more than good enough for most of my >>use-cases. When I tried the Init function on an autogenerated form I got >"NameError: global name 'TextEdit' is not defined"... Any ideas how to fix >>that? > >2) It seems to me that the query - which is used to fill the QCompleter - is >executed each time the form is opened. Would it be possible to avoid this, I >>mean that the query is only run once (e.g. when I open the project)? I hoped >this could speed up the start of the form (even if the query gets cached in >>PostgreSQL)... ___ Qgis-user mailing list Qgis-user@lists.osgeo.org http://lists.osgeo.org/mailman/listinfo/qgis-user
[Qgis-user] QCompleter in QGIS form
Dear all, Thanks to Nathan`s excellent example here: http://nathanw.net/2011/09/05/qgis-tips-custom-feature-forms-with-python-logic/ I managed to implement a simple QCompleter for a LineEdit in my form where the completer items are being fetched from DB (see init function code at the end of my mail). This is very, very promising stuff which comes in quite handy for entering species names (from an official list of (thousands of) species names in my case)! Yet there are two things I am struggling with: 1) Would it be possible to use this QCompleter solution to an autogenerated form? The auto generated forms are more than good enough for most of my use-cases. When I tried the Init function on an autogenerated form I got "NameError: global name 'TextEdit' is not defined"... Any ideas how to fix that? 2) It seems to me that the query - which is used to fill the QCompleter - is executed each time the form is opened. Would it be possible to avoid this, I mean that the query is only run once (e.g. when I open the project)? I hoped this could speed up the start of the form (even if the query gets cached in PostgreSQL)... Many thanks in advance for helping. Kind regards, Stefan P.S.: Next thing I will have to do is understand SIGNALS and SLOTS so I can adjust the completer content depending on other data entered in the form (e.g. filter species by kingdom or known occurrence in a country (here Norway)) ... P.P.S.: My form_init.py looks like this: from PyQt4.QtCore import * from PyQt4.QtGui import * from PyQt4.QtSql import * import psycopg2 nameField = None myDialog = None def formOpen(dialog,layerid,featureid): global myDialog myDialog = dialog global nameField nameField = dialog.findChild(QLineEdit,"latinsk_navn") #Initiate completer completer = QCompleter() nameField.setCompleter(completer) #Fetch data from DB to fill completer conn = psycopg2.connect("dbname='MYDB' user='MYUSERNAME' host='MYHOST' password='MYPASSWD'") cur = conn.cursor() cur.execute("""SELECT scientificname FROM kls.l_artsliste WHERE finnesinorge = 'Ja'""") completition_items = [] for row in cur.fetchall(): completition_items.append(row[0]) #Add data to Qt Model / QCompleter model = QStringListModel() model.setStringList(completition_items) completer.setModel(model) ___ Qgis-user mailing list Qgis-user@lists.osgeo.org http://lists.osgeo.org/mailman/listinfo/qgis-user