Hi,
i have a GUI and my GUI Toolkit is wxPython. Now when the GUI opens...whatever tabs and buttons i click...an action is performed. Each mouse click is an event and it is processed in the script accordingly.
Now i want to operate that GUI without using the mouse..i'e thru my script....
for example...in the original python script...there is a function "OnBrowseForReport Directory". When i click on the tab for browse in the GUI....a dialog opens from where i can choose my report directory and click on OK. The directory gets chosen...but all these actions are performed on the click of the mouse...i.e manually. I want to automate the entire thing...i.e I want to open the dialog thru my own python script and choose the directory without clicking on the "OK" tab...i.e thru my script.....i want to use the underlyting fumction "OnBrowseForReport Directory"...
Plz help...it's urgent!!
19 1896
Hi,
i have a GUI and my GUI Toolkit is wxPython. Now when the GUI opens...whatever tabs and buttons i click...an action is performed. Each mouse click is an event and it is processed in the script accordingly.
Now i want to operate that GUI without using the mouse..i'e thru my script....
for example...in the original python script...there is a function "OnBrowseForReport Directory". When i click on the tab for browse in the GUI....a dialog opens from where i can choose my report directory and click on OK. The directory gets chosen...but all these actions are performed on the click of the mouse...i.e manually. I want to automate the entire thing...i.e I want to open the dialog thru my own python script and choose the directory without clicking on the "OK" tab...i.e thru my script.....i want to use the underlyting fumction "OnBrowseForReport Directory"...
Plz help...it's urgent!!
"OnBrowseForReport Directory" can't really be the name because of the space in there (I'll use "OnBrowseForReport" in my explanation:
The easiest way to do this is to add a button (or menu item, or whaterver) to start the action you want. Then you can call self.OnBrowseForReport(None) as long as the event handler never calls any event.WhatEver()s. And so on, until all actions are complete.
"OnBrowseForReport Directory" can't really be the name because of the space in there (I'll use "OnBrowseForReport" in my explanation:
The easiest way to do this is to add a button (or menu item, or whaterver) to start the action you want. Then you can call self.OnBrowseForReport(None) as long as the event handler never calls any event.WhatEver()s. And so on, until all actions are complete.
Cudn't get u...let me explain it a bit....
thr's one function which looks like this -
-
def OnBrowseForDeviceWrapperFile(self, event):
-
'''Allows the user to select a 'device wrapper' file via a dialog.'''
-
-
dlg = wx.FileDialog(
-
self, message="Choose a Device Wrapper file",
-
wildcard=deviceWrapperFileFilter, style=wx.OPEN|wx.CHANGE_DIR)
-
-
if dlg.ShowModal() == wx.ID_OK:
-
-
# get the new filename from the dialog, then update the test setup
-
# and GUI to reflect the change...
-
filename = dlg.GetPath()
-
self.testSetup.DeviceWrapperFilename = filename
-
self.textCtrls['DeviceWrapperFilename'].SetValue(filename)
-
self.refreshSetupModifiedFlag()
-
-
dlg.Destroy()
-
this function takes an event as input. I don't want to select the directory using mouse click.
How do i go about it??
Cudn't get u...let me explain it a bit....
thr's one function which looks like this -
-
def OnBrowseForDeviceWrapperFile(self, event):
-
'''Allows the user to select a 'device wrapper' file via a dialog.'''
-
-
dlg = wx.FileDialog(
-
self, message="Choose a Device Wrapper file",
-
wildcard=deviceWrapperFileFilter, style=wx.OPEN|wx.CHANGE_DIR)
-
-
if dlg.ShowModal() == wx.ID_OK:
-
-
# get the new filename from the dialog, then update the test setup
-
# and GUI to reflect the change...
-
filename = dlg.GetPath()
-
self.testSetup.DeviceWrapperFilename = filename
-
self.textCtrls['DeviceWrapperFilename'].SetValue(filename)
-
self.refreshSetupModifiedFlag()
-
-
dlg.Destroy()
-
this function takes an event as input. I don't want to select the directory using mouse click.
How do i go about it??
You may want to consider refactoring.
Let's see if I can explain:
Presumably, OnBrowseForDeviceWrapperFile() is caused by a button or menu, etc., which gives an interactive (file dialog) means of getting file name.
If you have the file name already you would refactor thusly: -
-
def OnBrowseForDeviceWrapperFile(self, event):
-
'''Allows the user to select a 'device wrapper' file via a dialog.'''
-
filename = "" # Use filename as a flag
-
dlg = wx.FileDialog(
-
self, message="Choose a Device Wrapper file",
-
wildcard=deviceWrapperFileFilter, style=wx.OPEN|wx.CHANGE_DIR)
-
-
if dlg.ShowModal() == wx.ID_OK:
-
-
# get the new filename from the dialog, then update the test setup
-
# and GUI to reflect the change...
-
filename = dlg.GetPath()
-
dlg.Destroy() # best to do this sooner than later
-
-
if filename:
-
self.UpdateInterface(filename)
-
-
def UpdateInterface(self, filename):
-
self.testSetup.DeviceWrapperFilename = filename
-
self.textCtrls['DeviceWrapperFilename'].SetValue(filename)
-
self.refreshSetupModifiedFlag()
-
By refactoring, you make the update code available to other methods.
If you don't already have the file name and you are trying to (say) start your program with command-line arguments, those will be availble in the first module that is used to launch your program as in - # file 'MyModule.py'
-
import sys
-
print sys.argv
The first argument is always the name of the first module as in
['MyModule.py']
You may want to consider refactoring.
Let's see if I can explain:
Presumably, OnBrowseForDeviceWrapperFile() is caused by a button or menu, etc., which gives an interactive (file dialog) means of getting file name.
If you have the file name already you would refactor thusly: -
-
def OnBrowseForDeviceWrapperFile(self, event):
-
'''Allows the user to select a 'device wrapper' file via a dialog.'''
-
filename = "" # Use filename as a flag
-
dlg = wx.FileDialog(
-
self, message="Choose a Device Wrapper file",
-
wildcard=deviceWrapperFileFilter, style=wx.OPEN|wx.CHANGE_DIR)
-
-
if dlg.ShowModal() == wx.ID_OK:
-
-
# get the new filename from the dialog, then update the test setup
-
# and GUI to reflect the change...
-
filename = dlg.GetPath()
-
dlg.Destroy() # best to do this sooner than later
-
-
if filename:
-
self.UpdateInterface(filename)
-
-
def UpdateInterface(self, filename):
-
self.testSetup.DeviceWrapperFilename = filename
-
self.textCtrls['DeviceWrapperFilename'].SetValue(filename)
-
self.refreshSetupModifiedFlag()
-
By refactoring, you make the update code available to other methods.
If you don't already have the file name and you are trying to (say) start your program with command-line arguments, those will be availble in the first module that is used to launch your program as in - # file 'MyModule.py'
-
import sys
-
print sys.argv
The first argument is always the name of the first module as in
['MyModule.py']
Hi,
I did what u had asked, when i call the function "OnBrowseForDeviceWrapperFile", it opens a dialog but i have to manually select the file and click on open. It is not doing it on it's own.
Hi,
I did what u had asked, when i call the function "OnBrowseForDeviceWrapperFile", it opens a dialog but i have to manually select the file and click on open. It is not doing it on it's own.
I suggested that you use -
def UpdateInterface(self, filename):
-
self.testSetup.DeviceWrapperFilename = filename
-
self.textCtrls['DeviceWrapperFilename'].SetValue(filename)
-
self.refreshSetupModifiedFlag()
-
and call it - self.UpdateInterface(aKnownFileName)
I suggested that you use -
def UpdateInterface(self, filename):
-
self.testSetup.DeviceWrapperFilename = filename
-
self.textCtrls['DeviceWrapperFilename'].SetValue(filename)
-
self.refreshSetupModifiedFlag()
-
and call it - self.UpdateInterface(aKnownFileName)
i called UpdateInterface with a known filename sa input...this time the dialog did not open ...however the GUI remained empty i.e the column where the file name(after it is selected thru the GUI) is reflected, remained vacent.
i called UpdateInterface with a known filename sa input...this time the dialog did not open ...however the GUI remained empty i.e the column where the file name(after it is selected thru the GUI) is reflected, remained vacent.
Thats odd. If it works one way (file dialog get file name) it will work the other.
Try -
def UpdateInterface(self, filename):
-
print filename
-
self.testSetup.DeviceWrapperFilename = filename
-
self.textCtrls['DeviceWrapperFilename'].SetValue(filename)
-
self.refreshSetupModifiedFlag()
-
as a quick debugging test. If filename gets printed, it should also be Set in the TextCtrl.
Are you working in an IDE that will show you if an error occured?
Thats odd. If it works one way (file dialog get file name) it will work the other.
Try -
def UpdateInterface(self, filename):
-
print filename
-
self.testSetup.DeviceWrapperFilename = filename
-
self.textCtrls['DeviceWrapperFilename'].SetValue(filename)
-
self.refreshSetupModifiedFlag()
-
as a quick debugging test. If filename gets printed, it should also be Set in the TextCtrl.
Are you working in an IDE that will show you if an error occured?
Hi,
My script looks something like this -
import traceback
-
import thread
-
import pst
-
import petShopTest
-
-
class newclass:
-
-
def __init__(self):
-
newApp = petShopTest.MyApp(0)
-
newFrame = petShopTest.MyFrame(None, -1, "PetShopTest")
-
self.testsetup = pst.TestSetup()
-
self.Log = logging.getLogger('GUI')
-
path = "c:\pst\pst_modified\Flash_Test.py"
-
path1 = "c:\pst\pst_modified\DeviceCommsLayer_984_v6_00.py"
-
path2 = "c:\python23"
-
-
-
newFrame.UpdateInterfaceForDeviceWrapper(path1)
-
-
newApp.MainLoop()
-
-
and the UpdateInterfaceForDeviceWrapper function looks like this: -
def UpdateInterfaceForDeviceWrapper(self,filename):
-
print filename
-
print "in update"
-
self.testSetup.DeviceWrapperFilename = filename
-
self.textCtrls['DeviceWrapperFilename'].SetValue(filename)
-
self.refreshSetupModifiedFlag()
-
i am executing this on python command promt window like this: -
import myfilename
-
myfilename.newclass()
-
and it shows the following: -
c:\pst\pst_modified\DeviceCommsLayer_984_v6_00.py
-
in update
-
-
and nothing appears on the GUI...the GUI remains vacant!!:(
It's not showing any errors.
Hi,
My script looks something like this -
import traceback
-
import thread
-
import pst
-
import petShopTest
-
-
class newclass:
-
-
def __init__(self):
-
newApp = petShopTest.MyApp(0)
-
newFrame = petShopTest.MyFrame(None, -1, "PetShopTest")
-
self.testsetup = pst.TestSetup()
-
self.Log = logging.getLogger('GUI')
-
path = "c:\pst\pst_modified\Flash_Test.py"
-
path1 = "c:\pst\pst_modified\DeviceCommsLayer_984_v6_00.py"
-
path2 = "c:\python23"
-
-
-
newFrame.UpdateInterfaceForDeviceWrapper(path1)
-
-
newApp.MainLoop()
-
-
and the UpdateInterfaceForDeviceWrapper function looks like this: -
def UpdateInterfaceForDeviceWrapper(self,filename):
-
print filename
-
print "in update"
-
self.testSetup.DeviceWrapperFilename = filename
-
self.textCtrls['DeviceWrapperFilename'].SetValue(filename)
-
self.refreshSetupModifiedFlag()
-
i am executing this on python command promt window like this: -
import myfilename
-
myfilename.newclass()
-
and it shows the following: -
c:\pst\pst_modified\DeviceCommsLayer_984_v6_00.py
-
in update
-
-
and nothing appears on the GUI...the GUI remains vacant!!:(
It's not showing any errors.
That helps a lot!
Mainloop() has to be running before widgets will act. -
class newclass:
-
-
def __init__(self):
-
newApp = petShopTest.MyApp(0)
-
self.newFrame = newFrame = petShopTest.MyFrame(None, -1, "PetShopTest")
-
self.testsetup = pst.TestSetup()
-
self.Log = logging.getLogger('GUI')
-
path = "c:\pst\pst_modified\Flash_Test.py"
-
path1 = "c:\pst\pst_modified\DeviceCommsLayer_984_v6_00.py"
-
path2 = "c:\python23"
-
-
-
wx.FutureCall(100, self.SendFileName)
-
-
newApp.MainLoop()
-
-
def SendFileName(self):
-
self.newFrame.UpdateInterfaceForDeviceWrapper(path1)
But if you are calling from the command-line, why not - import sys
-
-
-
wx.FutureCall(100, self.GetFileName)
-
-
newApp.MainLoop()
-
-
def GetFileName(self):
-
filename = sys.argv[1]
-
self.newFrame.UpdateInterfaceForDeviceWrapper(filename)
python TestWhatever c:\pst\pst_modified\DeviceCommsLayer_984_v6_00.py
That helps a lot!
Mainloop() has to be running before widgets will act. -
class newclass:
-
-
def __init__(self):
-
newApp = petShopTest.MyApp(0)
-
self.newFrame = newFrame = petShopTest.MyFrame(None, -1, "PetShopTest")
-
self.testsetup = pst.TestSetup()
-
self.Log = logging.getLogger('GUI')
-
path = "c:\pst\pst_modified\Flash_Test.py"
-
path1 = "c:\pst\pst_modified\DeviceCommsLayer_984_v6_00.py"
-
path2 = "c:\python23"
-
-
-
wx.FutureCall(100, self.SendFileName)
-
-
newApp.MainLoop()
-
-
def SendFileName(self):
-
self.newFrame.UpdateInterfaceForDeviceWrapper(path1)
But if you are calling from the command-line, why not - import sys
-
-
-
wx.FutureCall(100, self.GetFileName)
-
-
newApp.MainLoop()
-
-
def GetFileName(self):
-
filename = sys.argv[1]
-
self.newFrame.UpdateInterfaceForDeviceWrapper(filename)
python TestWhatever c:\pst\pst_modified\DeviceCommsLayer_984_v6_00.py
Did according to what u suggested. No change in the output. It is the same as before: :( -
c:\pst\pst_modified\DeviceCommsLayer_984_v6_00.py
-
in update
-
and nothing was reflected in the GUI!! :(
Did according to what u suggested. No change in the output. It is the same as before: :( -
c:\pst\pst_modified\DeviceCommsLayer_984_v6_00.py
-
in update
-
and nothing was reflected in the GUI!! :(
I'll try to get some time to work up some running code later on today or tonight.
This one has me baffled, because that should have worked.
I'll try to get some time to work up some running code later on today or tonight.
This one has me baffled, because that should have worked.
Hi,
Did u see it?? it's still not working!!
I'll try to get some time to work up some running code later on today or tonight.
This one has me baffled, because that should have worked.
Hi,
Please help me out with the problem. Did u find some way out of it??
Hi,
Please help me out with the problem. Did u find some way out of it??
I did a test: - #Boa:Frame:Frame2
-
-
import wx
-
-
def create(parent):
-
return Frame1(parent)
-
-
[wxID_FRAME1, wxID_FRAME1PANEL1, wxID_FRAME1TEXTCTRL1,
-
] = [wx.NewId() for _init_ctrls in range(3)]
-
-
class Frame1(wx.Frame):
-
def _init_sizers(self):
-
# generated method, don't edit
-
self.boxSizer1 = wx.BoxSizer(orient=wx.VERTICAL)
-
-
self._init_coll_boxSizer1_Items(self.boxSizer1)
-
-
self.SetSizer(self.boxSizer1)
-
-
-
def _init_coll_boxSizer1_Items(self, parent):
-
# generated method, don't edit
-
-
parent.AddWindow(self.panel1, 1, border=0, flag=wx.EXPAND)
-
-
def _init_ctrls(self, prnt):
-
# generated method, don't edit
-
wx.Frame.__init__(self, id=wxID_FRAME1, name='', parent=prnt, pos=wx.Point(22, 22),
-
size=wx.Size(400, 250), style=wx.DEFAULT_FRAME_STYLE, title='Frame1')
-
self.SetClientSize(wx.Size(392, 223))
-
-
self.panel1 = wx.Panel(id=wxID_FRAME1PANEL1, name='panel1', parent=self, pos=wx.Point(0, 0),
-
size=wx.Size(392, 223), style=wx.TAB_TRAVERSAL)
-
-
self.textCtrl1 = wx.TextCtrl(id=wxID_FRAME1TEXTCTRL1, name='textCtrl1', parent=self.panel1,
-
pos=wx.Point(16, 72), size=wx.Size(360, 21), style=0, value='')
-
-
self._init_sizers()
-
-
def __init__(self, parent):
-
self._init_ctrls(parent)
-
- #!/usr/bin/env python
-
#Boa:App:BoaApp
-
-
import wx
-
-
import Frame2
-
-
modules ={u'Frame2': [1, 'Main frame of Application', u'Frame2.py']}
-
-
class BoaApp(wx.App):
-
def OnInit(self):
-
self.main = Frame2.create(None)
-
## this is NOT good OOP encapulation, but it works ##
-
self.main.textCtrl1.SetValue('this is a test')
-
# #
-
self.main.Show()
-
self.SetTopWindow(self.main)
-
return True
-
-
def main():
-
application = BoaApp(0)
-
application.MainLoop()
-
-
if __name__ == '__main__':
-
main()
-
I can set the TextCtrl Value while the app is being initialized.
I did a test: - #Boa:Frame:Frame2
-
-
import wx
-
-
def create(parent):
-
return Frame1(parent)
-
-
[wxID_FRAME1, wxID_FRAME1PANEL1, wxID_FRAME1TEXTCTRL1,
-
] = [wx.NewId() for _init_ctrls in range(3)]
-
-
class Frame1(wx.Frame):
-
def _init_sizers(self):
-
# generated method, don't edit
-
self.boxSizer1 = wx.BoxSizer(orient=wx.VERTICAL)
-
-
self._init_coll_boxSizer1_Items(self.boxSizer1)
-
-
self.SetSizer(self.boxSizer1)
-
-
-
def _init_coll_boxSizer1_Items(self, parent):
-
# generated method, don't edit
-
-
parent.AddWindow(self.panel1, 1, border=0, flag=wx.EXPAND)
-
-
def _init_ctrls(self, prnt):
-
# generated method, don't edit
-
wx.Frame.__init__(self, id=wxID_FRAME1, name='', parent=prnt, pos=wx.Point(22, 22),
-
size=wx.Size(400, 250), style=wx.DEFAULT_FRAME_STYLE, title='Frame1')
-
self.SetClientSize(wx.Size(392, 223))
-
-
self.panel1 = wx.Panel(id=wxID_FRAME1PANEL1, name='panel1', parent=self, pos=wx.Point(0, 0),
-
size=wx.Size(392, 223), style=wx.TAB_TRAVERSAL)
-
-
self.textCtrl1 = wx.TextCtrl(id=wxID_FRAME1TEXTCTRL1, name='textCtrl1', parent=self.panel1,
-
pos=wx.Point(16, 72), size=wx.Size(360, 21), style=0, value='')
-
-
self._init_sizers()
-
-
def __init__(self, parent):
-
self._init_ctrls(parent)
-
- #!/usr/bin/env python
-
#Boa:App:BoaApp
-
-
import wx
-
-
import Frame2
-
-
modules ={u'Frame2': [1, 'Main frame of Application', u'Frame2.py']}
-
-
class BoaApp(wx.App):
-
def OnInit(self):
-
self.main = Frame2.create(None)
-
## this is NOT good OOP encapulation, but it works ##
-
self.main.textCtrl1.SetValue('this is a test')
-
# #
-
self.main.Show()
-
self.SetTopWindow(self.main)
-
return True
-
-
def main():
-
application = BoaApp(0)
-
application.MainLoop()
-
-
if __name__ == '__main__':
-
main()
-
I can set the TextCtrl Value while the app is being initialized.
Hi,
This does not serve my purpose. I want to set some value in a box thru my script which wud have ,otherwise,been set by clicking on a browse tab and then selecting a file by a mouse click.
Hi,
This does not serve my purpose. I want to set some value in a box thru my script which wud have ,otherwise,been set by clicking on a browse tab and then selecting a file by a mouse click.
It may not serve your purpose, but it shows you that you should be able to set the Value of a TextCtrl from outside the frame that creates it.
And since you have not provided the frame to work on, this is the best that I could whip up in order to show you.
It may not serve your purpose, but it shows you that you should be able to set the Value of a TextCtrl from outside the frame that creates it.
And since you have not provided the frame to work on, this is the best that I could whip up in order to show you.
This may be of interest to you:
wxApp::argv
wxChar ** argv
Command line arguments (after environment-specific processing).
This may be of interest to you:
wxApp::argv
wxChar ** argv
Command line arguments (after environment-specific processing).
hey hi...
the code snippet u had posted as an example worked. I created a GUI of my own...rather than using the already available one.It's working the way i wanted it to....:)
thanks!! :)
hey hi...
the code snippet u had posted as an example worked. I created a GUI of my own...rather than using the already available one.It's working the way i wanted it to....:)
thanks!! :)
That's awesome. I am SO glad that you got it working.
Thanks for the update,
Barton
Sign in to post your reply or Sign up for a free account.
Similar topics
by: RJS |
last post by:
Hi all,
I can't get a py2exe compiled app to run with numarray (numarray-0.5.win32-
py2.2).
Also wxPythonWIN32-2.3.3.1-Py22 and ActivePython-2.2.1-222.
In the sample below, commenting out...
|
by: Doug Farrell |
last post by:
Hi all,
I just installed the wxPython-2.4.1.2 demo RPM on my RedHat Linux 9.0
machine, which has Python 2.2.2 on it, and I'm having a problem
running the demo.py program. Here is a trace of the...
|
by: achrist |
last post by:
I've just installed the new wxPython, version 2.4.2.4 (under
Windows NT, sp6, python 2.3.2) and tried to create an exe
using the McMillan installer. Seems to be a new problem ...
I've got the...
|
by: Russell Reagan |
last post by:
I installed wxPython 2.4.2.4 from the prebuilt binary for Windows. I am
using the Cygwin version of Python 2.3.2. After installing wxPython, I ran
the minimal window script:...
|
by: timothy.williams |
last post by:
I'm trying to install wxPython 2.5.3.1 using Python 2.3.2 on a Fedora 2
machine.
I have python in a non-standard place, but I'm using --prefix with the
configure script to point to where I have...
|
by: Kenneth McDonald |
last post by:
If this is not an appropriate newsgroup for this type of posting,
please let me know and (if possible) suggest an alternative. I've
done a fair bit of research on the net, but information is...
|
by: Francach |
last post by:
Hi,
I'm using python 2.4.1, wxPython 2.6.1.0 and py2exe 1.6.3 on Windows
XP.
My script runs fine with python, but the .exe produced with py2exe
crashes out with:
Traceback (most recent...
|
by: BH |
last post by:
Hi !
I have a small problem with wx.Grid and scrollbars.
Scrollbars definitively dissapears after resizing the frame.
Thx for help
...
|
by: gatoruss |
last post by:
Newbie here with a (hopefully not) dumb question....tried searching around on the 'Net without success, so here goes....
I have been playing around with python. I wrote a script that sends an smtp...
|
by: Stef Mientki |
last post by:
Peter Anderson wrote:
In PyScripter, you should run wxPython in the plain remote machine (not
the wxPython remote),
and you should set "reset before run flag" or reset the remote machine
each...
|
by: DolphinDB |
last post by:
Tired of spending countless mintues downsampling your data? Look no further!
In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
|
by: ryjfgjl |
last post by:
ExcelToDatabase: batch import excel into database automatically...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: ArrayDB |
last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
|
by: PapaRatzi |
last post by:
Hello,
I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
|
by: CloudSolutions |
last post by:
Introduction:
For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
|
by: af34tf |
last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome former...
| |