Hi George,
To attach a python method or MBX sub to a button click you need to create python addin because simple python script will run, execute and unload from MapInfo Pro. Addin on the other hand remains in MapInfo Pro memory unless explicitly unloaded.
In case of addin also, you just have to work in python and no need to create any .mb script. You can use the below template and add your whole python script code to create an addin. Template has TODO's which you can follow and rename the .py file as per you requirement.
To attach a command python method to a button and open table from its click use the below code.
import sys
import os
from os.path import join, dirname
import clr
from MapInfo.Types import IMapInfoPro, MessageOutput
from mi_common_util import CommonUtil
from mi_addin_util import AddinUtil
from MapInfo.Types import ControlType
sys.stdout = sys.stderr = sys.stdin = MessageOutput()
class MyAddin():
def __init__(self, imapinfopro, thisApplication):
try:
self._pro = imapinfopro
self._thisApplication = thisApplication
self._tab = None
r_item_name="Infrastructure_Data"
r_button_name="Water"
r_subroup_name="Not Abandoned"
r_subgroup_action="Open\nClose"
tab = self._pro.Ribbon.Tabs.Add(r_item_name)
self._tab = tab
if tab:
group = tab.Groups.Add(r_button_name, r_button_name)
if group:
button = group.Controls.Add("ButtonOpenTable", r_subroup_name, ControlType.Button)
button.IsLarge = True
button.LargeIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Mapping/infoTool_32x32.png")
button.SmallIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Mapping/infoTool_16x16.png")
button.Command = AddinUtil.create_command(self.open_table_click)
except Exception as e:
print("Failed to load: {}".format(e))
def open_table_click(self, sender):
pass
def unload(self):
if self._tab:
self._pro.Ribbon.Tabs.Remove(self._tab)
self._thisApplication = None
self._pro = None
pass
class main():
def __init__(self, imapinfopro):
self._imapinfopro = imapinfopro
def load(self):
try:
if self._imapinfopro:
thisApplication = self._imapinfopro.GetMapBasicApplication(os.path.splitext(__file__)[0] + ".mbx")
self._addin = MyAddin(self._imapinfopro, thisApplication)
except Exception as e:
print("Failed to load: {}".format(e))
def unload(self):
try:
if self._addin:
self._addin.unload()
del self._addin
self._addin = None
except Exception as e:
print("Failed to unload: {}".format(e))
def __del__(self):
self._imapinfopro = None
pass
def addin_name(self) -> str:
return "Python Add-in"
def addin_description(self) -> str:
return "Python Add-in Description"
def addin_defaultcommandtext(self) -> str:
return "Python Add-in Default Command"
def addin_defaultcommand(self):
self.on_default_button_clicked(self)
def addin_imageuri(self) -> str:
return "pack://application:,,,/MapInfo.StyleResources;component/Images/Application/about_32x32.png"
def on_default_button_clicked(self, sender):
try:
print('default command executed')
except Exception as e:
print("Failed to execute: {}".format(e))
Thanks
Anshul
------------------------------
Anshul Goel
Knowledge Community Shared Account
Shelton CT
------------------------------
Original Message:
Sent: 06-29-2020 18:39
From: George Corea
Subject: Using Python can we assign symbology to a dataset?
Thanks Peter.
The document does help in creating the different button types for my question 2.
For 1 and 3 - It's still not clear how to get clicking the button to trigger the do(Open Table) or pro.Catalog.OpenTable() command.
How do I trigger this?
tab = pro.Ribbon.Tabs.Add(r_item_name)
group = tab.Groups.Add(r_button_name, r_button_name)
button = group.Controls.Add("ButtonOpenTable", r_subroup_name, ControlType.Button)
button.IsLarge = True
button.CommandId = 102 #this is for the open table tool but I want to open a table so 'do (open table "d:\sometable.tab" as sometable)' or pro.Catalog.OpenTable(r"D:\Data\World\WORLD.TAB")
The variable details are listed in my previous post.
------------------------------
George Corea
Mangoesmapping
Original Message:
Sent: 06-29-2020 10:35
From: Peter Horsbøll Møller
Subject: Using Python can we assign symbology to a dataset?
Hi George
Let me try to answer your questions and give you some pointers to where to find out more.
1. Opening a table.
Yes, you can use the Do method and basically pass the Open Table MapBasic command to the MapInfo Pro using this approach.
You can also use the Table Catalog that we added a few versions back. This is also a .NET library but it can be used from within Python too:
pro.Catalog.OpenTable(r"D:\Data\World\WORLD.TAB")
The OpenTable method also comes in other "forms" where you also can specify an alias etc.
2. How to add items to a Gallery Control
I'd recommend that you take a look at the attached document. Look for Gallery Control and see how it's described in the document. The Gallery control gives you some more capabilities but this also makes it a bit harder to build the control with all its elements in the first place.
The document has been compiled by @William Wemple and gives you an overview of how to use most if not all the controls. Note that it's built for MapBasic developers but I think it gives you an idea on how to structure the build of the Gallery Control.
3. And how do I make these open a file/table
You will have to set a handler for each of the items that you add to the gallery. In this handler, you can now use one of the two methods I mentioned under 1. to open a table.
------------------------------
Peter Horsbøll Møller
Distinguished Engineer
Pitney Bowes Software & Data
Original Message:
Sent: 06-24-2020 23:18
From: George Corea
Subject: Using Python can we assign symbology to a dataset?
Thanks Anshul,
I had looked at this example and it was in the example code I posted. I don't want to create a full add in and would prefer to work only in python. Here's an updated code that shows where I am having issues.
### Description: Creates a new Ribbon, Group, Button and list types in Python and trigger open/close of tab file
#run application "D:\Projects\MGM\MI_Custom_Python_Interface\scripts\AddMenuItem.py" #Run in mapbasic window to execute the py code below
import sys
import os
from os.path import join, dirname
sys.path.append(join(r'C:\Users\George\AppData\Local\MapInfo\MapInfo\Professional\1900\Tools\PythonQuickStart\PythonAddins'))
print (sys.path)
import clr
from System import Int32, Array
from mi_common_util import CommonUtil
from mi_addin_util import AddinUtil
#from ribbon_customization_ole_handler import OleHandler
from MapInfo.Types import IMapInfoPro, ControlType, PaperUnits, DimensionedValue, NotificationObject, NotificationType
from System import Uri, UriKind
pro.Ribbon.Tabs.Clear() #clear existing python buttons
# Some standard variables to allow functions to be created for each action for easier use.
#r_ is for Ribbon actions
r_item_name="Infrastructure_Data" #Name of button on main ribbon (no spaces allowed)
r_button_name="Water" #same as operations in the ribbon_customization.py
r_subroup_name="Not Abandoned" #same as "Table" and "CallBack" in the ribbon_customization.py
r_subgroup_action="Open\nClose" #same as 'MB Handler\nNo Parameter'in the ribbon_customization.py
tab = pro.Ribbon.Tabs.Add(r_item_name)
group = tab.Groups.Add(r_button_name, r_button_name)
button = group.Controls.Add("ButtonOpenTable", r_subroup_name, ControlType.Button)
button.IsLarge = True
button.CommandId = 102 #this is for the open table tool but I want to open a table so 'do (open table "d:\sometable.tab" as sometable)'
button.LargeIcon = Uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Mapping/infoTool_32x32.png", UriKind.RelativeOrAbsolute)
#group = tab.Groups.Add('pytab', 'Custom')
r_subroup_name="Abandoned"
button = group.Controls.Add("ButtonOpenTable", r_subroup_name, ControlType.Button)
button.IsLarge = True
button.CommandId = 102 #this is for the open table tool but I want to open a table so 'do (open table "d:\sometable.tab" as sometable)'
button.LargeIcon = Uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Mapping/infoTool_32x32.png", UriKind.RelativeOrAbsolute)
#Create a seperator
seperatorB = group.Controls.Add("Separator","Seperator",ControlType.RibbonSeparator)
#Create a list of text items in another group
r_button_name="Sewer" #same as operations in the ribbon_customization.py
group2 = tab.Groups.Add(r_button_name, r_button_name)
splitB = group2.Controls.Add("DropDown", "List1", ControlType.SplitButton) #how do we add additional list items?
#do ('open table "c:\somefile.tab" as somfile') # open a table when clicked
#Create a seperator
seperatorB = group.Controls.Add("Separator","Seperator",ControlType.RibbonSeparator)
#Create filters
r_item_call="Planning" #Name of Button Call, r_ is for Ribbon actions
r_item_name="Planning" #Friendly name of button on main ribbon
r_button_name="Flood" #same as operations in the ribbon_customization.py
tab2 = pro.Ribbon.Tabs.Add(r_item_call)
group2 = tab2.Groups.Add('pytab', r_button_name)
filterItems = group2.Controls.Add("FilterItems","Filter Items", ControlType.GalleryControl)
filterItems.AddFilter("All")
filterItems.AddFilter("Table")
filterItems.AddFilter("Callback")
galleryGroup1 = filterItems.Groups.Add("Table")
customMBHandler = galleryGroup1.Controls.Add("customMBHandler","MB Handler", ControlType.GalleryItem)
if customMBHandler:
customMBHandler.LargeIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Spatial/clearTarget_32x32.png")
customMBHandler.SmallIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Spatial/clearTarget_16x16.png")
customMBHandler.ToolTip = AddinUtil.create_tooltip("Custom MB Handler ToolTip","Custom MBHandler ToolTip Text", "Custom MBHandler Disabled Text")
customMBHandler.IsQatItem = False
#customMBHandler.Command = AddinUtil.create_command(self.OnMBHandlerClick)
Key Questions:
1. How do I open a table? see button.CommandId = 102 #this is for the open table tool but I want to open a table so 'do (open table "d:\sometable.tab" as sometable)'
2. How do I add items to the list? See splitB = group2.Controls.Add("DropDown", "List1", ControlType.SplitButton) #how do we add additional list items?
Once added how do I trigger it to open some files on click.
3, Once you create filters how do you add buttons and text to them? See the #Create filters
section. It should look like the Operations tab in the ribbon customization script.
I just want to create a sample of all the options for items in the ribbon so that I have a simple sample of base code to then modify the interface as required by creating custom functions for each type of item in the ribbon.
------------------------------
George Corea
Mangoesmapping
Original Message:
Sent: 06-24-2020 07:16
From: Anshul Goel
Subject: Using Python can we assign symbology to a dataset?
Hi George,
From your post I think you want to create a Addin for MapInfo Pro in Python. For this you can take a look at the attached ribbon customization sample.
Basically Ribbon has a Tab and inside the Tab we have multiple Ribbon Groups.
Example:
newTab = pro.Ribbon.Tabs.Add("myTab", "New Tab") # this will add a new Tab into ribbon with caption "New Tab" and internal control name as "myTab"
# We will add ribbon group to this new tab.
grp = newTab.Groups.Add("grpName","New Group") # this will add a new Ribbon Group into tab with caption "New Group" and internal control name "grpName".
Similarly this pattern follows for buttons, gallery in a Ribbon Group.
You can take a look into Extensibility reference for more information on ribbon API.
------------------------------
Anshul Goel
Knowledge Community Shared Account
Shelton CT
Original Message:
Sent: 06-17-2020 06:35
From: George Corea
Subject: Using Python can we assign symbology to a dataset?
Thanks for the details Peter.
When you say 'You can also use the OpenTable method on the Catalog object to open a table into the current MapInfo Pro session' - how do you do this? i.e add a tab file to the current workspace in python? does it mean just do (Open Table "c:\somefile.tab" as somefile)
?
In the new Mapbasic/Python is there a way to load a thm file -there is this old thread about it but no answer.? this would make it easier than having to code each change of a default theme.
Looking at the examples I am trying to work out how to do the following but am not having much luck.
r_item_call="Infrastructure_Data" #Name of Button Call, r_ is for Ribbon actions
r_item_name="Infrastructure Data" #Friendly name of button on main ribbon
r_button_name="Water #same as operations in the ribbon_customization.py
r_subroup_name="Not Abandoned" #same as "Table" and "CallBack" in the ribbon_customization.py
r_subgroup_action="Open\nClose" #same as 'MB Handler\nNo Parameter'in the ribbon_customization.py
1. Add a ribbon item - this is easy
tabgroup=pro.Ribbon.Tabs.Add(r_item_call,r_item_name)
2.Name of item in Button on ribbon (i.e r_button_name
above)
#based on ribbon_customization.py key commands
#tabGroup1 = self._newTab.Groups.Add("demoGalleryGroup","Demo Gallery")
#gallery = tabGroup1.Controls.Add("Gallery","Operations", ControlType.GalleryControl)
so for gallery do we need to have 'demo' and 'Group' before and after it? but then refer to it as gallery (case insensitive)?
3. Add subgroups to button (ie r_r_subroup_name
above)
#galleryGroup1 = gallery.Groups.Add("Table")
Once 2 is sorted this should work
4. Add Items to subgroup and make them load a table on click (same as r_subgroup_action
above)
customHandlerWP = galleryGroup1.Controls.Add("customHandlerWP","MB Handler\nNo Parameter", ControlType.GalleryItem)
Not sure how to load a table and same issue as 2.
The quick graphic below relates to the numbers above...
Thanks for your advice...
------------------------------
George Corea
Mangoesmapping