This post was updated on .
Hi Chaps
I have attempted to purloin some of the code shipped with IP in Action and, following issues, I have even gone to the lengths of reading the book! I am getting the error 'expect Delegate, got Function' when I use the following code. FYI I am passing in a reference to a WPF textBox so I should have a dispatcher on my UI element I have removed all of the threading pipe reading stuff just to leave 'test' code: import System import System.IO import Avacta.Optim.Server.WebServices import Avacta.Optim.Server.DataModel import sys import clr import time from System import Console from System.Threading import Thread, ThreadStart def SetDispatcher(ui_element): global dispatcher # needed else "Exception: 'NoneType' object has no attribute 'BeginInvoke'" dispatcher = ui_element.Dispatcher def Dispatch(function, *args): dispatcher.BeginInvoke(lambda *_: function(*args)) def GetDispatchFunction(function): return lambda *args: Dispatch(function, *args) class ListOutput: def __init__(self, textbox): self.textbox = textbox def write(self, string): Dispatch(self.addText, string) # error: "expect Delegate, got Function" # self.addText(string) # ok works fine w-w/o dispatcher stuff def addText(self, string): textbox.AppendText(string) if textbox != None: listout = ListOutput(textbox) sys.stdout = listout SetDispatcher(textbox) print "Define running" #running = True Thread.Sleep(0) time.sleep(2) print "Start The Comms Thread..." #comms_t = Thread(ThreadStart(run_comms)) #comms_t.Start() Thread.Sleep(0) time.sleep(2) Any clues would be greatly appreciated! AndyF. |
AndyF wrote:
> Hi Chaps > > I have attempted to purloin some of the code shipped with IP in Action and, > following issues, I have even gone to the lengths of reading the book! > > I am getting the error 'expect Delegate, got Function' when I use the > following code. FYI I am passing in a reference to a WPF textBox so I should > have a dispatcher on my UI element > > I have removed all of the threading pipe reading stuff just to leave 'test' > code: > > import System > import System.IO > import Avacta.Optim.Server.WebServices > import Avacta.Optim.Server.DataModel > import sys > import clr > import time > > from System import Console > from System.Threading import Thread, ThreadStart > > def SetDispatcher(ui_element): > global dispatcher # needed else "Exception: 'NoneType' object has no > attribute 'BeginInvoke'" > dispatcher = ui_element.Dispatcher > > def Dispatch(function, *args): > dispatcher.BeginInvoke(lambda *_: function(*args)) > > def GetDispatchFunction(function): > return lambda *args: Dispatch(function, *args) > > class ListOutput: > def __init__(self, textbox): > self.textbox = textbox > > def write(self, string): > Dispatch(self.addText, string) # error: "expect Delegate, got Function" > # self.addText(string) # ok works fine w-w/o dispatcher stuff > > def addText(self, string): > textbox.AppendText(string) > > if textbox != None: > listout = ListOutput(textbox) > sys.stdout = listout > SetDispatcher(textbox) > > print "Define running" > #running = True > > Thread.Sleep(0) > time.sleep(2) > > print "Start The Comms Thread..." > #comms_t = Thread(ThreadStart(run_comms)) > #comms_t.Start() > > Thread.Sleep(0) > time.sleep(2) > > Any clues would be greatly appreciated! The WPF invocation functions just take a type which is typed to "Delegate" instead of a type of a specific delegate. Therefore we don't know what type of delegate to create for you automatically. Instead you can convert the Python function into a delegate by calling the delegate type directly, e.g.: dispatcher.BeginInvoke(System.Action(lambda *_: function(*args))) or you can use another delegate type (e.g. System.Action[object]) with the appropriate signature you need. _______________________________________________ Users mailing list [hidden email] http://lists.ironpython.com/listinfo.cgi/users-ironpython.com |
Thank you Dino
modifying my Python dispatcher to read dispatcher.BeginInvoke(System.Action(lambda *_: function(*args))) fixed the problem. Unfortunately for me, utilising the dispatcher has an unforseen side effect - the 'messages' printed to my console only appear when the python script exits. If I revert the code to bypass all dispatcher code i.e. use the following def write(self, string): self.texbox.AppendText(string) then I see the messages arrive in real time. I have tested launching my PythonEngine class using a thread with both ApartmentState.STA and MTA but this has no discernible effect. Can you offer any explanation, maybe workaround? Thanks AndyF.
|
I have not tested this on a GUI screen, but...
You should be able to assign any class with a .write() method to sys.stdout (and/or sys.stderr) so that normal "print" statements/functions and tracebacks will be sent to that method. I use the trick frequently to get a simple logging facility by assigning a text file -- like: <code> import sys my_log = open('my_log_file.txt','w') sys.stdout = my_log print 'Hello, Log.' sys.stderr = my_log error = 1 / 0 </code> Is that the kind of 'messages' you were thinking about? -- Vernon On Tue, Jun 7, 2011 at 2:00 AM, AndyF. <[hidden email]> wrote:
_______________________________________________ Users mailing list [hidden email] http://lists.ironpython.com/listinfo.cgi/users-ironpython.com |
Free forum by Nabble | Edit this page |