[GRASS-dev] Python scripts receiving input from the GRASS GUI?

Michel Wortmann wortmann at pik-potsdam.de
Thu Aug 20 02:49:28 PDT 2015


Thanks Vaclav,
I agree that it is a bit of a dirty implementation, but I guess I just 
wanted to make this work quickly.
First to your copy-paste solution: I was more looking for something more 
interactive/clickable to precisely avoid the typing/reformatting. 
Something to seamlessly parse a few arguments to existing modules/addons 
or even scripts.
Taking on your comments about the non-dependency and sqlite DB issue, I 
will rewrite g.gui.triggers to work with a file in ~/.grass7 and the 
existence of which could then be checked in the dbmgr.base file and the 
gui_core.query file. There could be a 'Launch...' section in the 
right-click menu maybe?
I'll update you once I have come that far and maybe you can play around 
with it to see if it's useful for general inclusion.

Best,
Michel

On 08/19/2015 06:30 PM, Vaclav Petras wrote:
>
>
> On Wed, Aug 19, 2015 at 11:33 AM, Michel Wortmann 
> <wortmann at pik-potsdam.de <mailto:wortmann at pik-potsdam.de>> wrote:
>
>     Hi Vaclav,
>     thanks for the ideas. I have already implemented an idea which I
>     find works very well and is based on an add on, which works well
>     with GRASS' existing addon structure. But it did require me to add
>     a few lines in the gui_core.query as well as the dbmgr.base python
>     files, which I guess is the downside of it. Here is the
>     implementation:
>
>     g.gui.triggers is a little addon that manages a sqlite table
>     (__triggers__) in the current mapset, it records the vector name,
>     the command and the argument=column mapping and additional
>     arguments to be used. It can also be called with the arguments
>     map= and cat= to actually do the triggering of the command listed
>     in the table for the respective cat.
>
>     To implement the dbmgr double-clicking, I add the following to
>     dbmgr.base to call g.gui.triggers if the addon exists and if the
>     vector is listed in the __triggers__ table.
>
>     %%%% in header:
>     try: import guitriggers
>     except: guitriggers=None
>
>     %%%% line 1063
>             if guitriggers and
>     guitriggers.hasTrigger(**{a:self.dbMgrData['mapDBInfo'].layers[layer][a]
>     for a in ['table','database']}):
>                 win.Bind(wx.EVT_LEFT_DCLICK, self.OnDataTrigger)
>                 win.Bind(wx.EVT_COMMAND_LEFT_DCLICK, self.OnDataTrigger)
>             elif UserSettings.Get(group = 'atm', key = 'leftDbClick',
>     subkey = 'selection') == 0:
>     %%%%
>
>     %%%% anywhere as method to the DbMgrBrowsePage class
>         def OnDataTrigger(self,event):
>             info  = self.dbMgrData['mapDBInfo'].layers[self.selLayer]
>             tlist =
>     self.FindWindowById(self.layerPage[self.selLayer]['data'])
>             # get categories
>             cats = map(int,tlist.GetSelectedItems())
>     guitriggers.trigger(info['table'],cats,database=info['database'])
>             return
>     %%%%
>
>
>     To implement the selection idea in the map display, I added a
>     check box to the query dialog (if the addon exists). If it is
>     checked, the command listed in the __triggers__ table is executed.
>     I added the following to the gui_core.query file:
>
>     %%%% in header:
>     try: import guitriggers
>     except: guitriggers=None
>
>     %%%% in QueryDialog.__init__ line 77
>             if guitriggers:
>                self.trigger = wx.CheckBox(self.panel, label=_("Enable
>     trigger"))
>                self.trigger.SetValue(False)
>                hbox = wx.BoxSizer(wx.HORIZONTAL)
>                hbox.Add(item=self.trigger, proportion=0,
>     flag=wx.EXPAND | wx.RIGHT, border=5)
>                self.mainSizer.Add(item=hbox, proportion=0,
>     flag=wx.EXPAND | wx.ALL, border=5)
>     %%%%
>
>     %%%% in QueryDialog.SetData, line 99
>             if guitriggers and self.trigger.IsChecked():
>                 for m in data[1:]:
>                     info = m[m.keys()[0]] #unpack
>                     try:
>     guitriggers.trigger(info['Table'].split()[0],[info['Category']],
>     database=info['Database'].split()[0])
>                     except: pass
>     %%%%
>
>     I have not found any major flaws with this approach, the only
>     downside being the few added lines in the existing code (which are
>     all pretty much copied from existing functionalities). The
>     'guitriggers' module is so far still imported as a python module,
>     but I guess it doesnt take much to check whether it's an installed
>     addon.
>
>
> I'm glad you got that far. I don't have any opinion on this "triggers" 
> yet. This seems like a general "custom action" system; something like 
> a limited plugin system. It could be quite useful but we should have a 
> more general analysis of this before putting something to the main 
> code base. Also, typically for wxGUI, some refactoring is needed 
> before adding new features.
>
> Anyway, you should not put the "triggers" to SQLite database of the 
> current Mapset, that's for data. This is GUI and behavior, this should 
> go to ~/.grass7. It can be text file or anything else.
>
> Also, main code should not depend on an addon, either main code should 
> implement a more general mechanism or addon's code should be moved to 
> the main code.
>
>
>     Let me know if you want more details or would like me to upload
>     the addon to the GRASS addon repro.
>
>
> When ready, please post here the code of the module to test and diff 
> for the changes in existing code.
>
> Vaclav
>
>     Regards,
>     Michel
>
>
>
>
>     On 08/19/2015 03:47 PM, Vaclav Petras wrote:
>>     Hi Michel,
>>
>>     On Thu, Aug 13, 2015 at 10:32 AM, Michel Wortmann
>>     <wortmann at pik-potsdam.de <mailto:wortmann at pik-potsdam.de>> wrote:
>>
>>         Dear Devs,
>>         what would be the best and least invasive way of receiving
>>         input from the grass GUI to use in python scripts. The
>>         following functionalities are on my mind:
>>
>>         - when double-clicking a line in the dbmgr, trigger a
>>         script/function using the line's content as input
>>         - when selecting a feature in the map display, trigger a
>>         script/function using the query results as input
>>
>>         I guess changing the effect of a dbmgr line double-click can
>>         only be changed by fiddling with the gui/wxpython/dbmgr
>>         module files. Receiving the select query results as input on
>>         the command line is in theory possible with the 'Redirect to
>>         console' option in the select pop-up, but how can I read the
>>         GUI console?
>>
>>         In case someone had similar intentions and has some clues, I
>>         would appreciate hearing about them.
>>
>>
>>     these are reasonable requests. I suppose this would make your
>>     module more convenient for users to use. Unfortunately, there is
>>     no easy way. Anyway, these are the options:
>>
>>     1. Create a new functionality similar to the button to select
>>     coordinates. Module would specify option type as feature ID and
>>     when the module's GUI is started from the main GUI, the button is
>>     associated with Map Display. User clicks the button. Clicks in
>>     Map Display. Some query function is invoked and result goes to
>>     the input field in module's GUI. There is already a "template"
>>     for implementing this - the coordinates button.
>>
>>     2. Create a plugin system for wxGUI (thanks to Python relatively
>>     simple) and writing a plugin. If somebody wants to do that,
>>     please contact me, I can give you few pointers.
>>
>>     3. Create a new feature in GUI Command Console to start a module
>>     with current output in console as standard input for the module.
>>     I'm not sure if this would overcomplicate things or how this can
>>     be made actually convenient for users, but it is en interesting
>>     option.
>>
>>     4. For attribute data (dbmgr), "copy and paste" the line's
>>     content can be enough. Same for query results. For query, the
>>     copy is implemented but the format might not be good for parsing.
>>     For dbmgr, the button to copy should be easy to add. This seems
>>     convenient enough for user.
>>
>>     I suggest to first check the option number 4. The most general
>>     option is number 2 but when implemented, it would require writing
>>     a module to do the processing and then also a plugin for GUI to
>>     do the interaction. In this light option number 1 seems as a good
>>     way.
>>
>>     Best,
>>     Vaclav
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/grass-dev/attachments/20150820/bb78c3e8/attachment.html>


More information about the grass-dev mailing list