[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