>
> 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 - [email protected]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor