> > with open('mypicklelog.txt','ab') as log: # open in binary mode > pickle.dump(self.data, log) # serialize data and write to file > > where pickle.dump(obj, file) converts `obj` to a sequence of bytes before it > is written to `file`. >
I put this like this: class DataEvent(wx.PyEvent): # the values of the text fields get passed into the constructor inside of data def __init__(self, data): wx.PyEvent.__init__(self) # this line *binds* this class to a certain type of event, wxDATA_EVENT self.SetEventType (wxDATA_EVENT) # and this is the actual data self.data = data with open('mypicklelog.txt','ab') as log: # open in binary mode pickle.dump(self.data, log) # serialize data and write to file And I still get nothing. This has me super confused, I have trying at this for a long time and I have been reading the docs like http://docs.python.org/2/library/pickle.html And I still don't get it to work. So the C++ makes the pickle, this is from the comments in the C++ : /** * snapshot_du_handler. Writes traffic snapshots to a msg_queue based * on the HDU frame contents. The format used is that of a pickled * python dictionary allowing the other end of the queue to pick only * those fields of interest and ignore the rest. */ Then the python program (attached) program unpickles and repickles it? I attached the python program, if you have a minute or two please take a look, its not too long.
#!/usr/bin/env python # -*- coding: utf-8 -*- # # op25_traffic_panel.py # # Copyright 2013 Balint Seeber <balint@crawfish> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. # # # MyVersion 1.2 # the import statements; very similar to #include in c++ from time import localtime, strftime import os import wx import cPickle as pickle import gnuradio.gr.gr_threading as _threading # wx is the gui class. it implements a version of "events" -- objects that sit and wait for some data to change, and call a specified function when the change happens wxDATA_EVENT = wx.NewEventType() # this is a function that *sets* what happens when the event is triggered. it takes in an event (win) and a function (func) def EVT_DATA_EVENT(win, func): win.Connect(-1, -1, wxDATA_EVENT, func) # the dataevent class -- stores the data that gets transmitted when the event occurs. #it is the data in text fields, stored in self.data as a dictionary, which is basically a c++ map #One of these classes gets created whenever an event occurs. class DataEvent(wx.PyEvent): # the values of the text fields get passed into the constructor inside of data def __init__(self, data): wx.PyEvent.__init__(self) # this line *binds* this class to a certain type of event, wxDATA_EVENT self.SetEventType (wxDATA_EVENT) # and this is the actual data self.data = data with open('mypicklelog.txt','ab') as log: # open in binary mode pickle.dump(self.data, log) # serialize data and write to file # clone is a python function to make a "deep" copy of an object def Clone (self): self.__class__ (self.GetId()) # thread that waits for new data to be received # when event is triggered new data is passed along # this class inherits from the standard Python class _threading.Thread class traffic_watcher_thread(_threading.Thread): def __init__(self, rcvd_pktq, event_receiver): ## variables are standard values required to set up a thread _threading.Thread.__init__(self) self.setDaemon(1) self.rcvd_pktq = rcvd_pktq self.event_receiver = event_receiver self.keep_running = True self.start() def stop(self): self.keep_running = False def run(self): while self.keep_running: msg = self.rcvd_pktq.delete_head() ## once data is received, an event is "Posted" with PostEvent. ## This is where the DataEvent object gets created de = DataEvent (msg) wx.PostEvent (self.event_receiver, de) del de # A snapshot of important fields in current traffic # this inherits from the gui class Panel (required for all gui programs) class TrafficPane(wx.Panel): # Initializer; class constructor # def __init__(self, parent, msgq): wx.Panel.__init__(self, parent) self.msgq = msgq #with open('msgqlog.txt','a') as log: #log.write(self.msgq) #name array to put traffic data in self.log_array = [] #layout of the panel. 10 px gap on each side of TextCtrls. panel is a grid, #texctrls and lables are placed at grid positions like (1,1), (2,1) etc. sizer = wx.GridBagSizer(hgap=10, vgap=10) # defines a dictionary ({} = empty dictionary), to hold the text control values self.fields = {} #TextCtrl recipe: label = wx.StaticText(self, -1, "DUID:") sizer.Add(label, pos=(1,1)) field = wx.TextCtrl(self, -1, "", size=(144, -1), style=wx.TE_READONLY) sizer.Add(field, pos=(1,2)) self.fields["duid"] = field; label = wx.StaticText(self, -1, "NAC:") sizer.Add(label, pos=(2,1)) field = wx.TextCtrl(self, -1, "", size=(144, -1), style=wx.TE_READONLY) sizer.Add(field, pos=(2,2)) self.fields["nac"] = field; label = wx.StaticText(self, -1, "Source:") sizer.Add(label, pos=(3,1)) field = wx.TextCtrl(self, -1, "", size=(144, -1), style=wx.TE_READONLY) sizer.Add(field, pos=(3,2)) self.fields["source"] = field; label = wx.StaticText(self, -1, "Destination:") sizer.Add(label, pos=(4,1)) field = wx.TextCtrl(self, -1, "", size=(144, -1), style=wx.TE_READONLY) sizer.Add(field, pos=(4,2)) self.fields["dest"] = field; label = wx.StaticText(self, -1, "MFID:") sizer.Add(label, pos=(1,4)) field = wx.TextCtrl(self, -1, "", size=(144, -1), style=wx.TE_READONLY) sizer.Add(field, pos=(1,5)) self.fields["mfid"] = field; label = wx.StaticText(self, -1, "ALGID:") sizer.Add(label, pos=(2,4)) field = wx.TextCtrl(self, -1, "", size=(144, -1), style=wx.TE_READONLY) sizer.Add(field, pos=(2,5)) self.fields["algid"] = field; label = wx.StaticText(self, -1, "KID:") sizer.Add(label, pos=(3,4)) field = wx.TextCtrl(self, -1, "", size=(144, -1), style=wx.TE_READONLY) sizer.Add(field, pos=(3,5)) self.fields["kid"] = field; label = wx.StaticText(self, -1, "MI:") sizer.Add(label, pos=(4,4)) field = wx.TextCtrl(self, -1, "", size=(216, -1), style=wx.TE_READONLY) sizer.Add(field, pos=(4,5)) self.fields["mi"] = field; label = wx.StaticText(self, -1, "TGID:") sizer.Add(label, pos=(5,4)) field = wx.TextCtrl(self, -1, "", size=(144, -1), style=wx.TE_READONLY) sizer.Add(field, pos=(5,5)) self.fields["tgid"] = field; # Open file button click event binded to openfile btn = wx.Button(self, -1, "Choose Log File") sizer.Add(btn, pos=(7,2)) btn.Bind(wx.EVT_BUTTON, self.openFile) #set the panel layout self.SetSizer(sizer) #makes the gui system fit all the controls onto the panel self.Layout() self.Fit() EVT_DATA_EVENT(self, self.display_data) self.watcher = traffic_watcher_thread(self.msgq, self) # openfile defined to start FileDialog and write the traffic log to the file def openFile(self, evt): with wx.FileDialog(self, "Choose a file", os.getcwd(), "", "*.txt*", wx.OPEN) as dlg: if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() mypath = os.path.basename(path) with open(mypath, "a") as f: f.writelines(self.log_array) # Clear the field values # def clear(self): #loops through each value in the dictionary #values are actually text control objects for v in self.fields.values(): # clear the text control value v.Clear() # Display the values on the UI def display_data(self,event): #gets the "message" into the event object #message is equal to the "data" parameter in the "DataEvent" class message = event.data # unpickle the string pickled_dict = message.to_string() #separate the string into values for each text control (attrs is a pickle object) attrs = pickle.loads(pickled_dict) #pass this pickle object into update self.update(attrs) # Update the field values # put values in array def update(self, field_values): next_line = "" next_line += strftime("%Y-%m-%d %H:%M:%S") next_line += ','.join( field_values[k] for k in self.fields.keys() if k in field_values ) self.log_array.append(next_line) #if the field 'duid' == 'hdu', then clear all the fields if field_values['duid'] == 'hdu': self.clear() #loop through all TextCtrl fields storing the key/value pairs in k, v for k,v in self.fields.items(): # get the pickle value for this TextCtrl f = field_values.get(k, None) # if the value is empty then set the new value if f: v.SetValue(f) if __name__ == '__main__': import wx.lib.mixins.inspection as inspect # when running it press ctrl-alt-i to help in sizer debug and more # this is often refered to as the WIT - Widget Inspection Tool - see the wiki app = inspect.InspectableApp(redirect=False) f = wx.Frame(None) f.p = TrafficPane(f, "") f.Fit() f.Show() app.MainLoop()
_______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor