sábado, 25 de abril de 2015

wxPython double slider widget to enter a range.

I had this problem to enter a range of times in a wxPython application. After some research I could not found a widget that does what I need. The closest I could get was a Slider with SL_SELRANGE
style. Unfortunatelly this option is only available in Windows.

So I decide to create a small widget with two sliders to select the maximum and minimum time. If the minimum goes over the maximum the maximum is updated and viceversa. The selected values are updated as labels.





This is the code:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx

class RangeSlider (wx.Panel):
    MAX_VALUE = 1000

    def __init__ (self, parent, minTime, maxTime):
        super(RangeSlider, self).__init__(parent, wx.ID_ANY)

        self.minTime = minTime
        self.maxTime = maxTime

        sizer = wx.FlexGridSizer (rows=2, cols = 3, vgap = 5, hgap = 5)
        self.sldMax = wx.Slider(self, value=RangeSlider.MAX_VALUE, minValue=0,
                maxValue=self.MAX_VALUE,
                style=wx.SL_HORIZONTAL )
        self.sldMin = wx.Slider (self, value=0, minValue=0,
                maxValue=self.MAX_VALUE,
                style =wx.SL_HORIZONTAL )

        self.sldMax.Bind(wx.EVT_SCROLL, self.OnSliderScroll)
        self.sldMin.Bind (wx.EVT_SCROLL, self.OnSliderScroll2)

        self.txtMax = wx.StaticText(self, label= self.formatTime (self.maxTime))
        self.txtMin = wx.StaticText(self, label=self.formatTime (self.minTime))

        lab1 = wx.StaticText (self, label="Min " + self.formatTime (self.minTime))
        lab2 = wx.StaticText (self, label="Max " + self.formatTime (self.maxTime))

        sizer.Add (lab1, 0, wx.LEFT, 10)
        sizer.Add (self.sldMax, 1, wx.EXPAND)
        sizer.Add (lab2, 0, wx.RIGHT, 10)
        sizer.Add (self.txtMin, 1, wx.ALIGN_CENTER)
        sizer.Add (self.sldMin, 1, wx.EXPAND)
        sizer.Add (self.txtMax, 1, wx.ALIGN_CENTER)
        sizer.AddGrowableCol (1, 1)

        self.SetSizer (sizer)

    def formatTime (self, t):
        return "%02d:%02d:%02d" % (t / 3600, (t%3600)/60, t%60)

    def formatValue (self, v):
        t = v * (self.maxTime - self.minTime) / 1000
        return self.formatTime (t)


    def OnSliderScroll(self, e):

        val = self.sldMax.GetValue()

        valMin = self.sldMin.GetValue ()
        if valMin > val:
            self.sldMin.SetValue (val)
            self.txtMin.SetLabel (self.formatValue(val))

        self.txtMax.SetLabel(self.formatValue(val))

    def OnSliderScroll2 (self, e):
        val = self.sldMin.GetValue()

        valMax = self.sldMax.GetValue ()
        if valMax < val:
            self.sldMax.SetValue (val)
            self.txtMax.SetLabel (self.formatValue(val))

        self.txtMin.SetLabel(self.formatValue(val))


class Example(wx.Frame):

    def __init__(self, parent, minTime, maxTime):
        """ The time is seconds """
        super(Example, self).__init__(parent, wx.ID_ANY)


        self.InitUI(minTime, maxTime)


    def InitUI(self, minTime, maxTime):

        rangeSlider = RangeSlider (self,minTime, maxTime)

        self.SetTitle('RangeSlider')
        self.Centre()
        self.Show(True)

def main():

    ex = wx.App()
    Example(None, 0, 7200)
    ex.MainLoop()

if __name__ == '__main__':
    main()



jueves, 9 de abril de 2015

Timedoctor Visualizer. An application to analyze timedoctor files.

Recently I needed to analyze some linux execution tasks and interrupt traces and I could not find a tool to do what I wanted so I created my own.

The timedoctor files show the begining and end time of each task executed by a CPU. This is a quite usefull tool to analyze errors in embedded systems, like deadlock, priority inversions...

The tool has two main windows the first one shows the existing tasks in one file and allows to sort, select and deselect each of them. More than one file can be analyzed at the same time.

The other windows allows to visualize the time of execution of the selected tasks in the time. The window allows to pan, zoom and save an image with the graph.

The application was implemented in python and it uses wxPython for the user interface and matplotlib for the plots. I've made it run on Linux, Windows and Mac. The tool can be downloaded from here:

http://github.com/rgonzalez72/tdv

lunes, 6 de abril de 2015

Managing id tags in mp3 files with eyed3.

This is a problem I solved some time ago but after updating to the lastest library I discovered the interface has changed. Setting the tags is quite straightforward following the instructions in here: http://eyed3.nicfit.net/. It wasn't so easy for me to figure out how to attach and image to an mp3 file.
This is the solution I found:

import eyed3

audiofile = eyed3.load (fileName)
if audiofile.tag == None:
    audiofile.tag = eyed3.id3.Tag ()
    audiofile.file_info = eyed3.id3.FileInfo (fileName)


audiofile.tag.artist = artist
audiofile.tag.title = unicode (title)
audiofile.tag.genre = unicode (genre)
img_fp = open (file_path, "rb")

# The type of image, the content of the jpg file, mime type, description
audiofile.tag.images.set(eyed3.id3.frames.ImageFrame.FRONT_COVER,
                img_fp.read(), "image/jpeg", u" ")
audiofile.tag.save (filename=fileName, version=eyed3.id3.ID3_V2_3)