Assign Action does not execute python code

Hello,

I have made a sample dialog which has username and password like this:
image
I have used the sample similar to
Python Listeners: Creating Event Listeners

This works correct as to be expected. However when i tried to implement using the interface (Assign Action):

image

The events simply would not fire. Is there is a reason for this? Am I stuck with putting ActionEvents in code? Thank you for your help

Please add the portion of the code you are using that handles the event successfully, both the registration and the handling, This way the community can see exactly what is working, and if code is necessary, others seeing this question can use it when the UI method doesn’t work as might be expected.

from __future__ import unicode_literals
import cx_Oracle
import ctypes
import uno, unohelper
from com.sun.star.awt import XActionListener
from com.sun.star.awt import ActionEvent
from com.sun.star.lang import EventObject
from com.sun.star.ui.dialogs.ExecutableDialogResults import OK, CANCEL
import msgbox as util

_MY_BUTTON =  "btnLogin"
_MY_LABEL = 'Python listens..'
_DLG_PROVIDER = "com.sun.star.awt.DialogProvider"

##--openForm-- is called from the MouseDown event of a drawing object 
## this initializes the global variable _ui and then execute the dialog
def openForm():
	global _ui
	_ui = createUnoDialog("Standard.dlgLogin", embedded=False)
	ctl=_ui.getControl(_MY_BUTTON)
	act = ActionListener()
	ctl.addActionListener(act)
	_ui.execute()
	return None

##--login-- is called from the Action object of the Login button
## _ui should have been initialized
## this code works as is - however when i try to assign it to an Event using the Assign Action it does 
## not work
def login():
	txtUserId = _ui.getControl("txtUserId").getText()
	txtPwd = _ui.getControl("txtPwd").getText()
	cbDbSources=_ui.getControl("cbDbSources").getText()
	MsgBox(cbDbSources)
	connection = cx_Oracle.connect(user=txtUserId,password=txtPwd,dsn=cbDbSources)
	try:
		connection.cursor()
		connection.close()
		MsgBox('success')
	except Exception as ex:
		MsgBox('fail')
	return None


def createUnoDialog(libr_dlg: str, embedded=False):
	ctx = XSCRIPTCONTEXT.getComponentContext()
	smgr = ctx.ServiceManager
	if embedded:
		model = XSCRIPTCONTEXT.getDocument()
		dp = smgr.createInstanceWithArguments(_DLG_PROVIDER, (model,))
		location = "?location=document"
	else:
		dp = smgr.createInstanceWithContext(_DLG_PROVIDER, ctx)
		location = "?location=application"
	return dp.createDialog("vnd.sun.star.script:"+libr_dlg+location)

	
def MsgBox(txt:str):
	mb = util.MsgBox(uno.getComponentContext())
	mb.addButton("0k")
	mb.show(txt,0, "Python")
	return None
	
class ActionListener(unohelper.Base, XActionListener):
	def __init__(self):
		self.count = 0
	def actionPerformed(self, evt: ActionEvent):
		if evt.Source.Model.Name == _MY_BUTTON:
			login()
	def disposing(self, evt: EventObject):  # mandatory routine
		pass

You don’t need your own log-in dialog to log in at a database. Tell the connected Base document that a log-in is required and you get a log-in dialog for free.
Open the Base document and call Edit > Database >Properties… or Connection …

I suppose that for the purpose of connecting to the database that would be a good solution. For the purpose of my work I would like to assign action to Python code and not Basic code. Hope this clarifies my problem. Thank you.

I was talking about calling no code at all because the underlying database (MySQL or whatever) can ask for the user log-in and Base will show a log-in dialog fully automatically.
Is your moduleLogin.py a macro or a component? Does it appear under Tools>Macros>Organize>Python or not?

If the task is about switching the data source of a serial letter, “my users” (elderly ladies) are very happy with this solution:
Writer menu: Edit>Exchange Database… and select the right query for the right letter template.
It is the obligation of the administrator (me) that every data source has at least one query for the serial letter in question. Such a query makes use of SQL aliases so the right database columns are assigned to the right mail merge fields.
Data source A, query “Patients Letter”: SELECT “FN” As “Forename”, “SN” AS “Surname”, … FROM “PatientsList”
Data source B, query “Patients Letter”: SELECT “Vorname” As “Forename”, “Nachname” AS “Surname”, … FROM “PatientenListe”
Both queries in both data sources return equally named fields from differently named columns and tables. The user calls the “exchange database” dialog, picks query “Patients Letter” from either source and gets the right data in her form letter. If the database requires a log-in, the user will be prompted automatically. All this can be done without writing a single line of code utilizing the built-in features of this office suite and a tiny little bit of user training.
Every now and then the admin (me) needs to refine a query to match certain conditions in the WHERE clause or prompt for a parameter (no code required) or simply dump all relevant data onto a spreadsheet and create a new data source from that spreadsheet for a one-off solution.

Hello,

I found out what the problem was. I made modification to the code:

rom __future__ import unicode_literals
import cx_Oracle
import ctypes
import uno, unohelper
from com.sun.star.awt import XActionListener
from com.sun.star.awt import ActionEvent
from com.sun.star.lang import EventObject
from com.sun.star.ui.dialogs.ExecutableDialogResults import OK, CANCEL
import msgbox as util

_MY_BUTTON =  "btnLogin"
_MY_LABEL = 'Python listens..'
_DLG_PROVIDER = "com.sun.star.awt.DialogProvider"


## Here is the modification to the code - the original def for login was def login():
## you can see the modification below. For some reason during events parameters are fed to any def 
##even if non are specified. the parameter with default (embedded=False) is simply a dummy so that
## the code can execute without error
def login(embedded=False):

	txtUserId = _ui.getControl("txtUserId").getText()
	txtPwd = _ui.getControl("txtPwd").getText()
	cbDbSources=_ui.getControl("cbDbSources").getText()
	connection = cx_Oracle.connect(user=txtUserId,password=txtPwd,dsn=cbDbSources)
	try:
		connection.cursor()
		connection.close()
		MsgBox('success')
	except Exception as ex:
		MsgBox('fail')
	return None

def checkDB():
	global _ui
	_ui = createUnoDialog("Standard.dlgLogin", embedded=False)
	ctl=_ui.getControl(_MY_BUTTON)
	#act = ActionListener()
	#ctl.addActionListener(act)
	_ui.execute()
	return None
def createUnoDialog(libr_dlg: str, embedded=False):
	ctx = XSCRIPTCONTEXT.getComponentContext()
	smgr = ctx.ServiceManager
	if embedded:
		model = XSCRIPTCONTEXT.getDocument()
		dp = smgr.createInstanceWithArguments(_DLG_PROVIDER, (model,))
		location = "?location=document"
	else:
		dp = smgr.createInstanceWithContext(_DLG_PROVIDER, ctx)
		location = "?location=application"
	return dp.createDialog("vnd.sun.star.script:"+libr_dlg+location)

	
def MsgBox(txt:str):
	mb = util.MsgBox(uno.getComponentContext())
	mb.addButton("0k")
	mb.show(txt,0, "Python")
	return None

It seems that all python def’s require some parameter, even if they are dummy parameters, when they are part of an Assigned Action from an object within a dialog.

1 Like

All Python routine that handle events require an event argument, while routines that create dialogs may not.

Have a look Creating event listener help page

1 Like