To enable/disable button you can assign a canexecute handler while creating commands and attach to buttons. In the canexecute handler you can check for condition on which button needs to be enabled.
Original Message:
Sent: 07-06-2020 18:26
From: Navjot Kaur
Subject: Using Python Script to Customize MapInfo Pro UI and Create Dialogs
Hi,
How can we create a button on Ribbon with Python that is disabled initially and gets enabled only when some map is open. For example, in above Py customization file, The "Open Dialog Winform Button"
Thanks
------------------------------
Navjot Kaur
Knowledge Community Shared Account
Original Message:
Sent: 06-25-2020 06:02
From: Anshul Goel
Subject: Using Python Script to Customize MapInfo Pro UI and Create Dialogs
Hi Navjot,
I think you should keep the state after the button click and clear it before the button click. Same logic could apply in any coding language.
Thanks
Anshul
------------------------------
Anshul Goel
Knowledge Community Shared Account
Shelton CT
Original Message:
Sent: 06-24-2020 09:11
From: Navjot Kaur
Subject: Using Python Script to Customize MapInfo Pro UI and Create Dialogs
Thanks it works.
I have another question. Suppose there is a customized button in Mapinfo that open a map for example "worldcap" when user clicks on it. When user clicks on the button for the second time, how to make sure it closes the previous opened map/or any action done in the first click.
Can you please suggest best way for that in Python
Thanks
------------------------------
Navjot Kaur
Knowledge Community Shared Account
Original Message:
Sent: 06-24-2020 06:29
From: Anshul Goel
Subject: Using Python Script to Customize MapInfo Pro UI and Create Dialogs
Hi Navjot,
You can do this by query out the values using a Select statement: Select SOMECOLUMN from SOMETABLE Group By SOMECOLUMN and then build shade statement.
Below is the small python code which you can use as it is.
import os
from os.path import join, dirname, abspath
import numpy as np
def get_random_rgb():
rgb_tuple = tuple(np.random.randint(256, size=3))
return rgb_tuple[0] << 16 | rgb_tuple[1] << 8 | rgb_tuple[2]
def shade_ind(objectType:int, tableAlias:str, col:str):
try:
do("map from {}".format(tableAlias))
mapId = int(eval("frontwindow()"))
layer = 1
qry = None
if objectType is 7:
qry = "Select {0} \"VALUE\" \
From {1} \
Where OBJ \
Group By {2} \
Order By {3} \
Into __THEME__STYLES NoSelect Hide"
elif objectType is 3:
qry = "Select {0} \"VALUE\" \
From {1} \
Where OBJ \
Group By {2} \
Order By {3} \
Into __THEME__STYLES NoSelect Hide"
elif objectType is 5:
qry = "Select {0} \"VALUE\", \
Str$(ObjectInfo(OBJ, OBJ_INFO_SYMBOL)) \"SYMBOL\" \
From {1} \
Where OBJ \
Group By {2} \
Order By {3} \
Into __THEME__STYLES NoSelect Hide"
if qry:
do(qry.format(col, tableAlias, col, col))
numRows = int(eval("TableInfo(__THEME__STYLES, TAB_INFO_NROWS)"))
print(numRows)
if numRows > 0:
themeCommand = None
symbol = None
value = None
do("Fetch First From __THEME__STYLES")
for i in range(numRows):
value = str(eval("__THEME__STYLES.VALUE"))
if objectType is 7:
rgb = get_random_rgb()
pen = "Pen (1,2, {})".format(rgb)
brush = "Brush (2, {}, 16777215)".format(rgb)
if not themeCommand:
themeCommand = " Values \"{0}\" {1} {2}".format(value, pen, brush)
else:
themeCommand += ", \"{0}\" {1} {2}".format(value, pen, brush)
elif objectType is 3:
pen = str(eval("__THEME__STYLES.PEN")).replace("Pen", "Line")
if not themeCommand:
themeCommand = " Values \"{0}\" {1}".format(value, pen)
else:
themeCommand += ", \"{0}\" {1}".format(value, pen)
elif objectType is 5:
symbol = str(eval("__THEME__STYLES.SYMBOL"))
if not themeCommand:
themeCommand = " Values \"{0}\" {1}".format(value, symbol)
else:
themeCommand += ", \"{0}\" {1}".format(value, symbol)
do("Fetch Next From __THEME__STYLES")
do("Close Table __THEME__STYLES")
do("Shade Window {0} {1} With {2} {3}".format(mapId, layer, col, themeCommand))
do("Create Designer Legend From Window {0} Behind Default Frame Style \"
except Exception as e:
print("Error: {}".format(e))
try:
table = pro.Catalog.OpenTable(abspath(join(dirname(__file__), r"..\Data\World\WORLD.TAB")))
if table:
shade_ind(7, table.Alias, "Country")
except Exception as e:
print("Error: {}".format(e))
Thanks
Anshul
------------------------------
Anshul Goel
Knowledge Community Shared Account
Shelton CT
Original Message:
Sent: 06-23-2020 21:13
From: Navjot Kaur
Subject: Using Python Script to Customize MapInfo Pro UI and Create Dialogs
Hi,
What is the correct way to Create Thematic map based on individual values in Python. In my data, I don't want to specifically mention values. Is there any way it can automatically take all values from a column and generate thematic map.
For example, in this case, I don't want to mention values because I am using Oracle table whose values keeps on changing.
do("shade Window FrontWindow() tablename With columnname Values 1, 2, 3"
Thanks,
Navjot
------------------------------
Navjot Kaur
Knowledge Community Shared Account
Original Message:
Sent: 06-03-2020 03:46
From: Anshul Goel
Subject: Using Python Script to Customize MapInfo Pro UI and Create Dialogs
Hi Navjot,
You can convert the PyQT5 dialog in custom_pyqt.py into a dialog like below:
import osos.environ['QT_USE_NATIVE_WINDOWS'] = "1"from PyQt5.QtWidgets import QPushButton, QWidget, QDialog, QVBoxLayoutimport win32.win32guiimport win32.lib.win32con as win32confrom mi_common_util import CommonUtilclass CustomQTDialog(QDialog): def __init__(self, pro, *args, **kwargs): super(CustomQTDialog, self).__init__(*args, **kwargs) self._pro = pro self.setWindowTitle("Dialog") self.resize(500, 500) b = QPushButton() b.setText("Say Hello!") b.clicked.connect(self.button_action) layout = QVBoxLayout() layout.addWidget(b) self.setLayout(layout) def button_action(self): try: print("Hello from QT!") table = self._pro.Catalog.OpenTable("D:\\maps\\asia\\asia.tab") if table: print(table.Alias) CommonUtil.do("map from {}".format(table.Alias)) except Exception as e: print("failed {}".format(e)) def showdialog(self, proHwnd): self.show()
Than this dialog can be invoked:
def on_open_dialog_qt_click(self, sender): try:
------------------------------
Anshul Goel
Knowledge Community Shared Account
Shelton CT
Original Message:
Sent: 06-02-2020 08:59
From: Navjot Kaur
Subject: Using Python Script to Customize MapInfo Pro UI and Create Dialogs
Can you please create class in PyQT5 dialog code and then import that in py_mapinfo_customization. I want to see how sample code looks for similar PyQT5 dialog when we create class in custom_pyqt.py
Thanks,
Navjot
------------------------------
Navjot Kaur
Knowledge Community Shared Account
Original Message:
Sent: 06-02-2020 03:12
From: Anshul Goel
Subject: Using Python Script to Customize MapInfo Pro UI and Create Dialogs
Hi Navjot,
I have updated the above sample to open up a PyQT5 dialog on button click of ribbon.
Thanks
Anshul
------------------------------
Anshul Goel
Knowledge Community Shared Account
Shelton CT
Original Message:
Sent: 06-01-2020 19:30
From: Navjot Kaur
Subject: Using Python Script to Customize MapInfo Pro UI and Create Dialogs
Hi Anshul,
Can you please help to create simple sample for following:
1. A customized button in MapInfo
2. When user clicks on that button then a PYQT5 dialog box opens up which is parent to MapInfo.
I am looking for something similar type of dialog box example that you have posted for WINFORM dialog but built with PYQT5.
Thanks,
Navjot
------------------------------
Navjot Kaur
Knowledge Community Shared Account
Original Message:
Sent: 05-29-2020 07:13
From: Anshul Goel
Subject: Using Python Script to Customize MapInfo Pro UI and Create Dialogs
Hello Navjot,
Here is a basic example of reparenting a dialog created in PyQT5 into MapInfo Pro and than interact with Pro using .Net API or MapBasic form Dialog button handlers. You can create python addin with PyQT5 dialogs using the sample approach.
For this example to run you have to install pyqt5 and pywin32 module in MapInfo Pro python installation.
After installing pywin32, you would need some aditional steps to get pywin32 module running in our environment, mentioned below.
- move the pywintype37.dll and pythoncom37.dll from <Pro Install Dir>\Python37\Lib\site-packages\pywin32_system32 folder to <Pro Install Dir>\Python37\Lib\site-packages\win32
import osos.environ['QT_USE_NATIVE_WINDOWS'] = "1"import sysfrom PyQt5.QtWidgets import QApplication, QPushButton, QWidget, QDialog, QVBoxLayoutfrom PyQt5 import QtGuifrom PyQt5 import QtCoreimport win32.win32guiimport win32.lib.win32con as win32condef application(): app = QApplication(sys.argv) try: showdialog() finally: app.exit()def showdialog():
Thanks
Anshul
------------------------------
Anshul Goel
Knowledge Community Shared Account
Shelton CT
Original Message:
Sent: 05-22-2020 08:37
From: Navjot Kaur
Subject: Using Python Script to Customize MapInfo Pro UI and Create Dialogs
Thanks Anshul!
Your post was very helpful. I have another question.
Can we use Python PYQT5 module created dialogs as well within MapInfo instead of Winform? It is very easy to create dialog in PYQT5designer but I don't know how to make those interacting with MapInfo.
If this is possible, can you please give some example on how to interact those with MapInfo.
Thanks,
Navjot
------------------------------
Navjot Kaur
Knowledge Community Shared Account
Original Message:
Sent: 05-20-2020 08:52
From: Anshul Goel
Subject: Using Python Script to Customize MapInfo Pro UI and Create Dialogs
I have updated the attached final addin with latest one.
Stay Tuned for the next post in thread regarding debugging of Python Addin in Visual Studio Code.
------------------------------
Anshul Goel
Knowledge Community Shared Account
Shelton CT
Original Message:
Sent: 05-20-2020 05:31
From: Anshul Goel
Subject: Using Python Script to Customize MapInfo Pro UI and Create Dialogs
Based on the Continued content about using Python script to create addins for MapInfo Pro, This post will help you in creating a Python Addin which will allow to customize the MapInfo Pro Ribbon, add some button and Create Dialogs.
Before we start, Please have a look at the post which will give you more information regarding the extent of support for Python in MapInfo Pro.
Now let get started:
Setup
- To Create an Addin in Python, we will first start by taking the Simple template provided in the MapBasic installation or attached. This template already has the startup code in main() class for MapInfo Pro Python Addin.
- SAMPLES\RIBBONINTERFACE\Python\py_addin_templates\Simple
- Once the template copied, we can start modifying it.
- Start with renaming the files → change <renameHere> to your addin name.
- Rename module reference as per your new file names.
- Check for all TODO in python code and modify the code as per your need.
Modifying the Ribbon
In your new Python module created above, lets look at the main() class, which is responsible to initialize and load a Python AddIn. main class should always be present if writing an AddIn or the Python module will be treated as standalone script.
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))
In the above main class, we are creating MyAddin class which is where we will start adding our code.
class MyAddin():
def __init__(self, imapinfopro, thisApplication):
try:
self._pro = imapinfopro
self._thisApplication = thisApplication
except Exception as e:
print("Failed to load: {}".format(e))
def unload(self):
self._thisApplication = None
self._pro = None
pass
Lets first start with modifying the MapInfo Pro Ribbon. We will create following things in MapInfo Pro Ribbon.
- New Ribbon Tab
- New Ribbon Group inside the Tab
- A Standard Tool Button
- A Custom Tool Button invoking a Python method.
- Button Creating Windows Forms Dialog.
- Button Creating A WPF Dialog.
All the above modification will be done to the UI when MyAddin class object is created, therefore we to have modified the __init__ and unload method of MyAddin class as below.
def __init__(self, imapinfopro, thisApplication):
try:
self._pro = imapinfopro
self._newTab = None
self._thisApplication = thisApplication
self.AddNewTabToRibbon()
except Exception as e:
print("Failed to load: {}".format(e))
def AddNewTabToRibbon(self):
pass
def unload(self):
if self._newTab:
self._pro.Ribbon.Tabs.Remove(self._newTab)
self._newTab = None
self._thisApplication = None
self._pro = None
Add a new Ribbon Tab and Ribbon Group
def AddNewTabToRibbon(self):
self._newTab = self._pro.Ribbon.Tabs.Add("RibbonCustomization","Ribbon Customization")
if self._newTab:
tabGroup = self._newTab.Groups.Add("DemoControls", "Demo Controls")
if tabGroup:
tabGroup.IsLauncherVisible = False
Once the Ribbon Group is added, let us add Button, ToolButtons to Ribbon and attach custom Python methods on button click.
def AddNewTabToRibbon(self):
self._newTab = self._pro.Ribbon.Tabs.Add("RibbonCustomization","Ribbon Customization")
if self._newTab:
tabGroup = self._newTab.Groups.Add("DemoControls", "Demo Controls")
if tabGroup:
tabGroup.IsLauncherVisible = False
buttonZoomIn = tabGroup.Controls.Add("ZoomInToolButton", "Zoom-In Tool", ControlType.ToolButton)
if buttonZoomIn:
buttonZoomIn.IsLarge = True
buttonZoomIn.KeyTip = "ZI"
buttonZoomIn.ToolTip = AddinUtil.create_tooltip("Zoom In", "Zoom In", "Open Mapper to use")
buttonZoomIn.LargeIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Mapping/zoomIn_32x32.png")
buttonZoomIn.SmallIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Mapping/zoomIn_16x16.png")
buttonZoomIn.CommandId = 1705
buttonZoomIn.Cursor = "129"
buttonZoomIn.DrawMode = 30
buttonZoomIn.BModifier = True
buttonCustomInfoTool = tabGroup.Controls.Add("InfoToolButton", "Info", ControlType.ToolButton)
if buttonCustomInfoTool:
buttonCustomInfoTool.IsLarge = True
buttonCustomInfoTool.KeyTip = "TI"
buttonCustomInfoTool.ToolTip = AddinUtil.create_tooltip("Info Tool", "Info Tool", "Open Map window to enable the tool.")
buttonCustomInfoTool.LargeIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Mapping/infoTool_32x32.png")
buttonCustomInfoTool.SmallIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Mapping/infoTool_16x16.png")
buttonCustomInfoTool.Cursor = "164"
buttonCustomInfoTool.DrawMode = 34
buttonCustomInfoTool.BModifierKeys = False
buttonCustomInfoTool.Command = AddinUtil.create_command(self.on_custom_info_tool_clicked)
tabGroup.Controls.Add("demoSeparator","Demo Seperator",ControlType.RibbonSeparator)
buttonOpenDialogWinForms = tabGroup.Controls.Add("OpenCustomDialogWinForms", "Open Dialog WinForms", ControlType.Button)
if buttonOpenDialogWinForms:
buttonOpenDialogWinForms.ToolTip = AddinUtil.create_tooltip("Open Dialog","Open Dialog", "Open Dialog")
buttonOpenDialogWinForms.Command = AddinUtil.create_command(self.on_open_dialog_winforms_click)
buttonOpenDialogWinForms.LargeIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Application/exportAsImage_32x32.png")
buttonOpenDialogWinForms.SmallIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Application/exportAsImage_16x16.png")
buttonOpenDialogWpf = tabGroup.Controls.Add("OpenCustomDialogWPF", "Open Dialog WPF", ControlType.Button)
if buttonOpenDialogWpf:
buttonOpenDialogWpf.ToolTip = AddinUtil.create_tooltip("Open Dialog","Open Dialog", "Open Dialog")
buttonOpenDialogWpf.Command = AddinUtil.create_command(self.on_open_dialog_wpf_click)
buttonOpenDialogWpf.LargeIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Application/exportAsImage_32x32.png")
buttonOpenDialogWpf.SmallIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Application/exportAsImage_16x16.png")
endProgram = tabGroup.Controls.Add("EndProgram", "End Program", ControlType.Button)
if endProgram:
endProgram.KeyTip = "LE"
endProgram.ToolTip = AddinUtil.create_tooltip("End Program Tooltip Description","End Program ToolTip Text", "End Program Disabled Text")
endProgram.Command = AddinUtil.create_command(self.on_end_application)
endProgram.LargeIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Table/closeTable_32x32.png")
endProgram.SmallIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Table/closeTable_16x16.png")
def on_open_dialog_winforms_click(self, sender):
try:
pass
except Exception as e:
print("Failed to execute: {}".format(e))
def on_open_dialog_wpf_click(self, sender):
try:
pass
except Exception as e:
print("Error: {}".format(e))
def on_custom_info_tool_clicked(self, sender):
try:
x1 = CommonUtil.eval("commandinfo(1)")
y1 = CommonUtil.eval("commandinfo(2)")
notification = NotificationObject()
if notification:
formatted_msg = "X: {}\nY: {}".format(x1, y1)
CommonUtil.do("print \"{}\"".format(formatted_msg))
notification.Message = formatted_msg
notification.Title = "Map Coordinates"
notification.Type = NotificationType.Info
notification.TimeToShow = 2000
notification.NotificationLocation = Point(-1,-1)
self._pro.ShowNotification(notification)
except Exception as e:
print("Failed to execute: {}".format(e))
def on_end_application(self, sender):
try:
if self._thisApplication:
self._thisApplication.EndApplication()
except Exception as e:
CommonUtil.sprint("Failed to load: {}".format(e))
Creating a WinForms Dialog
To create a WinForms dialog we will add a new class HelloForm in a separate Python module custom_winforms.py.
- Class HelloForm extends WinForm.Form C# class
- Adds Button to the Form.
- Attach a python method to click event of Button and execute Note mapbasic statement inside the event handler.
import clr
clr.AddReference("System.Windows.Forms")
import System.Windows.Forms as WinForms
from System.Drawing import Size, Point
from mi_common_util import *
class HelloForm(WinForms.Form):
def __init__(self, parent):
self.AutoScaleBaseSize = Size(8, 16)
self.AutoScaleMode = WinForms.AutoScaleMode.Font
self.ClientSize = Size(352, 212)
self.Name = "Form1"
self.Text = "Custom Dialog"
self.StartPosition = WinForms.FormStartPosition.CenterParent
self.Parent = WinForms.Control.FromHandle(parent)
self.button = WinForms.Button()
self.button.Location = Point(13, 85)
self.button.Size = Size(327, 23)
self.button.Text = "Click Me!"
self.button.Click += self.button_Click
self.Controls.Add(self.button)
def button_Click(self, sender, args):
"""Button click event handler"""
CommonUtil.do("note \"Button Click\"")
To Show the WinForms Dialog on click of Ribbon Button, let us modify the on_open_dialog_winforms_click on MyAddin class.
def on_open_dialog_winforms_click(self, sender):
try:
form = HelloForm(self._pro.MainHwnd)
if form:
form.ShowDialog()
except Exception as e:
print("Failed to execute: {}".format(e))
Creating a WPF Dialog
First create a XAML for the dialog UI. UI that we have created has ContentControl to show Map and as three button at bottom of the dialog.
Note : When created a XAML UI, we need to make sure to give x:Name to all the controls in the XAML so that Python can easily find the controls.
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Custom Dialog"
Height="400" Width="400"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<ContentControl x:Name="Mapper" Grid.Row="0"/>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Button x:Name="AddMapButton" Margin="5,5,5,5" VerticalAlignment="Bottom" IsDefault="False">Add Map</Button>
<Button x:Name="ShowTableInfo" Margin="5,5,5,5" VerticalAlignment="Bottom">Table Info</Button>
<Button x:Name="CloseButton" Margin="5,5,5,5" VerticalAlignment="Bottom" IsDefault="True" IsCancel="True">Close</Button>
</StackPanel>
</Grid>
</Window>
In Creating a WPF Dialog we will take MVVM approach, which will have a view, presenter and model.
We will create a Python module (custom_view_view.py) which will parse this XAML and convert it into a WPF Dialog. This module will be out view.
from mi_addin_util import AddinUtil
from os.path import join, dirname
class View:
XAML_FILE = "custom_view.xaml"
def __init__(self):
self._window = None
@property
def window(self):
if not self._window:
self._window = AddinUtil.create_user_control(join(dirname(__file__), self.XAML_FILE))
return self._window
def _on_close(self, new_value):
if new_value:
self.window.Closing += new_value
self.CloseButton.Click += new_value
on_close = property(None, _on_close)
def showdialog(self, parent):
if self._window is not None:
AddinUtil.set_dialog_parent(self._window, parent)
return self._window.ShowDialog()
return None
def _add_map_click(self, new_value):
if new_value:
self.AddMapButton.Click += new_value
add_map_click = property(None, _add_map_click)
def _info_click(self, new_value):
if new_value:
self.ShowTableInfo.Click += new_value
info_click = property(None, _info_click)
def __getattr__(self, name):
return AddinUtil.find_logical_control(self.window, name)
The above custom_view_view.py module needs a presenter or controller to handle user interaction/clicks and allow interaction between MapInfo Pro and Python. To all this stuff we will create another Python module custom_view_presenter.py.
import sys
from custom_view_model import Model
from custom_view_view import View
from MapInfo.Types import MessageOutput
from mi_addin_util import AddinUtil
from mi_common_util import CommonUtil
from System import Int32
sys.stdout = sys.stderr = sys.stdin = MessageOutput()
class Presenter:
def __init__(self, view, imapinfopro):
self._view = view
self._pro = imapinfopro
self._winId = -1
self._table_name = None
def add_map(self, event, sender):
try:
if self._winId is not -1:
self.close_map()
table_name = input("Table Name")
if table_name:
el, self._winId = self._pro.CreateUnattachedWindow("map from {}".format(table_name), Int32(0))
if el:
self._view.Mapper.Content = AddinUtil.create_user_control_from_handle(el)
self._table_name = table_name
except Exception as e:
print("Failed to execute: {}".format(e))
def close_map(self):
try:
self._view.Mapper.Content = None
if self._winId is not -1:
win = self._pro.Windows.FromId(self._winId)
if win:
win.Close()
self._winId = -1
self._table_name = None
except Exception as e:
print("Failed to execute: {}".format(e))
def on_close(self, event, sender):
self.close_map()
def info_click(self, event, sender):
try:
if self._table_name:
CommonUtil.do("open window message")
print(CommonUtil.eval("TableInfo({}, TAB_INFO_NAME)".format(self._table_name)))
print(CommonUtil.eval("TableInfo({}, TAB_INFO_NCOLS)".format(self._table_name)))
print(CommonUtil.eval("TableInfo({}, TAB_INFO_NROWS)".format(self._table_name)))
print(CommonUtil.eval("TableInfo({}, TAB_INFO_MAPPABLE)".format(self._table_name)))
print(CommonUtil.eval("TableInfo({}, TAB_INFO_COORDSYS_CLAUSE)".format(self._table_name)))
print(CommonUtil.eval("TableInfo({}, TAB_INFO_CHARSET)".format(self._table_name)))
except Exception as e:
print("Failed to execute: {}".format(e))
def showdialog(self):
try:
self._view.on_close = self.on_close
self._view.add_map_click = self.add_map
self._view.info_click = self.info_click
self._view.showdialog(self._pro.MainHwnd)
except Exception as e:
print("Failed to execute: {}".format(e))
@staticmethod
def create(imapinfopro):
try:
return Presenter(View(), imapinfopro)
except Exception as e:
print("Error: {}".format(e))
Final step in creating a WPF dialog is to invoke it when user click button on MapInfo Pro Ribbon for which we will again look into MyAddin class and modify on_open_dialog_wpf_click method.
def on_open_dialog_wpf_click(self, sender):
try:
presenter = Presenter.create(self._pro)
if presenter:
presenter.showdialog()
presenter = None
except Exception as e:
print("Error: {}".format(e))
We can run this Addin in MapInfo Pro by selecting the module with main() class (py_mapinfo_customization.py) from Run Program dialog.
This completes our Python Addin development. Final developed addin mentioned in this post is attached.
Thanks
Anshul
------------------------------
Anshul Goel
Knowledge Community Shared Account
Shelton CT
------------------------------